Changes to import and notifications

This commit is contained in:
Simon Pocrnjič
2025-10-13 21:14:10 +02:00
parent 0bbed64542
commit 79b3e20b02
28 changed files with 2173 additions and 438 deletions
+158
View File
@@ -82,6 +82,74 @@ const previewColumns = ref([]);
const previewTruncated = ref(false);
const previewLimit = ref(200);
// Import options (persisted on Import): show_missing and reactivate
const showMissingEnabled = ref(Boolean(props.import?.show_missing ?? false));
const reactivateEnabled = ref(Boolean(props.import?.reactivate ?? false));
async function saveImportOptions() {
if (!importId.value) return;
try {
await axios.post(
route("imports.options", { import: importId.value }),
{
show_missing: !!showMissingEnabled.value,
// keep existing reactivate value if UI doesn't expose it here
reactivate: !!reactivateEnabled.value,
},
{ headers: { Accept: "application/json" }, withCredentials: true }
);
} catch (e) {
console.error(
"Save import options failed",
e.response?.status || "",
e.response?.data || e
);
}
}
// Missing contracts (post-finish) UI state
const showMissingContracts = ref(false);
const missingContractsLoading = ref(false);
const missingContracts = ref([]);
const contractRefIsKeyref = computed(() => {
return (persistedMappings.value || []).some((m) => {
const tf = String(m?.target_field || "")
.toLowerCase()
.trim();
const am = String(m?.apply_mode || "")
.toLowerCase()
.trim();
return ["contract.reference", "contracts.reference"].includes(tf) && am === "keyref";
});
});
const canShowMissingButton = computed(() => {
return contractRefIsKeyref.value && !!showMissingEnabled.value;
});
async function openMissingContracts() {
if (!importId.value || !contractRefIsKeyref.value) return;
showMissingContracts.value = true;
missingContractsLoading.value = true;
try {
const { data } = await axios.get(
route("imports.missing-contracts", { import: importId.value }),
{
headers: { Accept: "application/json" },
withCredentials: true,
}
);
missingContracts.value = Array.isArray(data?.missing) ? data.missing : [];
} catch (e) {
console.error(
"Missing contracts fetch failed",
e.response?.status || "",
e.response?.data || e
);
missingContracts.value = [];
} finally {
missingContractsLoading.value = false;
}
}
// Determine if all detected columns are mapped with entity+field
function evaluateMappingSaved() {
console.log("here the evaluation happen of mapping save!");
@@ -1028,6 +1096,11 @@ async function fetchSimulation() {
:class="['px-2 py-0.5 rounded-full text-xs font-medium', statusInfo.classes]"
>{{ statusInfo.label }}</span
>
<span
v-if="showMissingEnabled"
class="text-[10px] px-1 py-0.5 rounded bg-amber-100 text-amber-700 align-middle"
>seznam manjkajočih</span
>
</div>
</div>
</template>
@@ -1065,6 +1138,22 @@ async function fetchSimulation() {
<span class="font-medium">{{ props.import?.valid_rows ?? "—" }}</span>
</div>
</div>
<div class="mt-3 flex items-center gap-2">
<button
class="px-3 py-1.5 bg-gray-700 text-white text-xs rounded"
@click.prevent="openPreview"
>
Ogled CSV
</button>
<button
v-if="canShowMissingButton"
class="px-3 py-1.5 bg-indigo-600 text-white text-xs rounded"
@click.prevent="openMissingContracts"
title="Prikaži aktivne pogodbe, ki niso bile prisotne v uvozu (samo keyref)"
>
Ogled manjkajoče
</button>
</div>
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<TemplateControls
@@ -1096,6 +1185,24 @@ async function fetchSimulation() {
"
@apply-template="applyTemplateToImport"
/>
<!-- Import options -->
<div v-if="!isCompleted" class="mt-2 p-3 rounded border bg-gray-50">
<div class="flex items-center gap-3">
<label class="inline-flex items-center text-sm text-gray-700">
<input
type="checkbox"
class="rounded mr-2"
v-model="showMissingEnabled"
@change="saveImportOptions"
/>
<span>Seznam manjkajočih (po končanem uvozu)</span>
</label>
</div>
<p class="mt-1 text-xs text-gray-500">
Ko je omogočeno in je "contract.reference" nastavljen na keyref, bo po
končanem uvozu na voljo gumb za ogled pogodb, ki jih ni v datoteki.
</p>
</div>
<ChecklistSteps :steps="stepStates" :missing-critical="missingCritical" />
</div>
@@ -1173,6 +1280,57 @@ async function fetchSimulation() {
@change-limit="(val) => (previewLimit = val)"
@refresh="fetchPreview"
/>
<!-- Missing contracts modal -->
<Modal
:show="showMissingContracts"
max-width="2xl"
@close="showMissingContracts = false"
>
<div class="p-4 max-h-[70vh] overflow-auto">
<div class="flex items-center justify-between mb-4">
<h3 class="font-semibold text-lg">Manjkajoče pogodbe (aktivne, ne-arhivirane)</h3>
<button
class="text-gray-500 hover:text-gray-700"
@click.prevent="showMissingContracts = false"
>
Zapri
</button>
</div>
<div v-if="missingContractsLoading" class="py-8 text-center text-sm text-gray-500">
Nalagam …
</div>
<div v-else>
<div v-if="!missingContracts.length" class="py-6 text-sm text-gray-600">
Ni zadetkov.
</div>
<ul v-else class="divide-y divide-gray-200">
<li
v-for="row in missingContracts"
:key="row.uuid"
class="py-2 text-sm flex items-center justify-between"
>
<div class="min-w-0">
<div class="font-mono text-gray-800">{{ row.reference }}</div>
<div class="text-xs text-gray-500 truncate">
<span class="font-medium text-gray-600">Primer: </span>
<span>{{ row.full_name || "" }}</span>
<span v-if="row.balance_amount != null" class="ml-2"
>• {{ formatMoney(row.balance_amount) }}</span
>
</div>
</div>
<div class="flex-shrink-0">
<a
:href="route('clientCase.show', row.case_uuid)"
class="text-blue-600 hover:underline text-xs"
>Odpri primer</a
>
</div>
</li>
</ul>
</div>
</div>
</Modal>
<SimulationModal
:show="showPaymentSim"
:rows="paymentSimRows"