281 lines
7.3 KiB
Vue
281 lines
7.3 KiB
Vue
<script setup>
|
|
import { computed, nextTick, ref, watch } from "vue";
|
|
import UiParentCard from "@/components/shared/UiParentCard.vue";
|
|
import { Icon } from "@iconify/vue";
|
|
|
|
const search = ref();
|
|
const dialog = ref(false);
|
|
const dialogDelete = ref(false);
|
|
const headers = ref([
|
|
{
|
|
title: "Dessert (100g serving)",
|
|
align: "start",
|
|
sortable: false,
|
|
key: "name",
|
|
},
|
|
{ title: "Calories", key: "calories" },
|
|
{ title: "Fat (g)", key: "fat" },
|
|
{ title: "Carbs (g)", key: "carbs" },
|
|
{ title: "Protein (g)", key: "protein" },
|
|
{ title: "Actions", key: "actions", sortable: false },
|
|
]);
|
|
const desserts = ref([]);
|
|
const editedIndex = ref(-1);
|
|
const editedItem = ref({
|
|
name: "",
|
|
calories: 0,
|
|
fat: 0,
|
|
carbs: 0,
|
|
protein: 0,
|
|
});
|
|
const defaultItem = ref({
|
|
name: "",
|
|
calories: 0,
|
|
fat: 0,
|
|
carbs: 0,
|
|
protein: 0,
|
|
});
|
|
const formTitle = computed(() => {
|
|
return editedIndex.value === -1 ? "New Item" : "Edit Item";
|
|
});
|
|
function initialize() {
|
|
desserts.value = [
|
|
{
|
|
name: "Frozen Yogurt",
|
|
calories: 159,
|
|
fat: 6,
|
|
carbs: 24,
|
|
protein: 4,
|
|
},
|
|
{
|
|
name: "Ice cream sandwich",
|
|
calories: 237,
|
|
fat: 9,
|
|
carbs: 37,
|
|
protein: 4.3,
|
|
},
|
|
{
|
|
name: "Eclair",
|
|
calories: 262,
|
|
fat: 16,
|
|
carbs: 23,
|
|
protein: 6,
|
|
},
|
|
{
|
|
name: "Cupcake",
|
|
calories: 305,
|
|
fat: 3.7,
|
|
carbs: 67,
|
|
protein: 4.3,
|
|
},
|
|
{
|
|
name: "Gingerbread",
|
|
calories: 356,
|
|
fat: 16,
|
|
carbs: 49,
|
|
protein: 3.9,
|
|
},
|
|
{
|
|
name: "Jelly bean",
|
|
calories: 375,
|
|
fat: 0,
|
|
carbs: 94,
|
|
protein: 0,
|
|
},
|
|
{
|
|
name: "Lollipop",
|
|
calories: 392,
|
|
fat: 0.2,
|
|
carbs: 98,
|
|
protein: 0,
|
|
},
|
|
{
|
|
name: "Honeycomb",
|
|
calories: 408,
|
|
fat: 3.2,
|
|
carbs: 87,
|
|
protein: 6.5,
|
|
},
|
|
{
|
|
name: "Donut",
|
|
calories: 452,
|
|
fat: 25,
|
|
carbs: 51,
|
|
protein: 4.9,
|
|
},
|
|
{
|
|
name: "KitKat",
|
|
calories: 518,
|
|
fat: 26,
|
|
carbs: 65,
|
|
protein: 7,
|
|
},
|
|
];
|
|
}
|
|
function editItem(item) {
|
|
editedIndex.value = desserts.value.indexOf(item);
|
|
editedItem.value = Object.assign({}, item);
|
|
dialog.value = true;
|
|
}
|
|
function deleteItem(item) {
|
|
editedIndex.value = desserts.value.indexOf(item);
|
|
editedItem.value = Object.assign({}, item);
|
|
dialogDelete.value = true;
|
|
}
|
|
function deleteItemConfirm() {
|
|
desserts.value.splice(editedIndex.value, 1);
|
|
closeDelete();
|
|
}
|
|
function close() {
|
|
dialog.value = false;
|
|
nextTick(() => {
|
|
editedItem.value = Object.assign({}, defaultItem.value);
|
|
editedIndex.value = -1;
|
|
});
|
|
}
|
|
function closeDelete() {
|
|
dialogDelete.value = false;
|
|
nextTick(() => {
|
|
editedItem.value = Object.assign({}, defaultItem.value);
|
|
editedIndex.value = -1;
|
|
});
|
|
}
|
|
function save() {
|
|
if (editedIndex.value > -1) {
|
|
Object.assign(desserts.value[editedIndex.value], editedItem.value);
|
|
} else {
|
|
desserts.value.push(editedItem.value);
|
|
}
|
|
close();
|
|
}
|
|
watch(dialog, (val) => {
|
|
val || close();
|
|
});
|
|
watch(dialogDelete, (val) => {
|
|
val || closeDelete();
|
|
});
|
|
initialize();
|
|
</script>
|
|
|
|
<template>
|
|
<v-row>
|
|
<v-col cols="12">
|
|
<!-- <UiParentCard title="Crud Table"> -->
|
|
<v-text-field
|
|
v-model="search"
|
|
append-inner-icon="mdi-magnify"
|
|
label="Search"
|
|
single-line
|
|
hide-details
|
|
class="mb-5"
|
|
/>
|
|
<v-data-table
|
|
class="border rounded-md datatabels"
|
|
:headers="headers"
|
|
:items="desserts"
|
|
:search="search"
|
|
:sort-by="[{ key: 'calories', order: 'asc' }]"
|
|
>
|
|
<template v-slot:top>
|
|
<v-toolbar class="bg-lightprimary" flat>
|
|
<v-toolbar-title>My Crud Table</v-toolbar-title>
|
|
<v-divider class="mx-4" inset vertical></v-divider>
|
|
<v-spacer></v-spacer>
|
|
<!-- dialog create & update -->
|
|
<v-btn color="primary" variant="flat" dark @click="dialog = true"
|
|
>Add New Item</v-btn
|
|
>
|
|
<UiComponents2DialogsScrollable v-model="dialog">
|
|
<template v-slot:title> coba </template>
|
|
<template v-slot:text>
|
|
<v-container class="px-0">
|
|
<v-row>
|
|
<v-col cols="12" sm="6" md="4">
|
|
<v-text-field
|
|
v-model="editedItem.name"
|
|
label="Dessert name"
|
|
></v-text-field>
|
|
</v-col>
|
|
<v-col cols="12" sm="6" md="4">
|
|
<v-text-field
|
|
v-model="editedItem.calories"
|
|
label="Calories"
|
|
></v-text-field>
|
|
</v-col>
|
|
<v-col cols="12" sm="6" md="4">
|
|
<v-text-field
|
|
v-model="editedItem.fat"
|
|
label="Fat (g)"
|
|
></v-text-field>
|
|
</v-col>
|
|
<v-col cols="12" sm="6" md="4">
|
|
<v-text-field
|
|
v-model="editedItem.carbs"
|
|
label="Carbs (g)"
|
|
></v-text-field>
|
|
</v-col>
|
|
<v-col cols="12" sm="6" md="4">
|
|
<v-text-field
|
|
v-model="editedItem.protein"
|
|
label="Protein (g)"
|
|
></v-text-field>
|
|
</v-col>
|
|
</v-row>
|
|
</v-container>
|
|
</template>
|
|
<template v-slot:actions>
|
|
<v-btn color="error" variant="tonal" @click="close">
|
|
Cancel
|
|
</v-btn>
|
|
<v-btn color="success" variant="tonal" @click="save">
|
|
Save
|
|
</v-btn>
|
|
</template>
|
|
</UiComponents2DialogsScrollable>
|
|
<!-- dialog delete -->
|
|
<UiComponents2DialogsActivator v-model="dialogDelete">
|
|
<template v-slot:text
|
|
>Are you sure you want to delete this item?</template
|
|
>
|
|
<template v-slot:actions>
|
|
<v-btn color="error" variant="flat" dark @click="closeDelete"
|
|
>Cancel</v-btn
|
|
>
|
|
<v-btn
|
|
color="primary"
|
|
variant="flat"
|
|
dark
|
|
@click="deleteItemConfirm"
|
|
>OK</v-btn
|
|
>
|
|
</template>
|
|
</UiComponents2DialogsActivator>
|
|
</v-toolbar>
|
|
</template>
|
|
<template v-slot:item.actions="{ item }">
|
|
<div class="d-flex gap-3">
|
|
<Icon
|
|
icon="solar:pen-new-square-broken"
|
|
height="20"
|
|
class="text-primary cursor-pointer"
|
|
size="small"
|
|
@click="editItem(item)"
|
|
/>
|
|
<Icon
|
|
icon="solar:trash-bin-minimalistic-linear"
|
|
height="20"
|
|
class="text-error cursor-pointer"
|
|
size="small"
|
|
@click="deleteItem(item)"
|
|
/>
|
|
</div>
|
|
</template>
|
|
<template v-slot:no-data>
|
|
<v-btn color="primary" @click="initialize"> Reset </v-btn>
|
|
</template>
|
|
</v-data-table>
|
|
<!-- </UiParentCard> -->
|
|
</v-col>
|
|
</v-row>
|
|
</template>
|