diff options
author | Vidhu Kant Sharma <vidhukant@vidhukant.com> | 2023-12-04 15:26:36 +0530 |
---|---|---|
committer | Vidhu Kant Sharma <vidhukant@vidhukant.com> | 2023-12-04 15:26:36 +0530 |
commit | 331a8da55352c736f08339ae6ca0d9e0eb690058 (patch) | |
tree | eebd21abc445d1f05a681668d1d66bbaa6034e98 | |
parent | d5fab4fefaa3e63c1cda945cf556a0ecfdfa0170 (diff) |
added table to show items of an invoice0.2.2
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/components/invoice_items_table.vue | 142 | ||||
-rw-r--r-- | src/components/item_selector.vue | 4 | ||||
-rw-r--r-- | src/components/items_table.vue | 2 | ||||
-rw-r--r-- | src/views/EditInvoice.vue | 7 | ||||
-rw-r--r-- | src/views/HomeView.vue | 2 |
6 files changed, 152 insertions, 7 deletions
diff --git a/package.json b/package.json index fbd1a52..8915981 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openbills-web", - "version": "0.2.1", + "version": "0.2.2", "private": false, "scripts": { "dev": "vite", diff --git a/src/components/invoice_items_table.vue b/src/components/invoice_items_table.vue new file mode 100644 index 0000000..6a89f5a --- /dev/null +++ b/src/components/invoice_items_table.vue @@ -0,0 +1,142 @@ +<script setup lang="js"> +import { ref, onMounted, toRaw } from 'vue' +import axios from 'axios' +import { useToast } from 'vue-toast-notification' + +const props = defineProps(["invoiceId"]) + +const toast = useToast({ + position: 'top-right' +}) + +const items = ref([]) +const isLoading = ref(false) + +const getItems = async () => { + items.value = [] + isLoading.value = true + + try { + const res = await axios.get(`/invoice/${props.invoiceId}/item`) + if (res.status === 200) { + items.value = res.data.data + } + } catch (err) { + toast.error('An unhandled exception occoured. Please check logs') + console.error(err) + } + + isLoading.value = false +} + +const handleDelete = async (id) => { + alert("coming soon") + return + try { + const res = await axios.delete(`/item/${id}`) + if (res.status === 200) { + toast.success('Successfully deleted item') + } + + getAllItems() + } catch (err) { + toast.error('An unhandled exception occoured. Please check logs') + console.error(err) + } +} + +onMounted(() => { + getItems() +}) +</script> + +<template> + <div v-if="isLoading" class="w-100 d-flex justify-content-center"> + <div class="spinner-border" role="status"> + <span class="sr-only"></span> + </div> + </div> + + <table v-else class="table table-striped table-hover"> + <thead> + <tr> + <th scope="col">#</th> + <th scope="col">Item Name</th> + <th scope="col">Description</th> + <th scope="col">Brand</th> + <th scope="col">HSN</th> + <th scope="col">Unit Price</th> + <th scope="col">UOM</th> + + <th scope="col" class="table-action-column"> + <div class="wrapper"> + <RouterLink to="/item/new"> + <button class="btn btn-dark"> + <i class="bi bi-plus-lg"></i> + </button> + </RouterLink> + <button class="btn btn-dark" v-on:click="getAllItems"> + <i class="bi bi-arrow-clockwise"></i> + </button> + </div> + </th> + </tr> + </thead> + + <tbody> + <tr v-for="(item, index) in items" :key="item['id']"> + <td scope="row">{{ index + 1 }}</td> + <td>{{ item.Name }}</td> + <td>{{ item.Description }}</td> + <td>{{ item.BrandName }}</td> + <td>{{ item.HSN }}</td> + <td>{{ item.UnitPrice }}</td> + <td>{{ item.UnitOfMeasure }}</td> + + <td class="table-action-column"> + <div class="wrapper"> + <button class="btn" data-bs-toggle="dropdown" aria-expanded="false"> + <i class="bi bi-caret-down-fill"></i> + </button> + + <div class="dropdown"> + <ul class="dropdown-menu"> + <li> + <button class="dropdown-item" v-on:click="console.log('Edit: ', item.ID)"> + Edit Item + </button> + </li> + <li> + <button class="dropdown-item" v-on:click="handleDelete(item.ID)"> + Delete Item + </button> + </li> + </ul> + </div> + </div> + </td> + </tr> + </tbody> + </table> +</template> + +<style> +.table-action-column .wrapper { + display: flex; + justify-content: flex-end; +} + +thead .table-action-column .wrapper { + gap: 0.5rem; +} + +tbody .table-action-column .btn { + opacity: 0; + transition: opacity 300ms; +} + +tbody tr:hover .table-action-column .btn { + opacity: 1; + transition: opacity 300ms; +} +</style> diff --git a/src/components/item_selector.vue b/src/components/item_selector.vue index 9cdbeed..5dc9b84 100644 --- a/src/components/item_selector.vue +++ b/src/components/item_selector.vue @@ -4,7 +4,7 @@ import axios from 'axios' import { useToast } from 'vue-toast-notification' import InvoiceItem from "./../classes/invoice_item" -const props = defineProps(["invoice"]) +const props = defineProps(["invoiceId"]) const emit = defineEmits(["added"]) const toast = useToast({ @@ -42,7 +42,7 @@ const submit = async (e: Event) => { submitting.value = true try { - await axios.post(`/invoice/${props.invoice.ID}/item`, toRaw(item.value)) + await axios.post(`/invoice/${props.invoiceId}/item`, toRaw(item.value)) itemSelection.value = null item.value = new InvoiceItem() emit("added") diff --git a/src/components/items_table.vue b/src/components/items_table.vue index 187ee0f..e9f103e 100644 --- a/src/components/items_table.vue +++ b/src/components/items_table.vue @@ -92,7 +92,7 @@ onMounted(() => { </thead> <tbody> - <tr v-for="(item, index) in allItems"> + <tr v-for="(item, index) in allItems" :key="item['id']"> <td scope="row">{{ index + 1 }}</td> <td>{{ item.Name }}</td> <td>{{ item.Description }}</td> diff --git a/src/views/EditInvoice.vue b/src/views/EditInvoice.vue index b134721..7a508f8 100644 --- a/src/views/EditInvoice.vue +++ b/src/views/EditInvoice.vue @@ -8,6 +8,7 @@ import Invoice from "./../classes/invoice" import invoiceHeader from './../components/invoice_header.vue' import itemSelector from './../components/item_selector.vue' +import invoiceItemsTable from './../components/invoice_items_table.vue' const toast = useToast({ position: 'top-right' @@ -15,6 +16,7 @@ const toast = useToast({ const route = useRoute() +const invoiceId = route.params.id const invoice = ref(new Invoice()) const isLoading = ref(true) @@ -22,7 +24,7 @@ const getInvoice = async () => { isLoading.value = true try { - const r = await axios.get(`/invoice/${route.params.id}`) + const r = await axios.get(`/invoice/${invoiceId}`) invoice.value = r.data.data } catch (err) { toast.error('An unhandled exception occoured. Please check logs') @@ -43,5 +45,6 @@ onMounted(() => { <template> <invoiceHeader :invoice="invoice" /> - <itemSelector :invoice="invoice" @added="refreshItems()"/> + <itemSelector :invoiceId="invoiceId" @added="refreshItems()"/> + <invoiceItemsTable :invoiceId="invoiceId" /> </template> diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue index 0a5bf4d..6ef6440 100644 --- a/src/views/HomeView.vue +++ b/src/views/HomeView.vue @@ -16,7 +16,7 @@ const getAllDrafts = async () => { allDrafts.value = res.data.data } } catch (err) { - toast.error('An unhandled exception occoured. Please check logs') + //toast.error('An unhandled exception occoured. Please check logs') console.error(err) } |