changes to UI mostly
This commit is contained in:
@@ -1,53 +1,163 @@
|
||||
<script setup>
|
||||
import BasicTable from '@/Components/BasicTable.vue';
|
||||
import { LinkOptions as C_LINK, TableColumn as C_TD, TableRow as C_TR} from '@/Shared/AppObjects';
|
||||
import { ref } from "vue";
|
||||
import { router } from "@inertiajs/vue3";
|
||||
import Dropdown from "@/Components/Dropdown.vue";
|
||||
import ConfirmationModal from "@/Components/ConfirmationModal.vue";
|
||||
import SecondaryButton from "@/Components/SecondaryButton.vue";
|
||||
import DangerButton from "@/Components/DangerButton.vue";
|
||||
import {
|
||||
FwbTable,
|
||||
FwbTableHead,
|
||||
FwbTableHeadCell,
|
||||
FwbTableBody,
|
||||
FwbTableRow,
|
||||
FwbTableCell,
|
||||
} from "flowbite-vue";
|
||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||
import { library } from "@fortawesome/fontawesome-svg-core";
|
||||
import { faTrash, faEllipsisVertical } from "@fortawesome/free-solid-svg-icons";
|
||||
|
||||
library.add(faTrash, faEllipsisVertical);
|
||||
|
||||
const props = defineProps({
|
||||
client_case: Object,
|
||||
activities: Object
|
||||
client_case: Object,
|
||||
activities: Object,
|
||||
});
|
||||
|
||||
// Dropdown component manages its own open/close state
|
||||
|
||||
let header = [
|
||||
C_TD.make('Pogodba', 'header'),
|
||||
C_TD.make('Datum', 'header'),
|
||||
C_TD.make('Akcija', 'header'),
|
||||
C_TD.make('Odločitev', 'header'),
|
||||
C_TD.make('Opomba', 'header'),
|
||||
C_TD.make('Datum zapadlosti', 'header'),
|
||||
C_TD.make('Znesek obljube', 'header'),
|
||||
C_TD.make('Dodal', 'header')
|
||||
];
|
||||
const fmtDate = (d) => {
|
||||
if (!d) return "";
|
||||
try {
|
||||
return new Date(d).toLocaleDateString("sl-SI");
|
||||
} catch (e) {
|
||||
return String(d);
|
||||
}
|
||||
};
|
||||
const fmtCurrency = (v) => {
|
||||
const n = Number(v ?? 0);
|
||||
try {
|
||||
return new Intl.NumberFormat("sl-SI", { style: "currency", currency: "EUR" }).format(
|
||||
n
|
||||
);
|
||||
} catch {
|
||||
return `${n.toFixed(2)} €`;
|
||||
}
|
||||
};
|
||||
|
||||
const createBody = (data) => {
|
||||
let body = [];
|
||||
|
||||
data.forEach((p) => {
|
||||
const createdDate = new Date(p.created_at).toLocaleDateString('de');
|
||||
const dueDate = (p.due_date) ? new Date().toLocaleDateString('de') : null;
|
||||
const userName = (p.user && p.user.name) ? p.user.name : (p.user_name || '');
|
||||
|
||||
const cols = [
|
||||
C_TD.make(p.contract?.reference ?? ''),
|
||||
C_TD.make(createdDate, 'body' ),
|
||||
C_TD.make(p.action.name, 'body'),
|
||||
C_TD.make(p.decision.name, 'body'),
|
||||
C_TD.make(p.note, 'body' ),
|
||||
C_TD.make(dueDate, 'body' ),
|
||||
C_TD.make(Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(p.amount), 'body' ),
|
||||
C_TD.make(userName, 'body')
|
||||
];
|
||||
|
||||
body.push(
|
||||
C_TR.make(cols)
|
||||
)
|
||||
});
|
||||
|
||||
return body;
|
||||
}
|
||||
const deleteActivity = (row) => {
|
||||
if (!row?.id) return;
|
||||
router.delete(
|
||||
route("clientCase.activity.delete", {
|
||||
client_case: props.client_case.uuid,
|
||||
activity: row.id,
|
||||
}),
|
||||
{
|
||||
preserveScroll: true,
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// Confirmation modal state and handlers
|
||||
const confirmDelete = ref(false);
|
||||
const toDeleteRow = ref(null);
|
||||
const openDelete = (row) => {
|
||||
toDeleteRow.value = row;
|
||||
confirmDelete.value = true;
|
||||
};
|
||||
const cancelDelete = () => {
|
||||
confirmDelete.value = false;
|
||||
toDeleteRow.value = null;
|
||||
};
|
||||
const confirmDeleteAction = () => {
|
||||
if (toDeleteRow.value) {
|
||||
deleteActivity(toDeleteRow.value);
|
||||
}
|
||||
confirmDelete.value = false;
|
||||
toDeleteRow.value = null;
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BasicTable :header="header" :body="createBody(activities.data)" />
|
||||
</template>
|
||||
<div class="overflow-x-auto">
|
||||
<FwbTable hoverable striped class="min-w-full text-left text-sm">
|
||||
<FwbTableHead>
|
||||
<FwbTableHeadCell class="py-2 pr-4">Pogodba</FwbTableHeadCell>
|
||||
<FwbTableHeadCell class="py-2 pr-4">Datum</FwbTableHeadCell>
|
||||
<FwbTableHeadCell class="py-2 pr-4">Akcija</FwbTableHeadCell>
|
||||
<FwbTableHeadCell class="py-2 pr-4">Odločitev</FwbTableHeadCell>
|
||||
<FwbTableHeadCell class="py-2 pr-4">Opomba</FwbTableHeadCell>
|
||||
<FwbTableHeadCell class="py-2 pr-4">Datum zapadlosti</FwbTableHeadCell>
|
||||
<FwbTableHeadCell class="py-2 pr-4 text-right">Znesek obljube</FwbTableHeadCell>
|
||||
<FwbTableHeadCell class="py-2 pr-4">Dodal</FwbTableHeadCell>
|
||||
<FwbTableHeadCell class="py-2 pl-2 pr-2 w-8 text-right"></FwbTableHeadCell>
|
||||
</FwbTableHead>
|
||||
|
||||
<FwbTableBody>
|
||||
<FwbTableRow v-for="row in activities.data" :key="row.id" class="border-b">
|
||||
<FwbTableCell class="py-2 pr-4">{{
|
||||
row.contract?.reference || ""
|
||||
}}</FwbTableCell>
|
||||
<FwbTableCell class="py-2 pr-4">{{ fmtDate(row.created_at) }}</FwbTableCell>
|
||||
<FwbTableCell class="py-2 pr-4">{{ row.action?.name || "" }}</FwbTableCell>
|
||||
<FwbTableCell class="py-2 pr-4">{{ row.decision?.name || "" }}</FwbTableCell>
|
||||
<FwbTableCell class="py-2 pr-4">{{ row.note || "" }}</FwbTableCell>
|
||||
<FwbTableCell class="py-2 pr-4">{{ fmtDate(row.due_date) }}</FwbTableCell>
|
||||
<FwbTableCell class="py-2 pr-4 text-right">{{
|
||||
fmtCurrency(row.amount)
|
||||
}}</FwbTableCell>
|
||||
<FwbTableCell class="py-2 pr-4">{{
|
||||
row.user?.name || row.user_name || ""
|
||||
}}</FwbTableCell>
|
||||
<FwbTableCell class="py-2 pl-2 pr-2 text-right">
|
||||
<Dropdown align="right" width="30" :content-classes="['py-1', 'bg-white']">
|
||||
<template #trigger>
|
||||
<button
|
||||
type="button"
|
||||
class="inline-flex items-center justify-center w-8 h-8 rounded hover:bg-gray-100"
|
||||
aria-haspopup="menu"
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
:icon="['fas', 'ellipsis-vertical']"
|
||||
class="text-gray-600 text-[20px]"
|
||||
/>
|
||||
</button>
|
||||
</template>
|
||||
<template #content>
|
||||
<button
|
||||
type="button"
|
||||
class="w-full flex items-center gap-2 px-3 py-2 text-sm hover:bg-red-50 text-red-600"
|
||||
@click.stop="openDelete(row)"
|
||||
>
|
||||
<FontAwesomeIcon :icon="['fas', 'trash']" class="text-[16px]" />
|
||||
<span>Izbriši</span>
|
||||
</button>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</FwbTableCell>
|
||||
</FwbTableRow>
|
||||
|
||||
<FwbTableRow v-if="!activities?.data || activities.data.length === 0">
|
||||
<FwbTableCell :colspan="9" class="py-4 text-gray-500"
|
||||
>Ni aktivnosti.</FwbTableCell
|
||||
>
|
||||
</FwbTableRow>
|
||||
</FwbTableBody>
|
||||
</FwbTable>
|
||||
</div>
|
||||
|
||||
<!-- Confirm deletion modal -->
|
||||
<ConfirmationModal :show="confirmDelete" @close="cancelDelete">
|
||||
<template #title>Potrditev</template>
|
||||
<template #content>
|
||||
Ali ste prepričani, da želite izbrisati to aktivnost? Tega dejanja ni mogoče
|
||||
razveljaviti.
|
||||
</template>
|
||||
<template #footer>
|
||||
<SecondaryButton type="button" @click="cancelDelete">Prekliči</SecondaryButton>
|
||||
<DangerButton type="button" class="ml-2" @click="confirmDeleteAction"
|
||||
>Izbriši</DangerButton
|
||||
>
|
||||
</template>
|
||||
</ConfirmationModal>
|
||||
</template>
|
||||
|
||||
@@ -94,10 +94,21 @@ const storeOrUpdate = () => {
|
||||
},
|
||||
preserveScroll: true,
|
||||
}
|
||||
const params = {}
|
||||
try {
|
||||
const url = new URL(window.location.href)
|
||||
const seg = url.searchParams.get('segment')
|
||||
if (seg) params.segment = seg
|
||||
} catch (e) {}
|
||||
if (isEdit) {
|
||||
formContract.put(route('clientCase.contract.update', { client_case: props.client_case.uuid, uuid: formContract.uuid }), options)
|
||||
formContract.put(route('clientCase.contract.update', { client_case: props.client_case.uuid, uuid: formContract.uuid, ...params }), options)
|
||||
} else {
|
||||
formContract.post(route('clientCase.contract.store', props.client_case), options)
|
||||
// route helper merges params for GET; for POST we can append query manually if needed
|
||||
let postUrl = route('clientCase.contract.store', props.client_case)
|
||||
if (params.segment) {
|
||||
postUrl += (postUrl.includes('?') ? '&' : '?') + 'segment=' + encodeURIComponent(params.segment)
|
||||
}
|
||||
formContract.post(postUrl, options)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user