update case index page segment index and show page
This commit is contained in:
@@ -2,44 +2,87 @@
|
||||
import AppLayout from "@/Layouts/AppLayout.vue";
|
||||
import SectionTitle from "@/Components/SectionTitle.vue";
|
||||
import { Link, router } from "@inertiajs/vue3";
|
||||
import { ref } from "vue";
|
||||
import { computed, ref } from "vue";
|
||||
import DataTable from "@/Components/DataTable/DataTableNew2.vue";
|
||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||
import { faFolderOpen } from "@fortawesome/free-solid-svg-icons";
|
||||
import Pagination from "@/Components/Pagination.vue";
|
||||
import AppCard from "@/Components/app/ui/card/AppCard.vue";
|
||||
import { FolderOpenIcon } from "lucide-vue-next";
|
||||
import { Filter, FolderOpenIcon } from "lucide-vue-next";
|
||||
import CardTitle from "@/Components/ui/card/CardTitle.vue";
|
||||
import { fmtCurrency, fmtDateDMY } from "@/Utilities/functions";
|
||||
import { Button } from "@/Components/ui/button";
|
||||
import AppPopover from "@/Components/app/ui/AppPopover.vue";
|
||||
import InputLabel from "@/Components/InputLabel.vue";
|
||||
import { Input } from "@/Components/ui/input";
|
||||
import DateRangePicker from "@/Components/DateRangePicker.vue";
|
||||
import AppMultiSelect from "@/Components/app/ui/AppMultiSelect.vue";
|
||||
|
||||
const props = defineProps({
|
||||
client_cases: Object,
|
||||
filters: Object,
|
||||
clients: {
|
||||
type: Array,
|
||||
default: () => [],
|
||||
},
|
||||
});
|
||||
|
||||
// Initial search for DataTable toolbar
|
||||
const search = ref(props.filters?.search || "");
|
||||
const dateRange = ref({
|
||||
start: props.filters?.from || null,
|
||||
end: props.filters?.to || null,
|
||||
});
|
||||
const selectedClients = ref(
|
||||
Array.isArray(props.filters?.clients)
|
||||
? props.filters.clients.map((value) => String(value))
|
||||
: []
|
||||
);
|
||||
const filterPopoverOpen = ref(false);
|
||||
|
||||
// Format helpers
|
||||
const fmtCurrency = (v) => {
|
||||
const n = Number(v ?? 0);
|
||||
try {
|
||||
return new Intl.NumberFormat("sl-SI", { style: "currency", currency: "EUR" }).format(
|
||||
n
|
||||
);
|
||||
} catch (e) {
|
||||
return `${n.toFixed(2)} €`;
|
||||
const appliedFilterCount = computed(() => {
|
||||
let count = 0;
|
||||
if (search.value?.trim()) count += 1;
|
||||
if (dateRange.value?.start || dateRange.value?.end) count += 1;
|
||||
if (selectedClients.value.length) count += 1;
|
||||
return count;
|
||||
});
|
||||
|
||||
function applyFilters() {
|
||||
filterPopoverOpen.value = false;
|
||||
|
||||
const params = {};
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
const currentPerPage = searchParams.get("perPage");
|
||||
if (currentPerPage) {
|
||||
params.perPage = currentPerPage;
|
||||
}
|
||||
if (search.value && search.value.trim() !== "") {
|
||||
params.search = search.value.trim();
|
||||
}
|
||||
if (dateRange.value?.start) {
|
||||
params.from = dateRange.value.start;
|
||||
}
|
||||
if (dateRange.value?.end) {
|
||||
params.to = dateRange.value.end;
|
||||
}
|
||||
if (selectedClients.value.length > 0) {
|
||||
params.clients = selectedClients.value.join(",");
|
||||
}
|
||||
};
|
||||
|
||||
const fmtDateDMY = (v) => {
|
||||
if (!v) return "-";
|
||||
const d = new Date(v);
|
||||
if (isNaN(d)) return "-";
|
||||
const dd = String(d.getDate()).padStart(2, "0");
|
||||
const mm = String(d.getMonth() + 1).padStart(2, "0");
|
||||
const yyyy = d.getFullYear();
|
||||
return `${dd}.${mm}.${yyyy}`;
|
||||
};
|
||||
router.get(route("clientCase"), params, {
|
||||
preserveState: true,
|
||||
replace: true,
|
||||
preserveScroll: true,
|
||||
});
|
||||
}
|
||||
|
||||
function clearFilters() {
|
||||
dateRange.value = { start: null, end: null };
|
||||
selectedClients.value = [];
|
||||
search.value = "";
|
||||
applyFilters();
|
||||
}
|
||||
</script>
|
||||
<template>
|
||||
<AppLayout title="Client cases">
|
||||
@@ -80,13 +123,99 @@ const fmtDateDMY = (v) => {
|
||||
},
|
||||
]"
|
||||
:data="client_cases.data || []"
|
||||
:meta="client_cases"
|
||||
route-name="clientCase"
|
||||
page-param-name="clientCasesPage"
|
||||
per-page-param-name="perPage"
|
||||
:page-size="client_cases.per_page"
|
||||
:page-size-options="[10, 15, 25, 50, 100]"
|
||||
:show-pagination="false"
|
||||
:show-toolbar="true"
|
||||
:hoverable="true"
|
||||
row-key="uuid"
|
||||
empty-text="Ni najdenih primerov."
|
||||
>
|
||||
<template #toolbar-filters>
|
||||
<AppPopover
|
||||
v-model:open="filterPopoverOpen"
|
||||
align="start"
|
||||
content-class="w-[400px]"
|
||||
>
|
||||
<template #trigger>
|
||||
<Button variant="outline" size="sm" class="gap-2">
|
||||
<Filter class="h-4 w-4" />
|
||||
Filtri
|
||||
<span
|
||||
v-if="appliedFilterCount > 0"
|
||||
class="ml-1 rounded-full bg-primary px-2 py-0.5 text-xs text-primary-foreground"
|
||||
>
|
||||
{{ appliedFilterCount }}
|
||||
</span>
|
||||
</Button>
|
||||
</template>
|
||||
<div class="space-y-4">
|
||||
<div class="space-y-2">
|
||||
<h4 class="font-medium text-sm">Filtri primerov</h4>
|
||||
<p class="text-sm text-muted-foreground">
|
||||
Izberite parametre za zožanje prikaza primerov.
|
||||
</p>
|
||||
</div>
|
||||
<div class="space-y-3">
|
||||
<div class="space-y-1.5">
|
||||
<InputLabel>Iskanje</InputLabel>
|
||||
<Input
|
||||
v-model="search"
|
||||
type="text"
|
||||
placeholder="Išči po imenu, davčni številki ..."
|
||||
/>
|
||||
</div>
|
||||
<div class="space-y-1.5">
|
||||
<InputLabel>Datumski obseg (ustvarjeno)</InputLabel>
|
||||
<DateRangePicker
|
||||
v-model="dateRange"
|
||||
format="dd.MM.yyyy"
|
||||
placeholder="Izberi datume"
|
||||
/>
|
||||
</div>
|
||||
<div class="space-y-1.5">
|
||||
<InputLabel>Stranke</InputLabel>
|
||||
<AppMultiSelect
|
||||
v-model="selectedClients"
|
||||
:items="
|
||||
(props.clients || []).map((client) => ({
|
||||
value: String(client.id),
|
||||
label: client.name,
|
||||
}))
|
||||
"
|
||||
placeholder="Vse stranke"
|
||||
search-placeholder="Išči stranko..."
|
||||
empty-text="Ni strank"
|
||||
chip-variant="secondary"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex justify-end gap-2 pt-2 border-t">
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
:disabled="
|
||||
!dateRange?.start &&
|
||||
!dateRange?.end &&
|
||||
selectedClients.length === 0 &&
|
||||
search === ''
|
||||
"
|
||||
@click="clearFilters"
|
||||
>
|
||||
Počisti
|
||||
</Button>
|
||||
<Button type="button" size="sm" @click="applyFilters">
|
||||
Uporabi
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</AppPopover>
|
||||
</template>
|
||||
<template #cell-nu="{ row }">
|
||||
{{ row.person?.nu || "-" }}
|
||||
</template>
|
||||
|
||||
Reference in New Issue
Block a user