Everywhere: More work on the todo page

This commit is contained in:
Riyyi
2024-11-25 18:28:45 +01:00
parent 9604097e7f
commit 18936ec703
14 changed files with 234 additions and 24 deletions
+59
View File
@@ -0,0 +1,59 @@
<template>
<Form v-slot="$form" ref="formRef" :initialValues :resolver @submit="onFormSubmit"
class="flex flex-col gap-4 w-full sm:w-56">
<!-- {{ $form }} -->
<div class="flex flex-col gap-1">
<InputText @input="initial = false;" v-model="formData.title" name="title" type="text" placeholder="Title"
autocomplete="off" fluid />
<Message v-if="$form.title?.invalid" severity="error" size="small" variant="simple">
{{ $form.title.error?.message }}
</Message>
</div>
<Button :disabled="initial || !$form.valid" class="fr" type="submit" severity="secondary" label="Submit" />
</Form>
</template>
<script setup lang="ts">
import { useTodoStore } from "@/stores/todoStore";
import { todoSchema } from "@/schemas/todo";
import { zodResolver } from '@primevue/forms/resolvers/zod';
import { v4 as uuidv4 } from "uuid";
import { type FormSubmitEvent } from "@primevue/forms/form";
const store = useTodoStore();
const toast = useToast();
const resolver = zodResolver(todoSchema);
const initial = ref(true); // makes submit button disabled
const initialValues = ref({
title: ""
});
const formRef = ref<HTMLElement | null>(null);
const formData = ref({ ...initialValues.value }); // copy data from initialValues
async function onFormSubmit(e: FormSubmitEvent) {
if (e.valid) {
toast.add({ severity: "success", summary: "Todo added", life: 3000 });
store.todos.push({
id: uuidv4(),
title: e.values?.title || e.states?.title.value
});
// Reset the form
initial.value = true;
formData.value = { ...initialValues.value }; // copy data from initialValues
}
else {
toast.add({ severity: "error", summary: "Invalid request", life: 3000 });
}
};
</script>
<style scoped>
.fr {
float: right;
}
</style>
+87
View File
@@ -0,0 +1,87 @@
<template>
<div class="card">
<ConfirmDialog></ConfirmDialog>
<DataTable :value="computedTodos" tableStyle="min-width: 50rem" @sort="onSort" sortMode="multiple" removableSort>
<Column field="number" header="#"></Column>
<Column field="id" header="ID" sortable filterField="id" showFilterMenu filter="true"></Column>
<Column field="title" header="Title" sortable filterField="title" showFilterMenu filter="true"></Column>
<Column header="Modifier">
<template #body="slotProps">
<a @click="removeTodo(slotProps.data.id)">
<span class="pi pi-trash" style="color: var(--p-red-600);"></span>
</a>
</template>
</Column>
</DataTable>
</div>
</template>
<script setup lang="ts">
import { useConfirm } from "primevue/useconfirm";
import { useToast } from "primevue/usetoast";
import { useTodoStore } from "@/stores/todoStore";
import type { Todo } from "@/schemas/todo";
const confirm = useConfirm();
const store = useTodoStore();
const toast = useToast();
const onSort = (event: any) => {
console.log(event);
};
const sorting = ref<Record<string, string>>({
id: "asc",
title: "asc",
});
function toggleSorting(key: string) {
sorting.value[key] = sorting.value[key] === 'asc' ? 'desc' : 'asc';
};
function sortTodos(): Todo[] {
let todos: Todo[] = JSON.parse(JSON.stringify(store.todos)); // deep copy
// Number
// ID
// Title
todos = (sorting.value.title === "desc")
? todos.sort((a, b) => b.title.localeCompare(a.title))
: todos.sort((a, b) => a.title.localeCompare(b.title));
return todos;
}
const computedTodos = computed(() => {
return sortTodos().map((todo, index) => ({
number: index + 1,
...todo
}));
});
const removeTodo = (id: String) => {
confirm.require({
message: "Do you want to delete this todo?",
header: "Confirmation",
icon: "pi pi-info-circle",
rejectLabel: "Cancel",
rejectProps: {
label: "Cancel",
severity: "secondary",
outlined: true
},
acceptProps: {
label: "Delete",
severity: "danger"
},
accept: () => {
toast.add({ severity: "info", summary: "Confirmed", detail: "Todo deleted", life: 3000 });
store.todos = store.todos.filter(todo => todo.id !== id);
},
reject: () => {}
});
};
</script>