Changes
This commit is contained in:
@@ -24,18 +24,31 @@ import DateRangePicker from "@/Components/DateRangePicker.vue";
|
||||
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
|
||||
import { ButtonGroup } from "@/Components/ui/button-group";
|
||||
import AppPopover from "@/Components/app/ui/AppPopover.vue";
|
||||
import { Filter, LinkIcon, FileDown } from "lucide-vue-next";
|
||||
import { Filter, LinkIcon, FileDown, LayoutIcon } from "lucide-vue-next";
|
||||
import { Card } from "@/Components/ui/card";
|
||||
import { Badge } from "@/Components/ui/badge";
|
||||
import { hasPermission } from "@/Services/permissions";
|
||||
import InputLabel from "@/Components/InputLabel.vue";
|
||||
import { cn } from "@/lib/utils";
|
||||
import {
|
||||
DropdownMenu,
|
||||
DropdownMenuContent,
|
||||
DropdownMenuItem,
|
||||
DropdownMenuLabel,
|
||||
DropdownMenuTrigger,
|
||||
} from "@/Components/ui/dropdown-menu";
|
||||
import { toNumber } from "lodash";
|
||||
import { FormControl, FormField, FormFieldArray, FormLabel } from "@/Components/ui/form";
|
||||
import { Field, FieldLabel } from "@/Components/ui/field";
|
||||
import { toTypedSchema } from "@vee-validate/zod";
|
||||
import { z } from "zod";
|
||||
import FormChangeSegment from "./Partials/FormChangeSegment.vue";
|
||||
|
||||
const props = defineProps({
|
||||
client: Object,
|
||||
contracts: Object,
|
||||
filters: Object,
|
||||
segments: Object,
|
||||
segments: Array,
|
||||
types: Object,
|
||||
});
|
||||
|
||||
@@ -59,10 +72,20 @@ const selectedSegments = ref(
|
||||
: []
|
||||
);
|
||||
const filterPopoverOpen = ref(false);
|
||||
const selectedContracts = ref([]);
|
||||
const changeSegmentDialogOpen = ref(false);
|
||||
const contractTable = ref(null);
|
||||
|
||||
const exportDialogOpen = ref(false);
|
||||
const exportScope = ref("current");
|
||||
const exportColumns = ref(["reference", "customer", "address", "start", "segment", "balance"]);
|
||||
const exportColumns = ref([
|
||||
"reference",
|
||||
"customer",
|
||||
"address",
|
||||
"start",
|
||||
"segment",
|
||||
"balance",
|
||||
]);
|
||||
const exportError = ref("");
|
||||
const isExporting = ref(false);
|
||||
|
||||
@@ -85,6 +108,12 @@ const allColumnsSelected = computed(
|
||||
const exportDisabled = computed(
|
||||
() => exportColumns.value.length === 0 || isExporting.value
|
||||
);
|
||||
const segmentSelectItems = computed(() =>
|
||||
props.segments.map((val, i) => ({
|
||||
label: val.name,
|
||||
value: val.id,
|
||||
}))
|
||||
);
|
||||
|
||||
function applyDateFilter() {
|
||||
filterPopoverOpen.value = false;
|
||||
@@ -288,6 +317,24 @@ function extractFilenameFromHeaders(headers) {
|
||||
const asciiMatch = disposition.match(/filename="?([^";]+)"?/i);
|
||||
return asciiMatch?.[1] || null;
|
||||
}
|
||||
|
||||
function handleSelectionChange(selectedKeys) {
|
||||
selectedContracts.value = selectedKeys.map((val, i) => {
|
||||
const num = toNumber(val);
|
||||
|
||||
return props.contracts.data[num].uuid;
|
||||
});
|
||||
}
|
||||
|
||||
function openDialogChangeSegment() {
|
||||
changeSegmentDialogOpen.value = true;
|
||||
}
|
||||
|
||||
function clearContractTableSelected() {
|
||||
if (contractTable.value) {
|
||||
contractTable.value.clearSelection();
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -357,6 +404,7 @@ function extractFilenameFromHeaders(headers) {
|
||||
</Link>
|
||||
</div>
|
||||
<DataTable
|
||||
ref="contractTable"
|
||||
:columns="[
|
||||
{ key: 'reference', label: 'Referenca', sortable: false },
|
||||
{ key: 'customer', label: 'Stranka', sortable: false },
|
||||
@@ -380,11 +428,13 @@ function extractFilenameFromHeaders(headers) {
|
||||
row-key="uuid"
|
||||
:only-props="['contracts']"
|
||||
:page-size-options="[10, 15, 25, 50, 100]"
|
||||
:enable-row-selection="true"
|
||||
@selection:change="handleSelectionChange"
|
||||
page-param-name="contracts_page"
|
||||
per-page-param-name="contracts_per_page"
|
||||
:show-toolbar="true"
|
||||
>
|
||||
<template #toolbar-filters>
|
||||
<template #toolbar-filters="{ table }">
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
<AppPopover
|
||||
v-model:open="filterPopoverOpen"
|
||||
@@ -481,6 +531,32 @@ function extractFilenameFromHeaders(headers) {
|
||||
<FileDown class="h-4 w-4" />
|
||||
Izvozi v Excel
|
||||
</Button>
|
||||
<DropdownMenu v-if="table.getSelectedRowModel().rows.length > 0">
|
||||
<DropdownMenuTrigger as-child>
|
||||
<Button class="gap-2 px-3" variant="outline">
|
||||
<Badge
|
||||
class="h-5 min-w-5 rounded-full font-mono tabular-nums text-accent"
|
||||
variant="destructive"
|
||||
>
|
||||
{{ table.getSelectedRowModel().rows.length }}
|
||||
</Badge>
|
||||
Akcija
|
||||
</Button>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent align="start">
|
||||
<DropdownMenuItem @click="openDialogChangeSegment">
|
||||
<LayoutIcon />
|
||||
Spremeni segment
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
<Button
|
||||
variant="outline"
|
||||
@click="clearContractTableSelected"
|
||||
v-if="table.getSelectedRowModel().rows.length > 0"
|
||||
>
|
||||
Odznači izbrane
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
<template #cell-reference="{ row }">
|
||||
@@ -519,7 +595,7 @@ function extractFilenameFromHeaders(headers) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Excel export dialog -->
|
||||
<DialogModal :show="exportDialogOpen" max-width="3xl" @close="closeExportDialog">
|
||||
<template #title>
|
||||
<div class="space-y-1">
|
||||
@@ -626,5 +702,15 @@ function extractFilenameFromHeaders(headers) {
|
||||
</div>
|
||||
</template>
|
||||
</DialogModal>
|
||||
|
||||
<!-- Change segment selected contracts dialog -->
|
||||
|
||||
<FormChangeSegment
|
||||
:show="changeSegmentDialogOpen"
|
||||
@close="changeSegmentDialogOpen = false"
|
||||
:segments="segmentSelectItems"
|
||||
:contracts="selectedContracts"
|
||||
:clear-selected-rows="clearContractTableSelected"
|
||||
/>
|
||||
</AppLayout>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
<script setup>
|
||||
import DialogModal from "@/Components/DialogModal.vue";
|
||||
import { Button } from "@/Components/ui/button";
|
||||
import {
|
||||
Field,
|
||||
FieldContent,
|
||||
FieldDescription,
|
||||
FieldError,
|
||||
FieldLabel,
|
||||
} from "@/Components/ui/field";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/Components/ui/select";
|
||||
import { toTypedSchema } from "@vee-validate/zod";
|
||||
import { useForm, Field as VeeField } from "vee-validate";
|
||||
import { router } from "@inertiajs/vue3";
|
||||
import { onMounted, ref } from "vue";
|
||||
import z from "zod";
|
||||
|
||||
const props = defineProps({
|
||||
show: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
segments: { type: Array, default: [] },
|
||||
contracts: { type: Array, default: [] },
|
||||
clearSelectedRows: { type: Function, default: () => console.log("test") },
|
||||
});
|
||||
|
||||
const emit = defineEmits(["close"]);
|
||||
|
||||
const close = () => {
|
||||
emit("close");
|
||||
};
|
||||
|
||||
const processing = ref(false);
|
||||
|
||||
// vee-validate Form setup
|
||||
const formSchema = toTypedSchema(
|
||||
z.object({
|
||||
segment_id: z
|
||||
.number()
|
||||
.refine((val) => props.segments.find((item) => item.value == val) !== undefined, {
|
||||
message: "Izbran segment ne obstaja v zbirki segmentov",
|
||||
}),
|
||||
})
|
||||
);
|
||||
|
||||
const { handleSubmit, resetForm, errors } = useForm({
|
||||
validationSchema: formSchema,
|
||||
});
|
||||
|
||||
const onSubmit = handleSubmit((data) => {
|
||||
processing.value = true;
|
||||
router.patch(
|
||||
route("contracts.segment"),
|
||||
{
|
||||
...data,
|
||||
contracts: props.contracts,
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
router.reload({ only: ["contracts"] });
|
||||
close();
|
||||
resetForm();
|
||||
props.clearSelectedRows();
|
||||
processing.value = false;
|
||||
},
|
||||
onError: (e) => {
|
||||
errors = e;
|
||||
|
||||
processing.value = false;
|
||||
},
|
||||
onFinish: () => {
|
||||
processing.value = false;
|
||||
},
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
console.log(props.segments);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<DialogModal :show="show" @close="close">
|
||||
<template #title>
|
||||
<h3 class="text-lg font-semibold leading-6 text-foreground">
|
||||
Spremeni segment pogodbam
|
||||
</h3>
|
||||
</template>
|
||||
|
||||
<template #content>
|
||||
<form id="segment-change-form" @submit.prevent="onSubmit">
|
||||
<VeeField v-slot="{ field, errors }" name="segment_id">
|
||||
<Field orientation="responsive" :data-invalid="!!errors.length">
|
||||
<FieldContent>
|
||||
<FieldLabel for="segment">Segment</FieldLabel>
|
||||
<FieldDescription>Izberi segment za preusmeritev</FieldDescription>
|
||||
<FieldError v-if="errors.length" :errors="errors" />
|
||||
</FieldContent>
|
||||
|
||||
<Select
|
||||
:model-value="field.value"
|
||||
@update:model-value="field.onChange"
|
||||
@blur="field.onBlur"
|
||||
>
|
||||
<SelectTrigger id="segment_id" :aria-invalid="!!errors.length">
|
||||
<SelectValue placeholder="Izberi segment..."></SelectValue>
|
||||
</SelectTrigger>
|
||||
<SelectContent position="item-aligned">
|
||||
<SelectItem value="auto"> Auto </SelectItem>
|
||||
<SelectItem
|
||||
v-for="segment in segments"
|
||||
:key="segment.label"
|
||||
:value="segment.value"
|
||||
>
|
||||
{{ segment.label }}
|
||||
</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</Field>
|
||||
</VeeField>
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<template #footer>
|
||||
<div class="flex flex-row gap-2">
|
||||
<Button
|
||||
type="button"
|
||||
:disabled="processing"
|
||||
variant="ghost"
|
||||
@click="
|
||||
() => {
|
||||
close();
|
||||
resetForm();
|
||||
}
|
||||
"
|
||||
>
|
||||
Prekliči
|
||||
</Button>
|
||||
<Button type="submit" form="segment-change-form" :disabled="processing">
|
||||
Potrdi
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
</DialogModal>
|
||||
</template>
|
||||
|
||||
<style></style>
|
||||
Reference in New Issue
Block a user