initial commit
This commit is contained in:
commit
7e466e29d2
28 changed files with 17360 additions and 0 deletions
140
components/Todo.vue
Normal file
140
components/Todo.vue
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
<script lang="ts" setup>
|
||||
import { TODOS_REPO_KEY } from "@/utils/proxy-service-keys";
|
||||
import { Todo } from "@/utils/types";
|
||||
import { createProxyService } from '@webext-core/proxy-service';
|
||||
import { v4 as uuidv4 } from "uuid"
|
||||
|
||||
const todosRepo = createProxyService(TODOS_REPO_KEY);
|
||||
|
||||
const props = defineProps<{
|
||||
showCompleted?: boolean,
|
||||
showOnlyCompleted?: boolean,
|
||||
showInput?: boolean,
|
||||
hoverShowDeleteButton?: boolean,
|
||||
showClearAllTodo?: boolean
|
||||
}>()
|
||||
|
||||
const todos = ref<Todo[]>([]);
|
||||
const inputNewTodo = ref<string | null>();
|
||||
|
||||
const refreshTodo = async () => {
|
||||
const allTodos = await todosRepo.getAll();
|
||||
todos.value = allTodos.filter(
|
||||
(todo: Todo) =>
|
||||
(props.showCompleted && todo.completed) ||
|
||||
(props.showOnlyCompleted && todo.completed) ||
|
||||
(!props.showOnlyCompleted && !todo.completed)
|
||||
)
|
||||
}
|
||||
|
||||
onBeforeMount(async () => refreshTodo())
|
||||
|
||||
const insertTodo = async () => {
|
||||
if (!inputNewTodo.value) return
|
||||
if (!inputNewTodo.value.trim()) return
|
||||
const generateTodoId = uuidv4()
|
||||
await todosRepo.insert({
|
||||
id: generateTodoId,
|
||||
name: inputNewTodo.value,
|
||||
completed: false
|
||||
})
|
||||
inputNewTodo.value = null
|
||||
refreshTodo()
|
||||
}
|
||||
|
||||
const updateTodo = async (todo: Todo) => {
|
||||
await todosRepo.update(toRaw(todo))
|
||||
refreshTodo()
|
||||
}
|
||||
|
||||
const deleteTodo = async (todo: Todo) => {
|
||||
await todosRepo.delete(toRaw(todo))
|
||||
refreshTodo()
|
||||
}
|
||||
|
||||
const clearAllCompletedTodo = async () => {
|
||||
const allTodos = await todosRepo.getAll()
|
||||
const completedTodos = allTodos.filter((todo) => todo.completed)
|
||||
const deletePromises = completedTodos.map((todo) => todosRepo.delete(todo))
|
||||
await Promise.all(deletePromises)
|
||||
refreshTodo()
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<h2 v-if="props.showOnlyCompleted">[completed todos]</h2>
|
||||
<h2 v-if="!props.showOnlyCompleted">[todos]</h2>
|
||||
<div v-if="showInput" class="form-input">
|
||||
<input @keydown.enter="insertTodo" v-model="inputNewTodo" placeholder="playing skateboard at 5am" type="input"/>
|
||||
<button @click="insertTodo">[add todo]</button>
|
||||
</div>
|
||||
<div v-if="showClearAllTodo">
|
||||
<button @click="clearAllCompletedTodo">[clear all completed todos]</button>
|
||||
</div>
|
||||
<br/>
|
||||
<div v-if="todos.length === 0">no todos :D</div>
|
||||
<ul v-else v-for="todo in todos">
|
||||
<li :class="{ completed: todo.completed }" :key="todo.id">
|
||||
<label>
|
||||
<input type="checkbox" @change="updateTodo(todo)" v-model="todo.completed" :id="todo.id"/>
|
||||
{{ todo.name }}
|
||||
<button class="button-delete" v-if="props.hoverShowDeleteButton" @click="deleteTodo(todo)">x</button>
|
||||
</label>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.container {
|
||||
min-width: 300px;
|
||||
}
|
||||
|
||||
ul {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
li {
|
||||
list-style: none;
|
||||
text-align: left;
|
||||
font-size: 14pt;
|
||||
}
|
||||
|
||||
li label {
|
||||
display: block;
|
||||
}
|
||||
|
||||
li label:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
li.completed {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
li .button-delete {
|
||||
display: none;
|
||||
padding: 1px 4px;
|
||||
font-size: 10pt;
|
||||
float: right
|
||||
}
|
||||
|
||||
li:hover .button-delete {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.form-input input,
|
||||
.form-input button {
|
||||
width: 100%;
|
||||
padding: 2px 4px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
.form-input input {
|
||||
font-size: 12pt;
|
||||
box-sizing: border-box;
|
||||
-webkit-box-sizing:border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
}
|
||||
</style>
|
||||
Loading…
Add table
Add a link
Reference in a new issue