Added the support for generating docs from template doc

This commit is contained in:
Simon Pocrnjič
2025-10-06 21:46:28 +02:00
parent 0c8d1e0b5d
commit cec5796acf
69 changed files with 4570 additions and 374 deletions
@@ -22,6 +22,8 @@ import {
faListCheck,
faPlus,
faBoxArchive,
faFileWord,
faSpinner,
} from "@fortawesome/free-solid-svg-icons";
const props = defineProps({
@@ -53,6 +55,42 @@ const onAddActivity = (c) => emit("add-activity", c);
import { ref, computed } from "vue";
import { router, useForm } from "@inertiajs/vue3";
import axios from "axios";
// Document generation state
const generating = ref({}); // contract_uuid => boolean
const generatedDocs = ref({}); // contract_uuid => { uuid, path }
const generationError = ref({}); // contract_uuid => message
// Hard-coded slug for now; could be made a prop or dynamic select later
const templateSlug = "contract-summary";
async function generateDocument(c) {
if (!c?.uuid || generating.value[c.uuid]) return;
generating.value[c.uuid] = true;
generationError.value[c.uuid] = null;
try {
const { data } = await axios.post(
route("contracts.generate-document", { contract: c.uuid }),
{
template_slug: templateSlug,
}
);
if (data.status === "ok") {
generatedDocs.value[c.uuid] = { uuid: data.document_uuid, path: data.path };
// optimistic: reload documents list (if parent provides it) partial reload optional
router.reload({ only: ["documents"] });
} else {
generationError.value[c.uuid] = data.message || "Napaka pri generiranju.";
}
} catch (e) {
if (e?.response?.status === 422) {
generationError.value[c.uuid] = "Manjkajoči tokeni v predlogi.";
} else {
generationError.value[c.uuid] = "Neuspešno generiranje.";
}
} finally {
generating.value[c.uuid] = false;
}
}
const showObjectDialog = ref(false);
const showObjectsList = ref(false);
const selectedContract = ref(null);
@@ -465,6 +503,43 @@ const closePaymentsDialog = () => {
<span>Dodaj aktivnost</span>
</button>
<div class="my-1 border-t border-gray-100" />
<!-- Dokumenti -->
<div
class="px-3 pt-2 pb-1 text-[11px] uppercase tracking-wide text-gray-400"
>
Dokument
</div>
<button
type="button"
class="w-full px-3 py-2 text-left text-sm text-gray-700 hover:bg-gray-50 flex items-center gap-2"
:disabled="generating[c.uuid]"
@click="generateDocument(c)"
>
<FontAwesomeIcon
:icon="generating[c.uuid] ? faSpinner : faFileWord"
class="h-4 w-4 text-gray-600"
:class="generating[c.uuid] ? 'animate-spin' : ''"
/>
<span>{{
generating[c.uuid] ? "Generiranje..." : "Generiraj povzetek"
}}</span>
</button>
<a
v-if="generatedDocs[c.uuid]?.path"
:href="'/storage/' + generatedDocs[c.uuid].path"
target="_blank"
class="w-full px-3 py-2 text-left text-sm text-indigo-600 hover:bg-indigo-50 flex items-center gap-2"
>
<FontAwesomeIcon :icon="faFileWord" class="h-4 w-4" />
<span>Prenesi zadnji</span>
</a>
<div
v-if="generationError[c.uuid]"
class="px-3 py-2 text-xs text-rose-600 whitespace-pre-wrap"
>
{{ generationError[c.uuid] }}
</div>
<div class="my-1 border-t border-gray-100" />
<!-- Predmeti -->
<div