Changes to UI and other stuff
This commit is contained in:
@@ -13,32 +13,47 @@ import {
|
||||
faTrash,
|
||||
faFileAlt,
|
||||
} from "@fortawesome/free-solid-svg-icons";
|
||||
import { ref } from "vue";
|
||||
import { ref, computed } from "vue";
|
||||
import { router } from "@inertiajs/vue3";
|
||||
import DataTable from "../DataTable/DataTable.vue";
|
||||
import DataTable from "../DataTable/DataTableNew2.vue";
|
||||
import Dropdown from "@/Components/Dropdown.vue";
|
||||
import DeleteDialog from "../Dialogs/DeleteDialog.vue";
|
||||
import { Badge } from "@/Components/ui/badge";
|
||||
import TableActions from "@/Components/DataTable/TableActions.vue";
|
||||
import ActionMenuItem from "@/Components/DataTable/ActionMenuItem.vue";
|
||||
import { fmtDateTime } from "@/Utilities/functions";
|
||||
|
||||
const props = defineProps({
|
||||
documents: { type: Array, default: () => [] },
|
||||
documents: { type: [Array, Object], default: () => [] },
|
||||
viewUrlBuilder: { type: Function, default: null },
|
||||
// Optional: direct download URL builder; if absent we emit 'download'
|
||||
downloadUrlBuilder: { type: Function, default: null },
|
||||
// Optional: direct delete URL builder; if absent we emit 'delete'
|
||||
deleteUrlBuilder: { type: Function, default: null },
|
||||
edit: { type: Boolean, default: false },
|
||||
pageSize: {
|
||||
type: Number,
|
||||
default: 15,
|
||||
},
|
||||
pageSizeOptions: {
|
||||
type: Array,
|
||||
default: () => [10, 15, 25, 50, 100],
|
||||
},
|
||||
// Server-side pagination support
|
||||
clientCase: { type: Object, default: null },
|
||||
});
|
||||
|
||||
// Define columns for DataTable
|
||||
const columns = [
|
||||
{ key: 'name', label: 'Naziv' },
|
||||
{ key: 'type', label: 'Vrsta' },
|
||||
{ key: 'size', label: 'Velikost', align: 'right' },
|
||||
{ key: 'created_at', label: 'Dodano' },
|
||||
{ key: 'source', label: 'Vir' },
|
||||
{ key: 'description', label: 'Opis', align: 'center' },
|
||||
{ key: "name", label: "Naziv", sortable: false },
|
||||
{ key: "type", label: "Vrsta", sortable: false },
|
||||
{ key: "size", label: "Velikost", align: "right", sortable: false },
|
||||
{ key: "created_at", label: "Dodano", sortable: false },
|
||||
{ key: "source", label: "Vir", sortable: false },
|
||||
{ key: "description", label: "Opis", align: "center", sortable: false },
|
||||
{ key: "actions", label: "", sortable: false, hideable: false, align: "center" },
|
||||
];
|
||||
|
||||
// Derive a human-friendly source for a document: Case or Contract reference
|
||||
const sourceLabel = (doc) => {
|
||||
// Server can include optional documentable meta; fall back to type
|
||||
@@ -50,6 +65,19 @@ const sourceLabel = (doc) => {
|
||||
|
||||
const emit = defineEmits(["view", "download", "delete", "edit"]);
|
||||
|
||||
// Support both array and Resource Collection (object with data property)
|
||||
const documentsData = computed(() => {
|
||||
if (Array.isArray(props.documents)) {
|
||||
return props.documents;
|
||||
}
|
||||
return props.documents?.data || [];
|
||||
});
|
||||
|
||||
// Check if using server-side pagination
|
||||
const isServerSide = computed(() => {
|
||||
return !!(props.documents?.links && props.clientCase);
|
||||
});
|
||||
|
||||
const formatSize = (bytes) => {
|
||||
if (bytes == null) return "-";
|
||||
const thresh = 1024;
|
||||
@@ -243,19 +271,27 @@ function closeActions() {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<div class="space-y-4">
|
||||
<DataTable
|
||||
:columns="columns"
|
||||
:rows="documents"
|
||||
:show-toolbar="false"
|
||||
:data="documentsData"
|
||||
:meta="isServerSide ? documents : null"
|
||||
:route-name="isServerSide ? 'clientCase.show' : null"
|
||||
:route-params="isServerSide ? { client_case: clientCase.uuid } : {}"
|
||||
:only-props="isServerSide ? ['documents'] : []"
|
||||
:page-size="pageSize"
|
||||
:page-size-options="pageSizeOptions"
|
||||
page-param-name="documentsPage"
|
||||
per-page-param-name="documentsPerPage"
|
||||
:show-pagination="false"
|
||||
:striped="false"
|
||||
:show-toolbar="true"
|
||||
:hoverable="true"
|
||||
:show-actions="true"
|
||||
row-key="uuid"
|
||||
empty-text="Ni dokumentov."
|
||||
empty-icon="faFileAlt"
|
||||
>
|
||||
<template #toolbar-actions>
|
||||
<slot name="add" />
|
||||
</template>
|
||||
<!-- Name column -->
|
||||
<template #cell-name="{ row }">
|
||||
<div>
|
||||
@@ -267,7 +303,12 @@ function closeActions() {
|
||||
>
|
||||
{{ row.name }}
|
||||
</button>
|
||||
<Badge v-if="row.is_public" variant="secondary" class="bg-green-100 text-green-700 hover:bg-green-200">Public</Badge>
|
||||
<Badge
|
||||
v-if="row.is_public"
|
||||
variant="secondary"
|
||||
class="bg-green-100 text-green-700 hover:bg-green-200"
|
||||
>Public</Badge
|
||||
>
|
||||
</div>
|
||||
<!-- Expanded description -->
|
||||
<div
|
||||
@@ -297,12 +338,25 @@ function closeActions() {
|
||||
|
||||
<!-- Created at column -->
|
||||
<template #cell-created_at="{ row }">
|
||||
{{ new Date(row.created_at).toLocaleString() }}
|
||||
<div class="text-gray-800 font-medium leading-tight">
|
||||
{{ row.created_by }}
|
||||
</div>
|
||||
<div v-if="row.created_at" class="mt-1">
|
||||
<span
|
||||
class="inline-block px-2 py-0.5 rounded text-[11px] bg-gray-100 text-gray-600 tracking-wide"
|
||||
>
|
||||
{{ fmtDateTime(row.created_at) }}
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- Source column -->
|
||||
<template #cell-source="{ row }">
|
||||
<Badge variant="secondary" class="bg-purple-100 text-purple-700 hover:bg-purple-200">{{ sourceLabel(row) }}</Badge>
|
||||
<Badge
|
||||
variant="secondary"
|
||||
class="bg-purple-100 text-purple-700 hover:bg-purple-200"
|
||||
>{{ sourceLabel(row) }}</Badge
|
||||
>
|
||||
</template>
|
||||
|
||||
<!-- Description column -->
|
||||
@@ -321,53 +375,29 @@ function closeActions() {
|
||||
</template>
|
||||
|
||||
<!-- Actions column -->
|
||||
<template #actions="{ row }">
|
||||
<div @click.stop>
|
||||
<Dropdown align="right" width="48">
|
||||
<template #trigger>
|
||||
<button
|
||||
type="button"
|
||||
class="inline-flex items-center justify-center h-8 w-8 rounded-full hover:bg-gray-100 focus:outline-none transition-colors"
|
||||
title="Možnosti"
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
:icon="faEllipsisVertical"
|
||||
class="h-4 w-4 text-gray-700"
|
||||
/>
|
||||
</button>
|
||||
</template>
|
||||
<template #content>
|
||||
<div class="py-1">
|
||||
<button
|
||||
type="button"
|
||||
class="w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 flex items-center gap-2 transition-colors"
|
||||
@click="emit('edit', row)"
|
||||
v-if="edit"
|
||||
>
|
||||
<FontAwesomeIcon :icon="faCircleInfo" class="h-4 w-4 text-gray-600" />
|
||||
<span>Uredi</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="w-full px-4 py-2 text-left text-sm text-gray-700 hover:bg-gray-100 flex items-center gap-2 transition-colors"
|
||||
@click="handleDownload(row)"
|
||||
>
|
||||
<FontAwesomeIcon :icon="faDownload" class="h-4 w-4 text-gray-600" />
|
||||
<span>Prenos</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
class="w-full px-4 py-2 text-left text-sm text-red-600 hover:bg-red-50 flex items-center gap-2 transition-colors"
|
||||
@click="askDelete(row)"
|
||||
v-if="edit"
|
||||
>
|
||||
<FontAwesomeIcon :icon="faTrash" class="h-4 w-4" />
|
||||
<span>Izbriši</span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
</Dropdown>
|
||||
</div>
|
||||
<template #cell-actions="{ row }">
|
||||
<TableActions align="right">
|
||||
<template #default>
|
||||
<ActionMenuItem
|
||||
v-if="edit"
|
||||
:icon="faCircleInfo"
|
||||
label="Uredi"
|
||||
@click="emit('edit', row)"
|
||||
/>
|
||||
<ActionMenuItem
|
||||
:icon="faDownload"
|
||||
label="Prenos"
|
||||
@click="handleDownload(row)"
|
||||
/>
|
||||
<ActionMenuItem
|
||||
v-if="edit"
|
||||
:icon="faTrash"
|
||||
label="Izbriši"
|
||||
danger
|
||||
@click="askDelete(row)"
|
||||
/>
|
||||
</template>
|
||||
</TableActions>
|
||||
</template>
|
||||
</DataTable>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user