|
|
@@ -2,7 +2,7 @@
|
|
|
<div>
|
|
|
<input
|
|
|
ref="fileInputRef"
|
|
|
- accept="image/*,video/*,.pdf"
|
|
|
+ accept="image/jpeg,image/png,.pdf"
|
|
|
style="display: none"
|
|
|
type="file"
|
|
|
@change="onFileSelected"
|
|
|
@@ -20,9 +20,7 @@
|
|
|
@on-add-item="handleAdd"
|
|
|
>
|
|
|
<template #body-cell-period="{ row }">
|
|
|
- <q-td>
|
|
|
- {{ row.signature_date }} — {{ row.end_date }}
|
|
|
- </q-td>
|
|
|
+ <q-td> {{ row.signature_date }} — {{ row.end_date }} </q-td>
|
|
|
</template>
|
|
|
|
|
|
<template #body-cell-status="{ row }">
|
|
|
@@ -36,10 +34,7 @@
|
|
|
|
|
|
<template #body-cell-actions="{ row }">
|
|
|
<q-td align="center">
|
|
|
- <q-item-section
|
|
|
- class="no-wrap"
|
|
|
- style="flex-direction: row; gap: 4px"
|
|
|
- >
|
|
|
+ <q-item-section class="no-wrap" style="flex-direction: row; gap: 4px">
|
|
|
<q-btn
|
|
|
v-if="canEditContract"
|
|
|
icon="mdi-pencil-outline"
|
|
|
@@ -47,9 +42,7 @@
|
|
|
style="width: 36px"
|
|
|
@click.prevent.stop="handleEdit(row)"
|
|
|
>
|
|
|
- <q-tooltip>
|
|
|
- Editar contrato
|
|
|
- </q-tooltip>
|
|
|
+ <q-tooltip> Editar contrato </q-tooltip>
|
|
|
</q-btn>
|
|
|
|
|
|
<q-btn
|
|
|
@@ -57,20 +50,45 @@
|
|
|
outline
|
|
|
style="width: 36px"
|
|
|
@click.prevent.stop="handleHistory(row)"
|
|
|
+ >
|
|
|
+ <q-tooltip> Ver histórico </q-tooltip>
|
|
|
+ </q-btn>
|
|
|
+
|
|
|
+ <q-btn
|
|
|
+ v-if="row.file_url || canEdit"
|
|
|
+ :icon="
|
|
|
+ row.file_url ? 'mdi-file-eye-outline' : 'mdi-file-plus-outline'
|
|
|
+ "
|
|
|
+ :loading="generatingId === row.id"
|
|
|
+ outline
|
|
|
+ style="width: 36px"
|
|
|
+ @click.prevent.stop="handleContractFile(row)"
|
|
|
>
|
|
|
<q-tooltip>
|
|
|
- Ver histórico
|
|
|
+ {{
|
|
|
+ row.file_url
|
|
|
+ ? "Visualizar arquivo do contrato"
|
|
|
+ : "Gerar arquivo do contrato"
|
|
|
+ }}
|
|
|
</q-tooltip>
|
|
|
</q-btn>
|
|
|
|
|
|
<q-btn
|
|
|
v-if="canEdit"
|
|
|
- icon="mdi-paperclip"
|
|
|
+ icon="mdi-file-sign"
|
|
|
outline
|
|
|
style="width: 36px"
|
|
|
:loading="uploadingId === row.id"
|
|
|
@click.prevent.stop="triggerFileInput(row)"
|
|
|
- />
|
|
|
+ >
|
|
|
+ <q-tooltip>
|
|
|
+ {{
|
|
|
+ row.signed_file_url
|
|
|
+ ? "Substituir contrato assinado"
|
|
|
+ : "Anexar contrato assinado"
|
|
|
+ }}
|
|
|
+ </q-tooltip>
|
|
|
+ </q-btn>
|
|
|
|
|
|
<q-btn
|
|
|
v-if="canEdit"
|
|
|
@@ -82,41 +100,24 @@
|
|
|
<q-menu>
|
|
|
<q-list style="min-width: 170px">
|
|
|
<template
|
|
|
- v-if="
|
|
|
- row.status === 'frozen' ||
|
|
|
- row.status === 'cancelled'
|
|
|
- "
|
|
|
+ v-if="row.status === 'frozen' || row.status === 'cancelled'"
|
|
|
>
|
|
|
<q-item
|
|
|
v-close-popup
|
|
|
clickable
|
|
|
@click="handleReactivate(row)"
|
|
|
>
|
|
|
- <q-item-section>
|
|
|
- Reativar Contrato
|
|
|
- </q-item-section>
|
|
|
+ <q-item-section> Reativar Contrato </q-item-section>
|
|
|
</q-item>
|
|
|
</template>
|
|
|
|
|
|
<template v-else>
|
|
|
- <q-item
|
|
|
- v-close-popup
|
|
|
- clickable
|
|
|
- @click="handleFreeze(row)"
|
|
|
- >
|
|
|
- <q-item-section>
|
|
|
- Trancar Contrato
|
|
|
- </q-item-section>
|
|
|
+ <q-item v-close-popup clickable @click="handleFreeze(row)">
|
|
|
+ <q-item-section> Trancar Contrato </q-item-section>
|
|
|
</q-item>
|
|
|
|
|
|
- <q-item
|
|
|
- v-close-popup
|
|
|
- clickable
|
|
|
- @click="handleCancel(row)"
|
|
|
- >
|
|
|
- <q-item-section>
|
|
|
- Cancelar Contrato
|
|
|
- </q-item-section>
|
|
|
+ <q-item v-close-popup clickable @click="handleCancel(row)">
|
|
|
+ <q-item-section> Cancelar Contrato </q-item-section>
|
|
|
</q-item>
|
|
|
</template>
|
|
|
</q-list>
|
|
|
@@ -131,8 +132,9 @@
|
|
|
|
|
|
<script setup>
|
|
|
import {
|
|
|
- attachContractFile,
|
|
|
+ attachSignedContractFile,
|
|
|
cancelContract,
|
|
|
+ generateStudentContractFile,
|
|
|
getStudentContracts,
|
|
|
reactivateContract,
|
|
|
} from "src/api/studentContract";
|
|
|
@@ -159,6 +161,7 @@ const permissions = permissionStore();
|
|
|
|
|
|
const fileInputRef = ref(null);
|
|
|
const rows = ref([]);
|
|
|
+const generatingId = ref(null);
|
|
|
const uploadingId = ref(null);
|
|
|
|
|
|
const canAdd = computed(() =>
|
|
|
@@ -211,9 +214,7 @@ const confirmAction = (title, message, apiFunction, contract) => {
|
|
|
try {
|
|
|
const updated = await apiFunction(contract.id);
|
|
|
|
|
|
- const index = rows.value.findIndex(
|
|
|
- (row) => row.id === contract.id,
|
|
|
- );
|
|
|
+ const index = rows.value.findIndex((row) => row.id === contract.id);
|
|
|
|
|
|
if (index !== -1) {
|
|
|
rows.value[index] = updated;
|
|
|
@@ -253,9 +254,7 @@ const handleFreeze = (contract) => {
|
|
|
contract,
|
|
|
},
|
|
|
}).onOk((updated) => {
|
|
|
- const index = rows.value.findIndex(
|
|
|
- (row) => row.id === contract.id,
|
|
|
- );
|
|
|
+ const index = rows.value.findIndex((row) => row.id === contract.id);
|
|
|
|
|
|
if (index !== -1) {
|
|
|
rows.value[index] = {
|
|
|
@@ -276,6 +275,50 @@ const handleHistory = (contract) => {
|
|
|
});
|
|
|
};
|
|
|
|
|
|
+const handleContractFile = async (contract) => {
|
|
|
+ if (contract.file_url) {
|
|
|
+ window.open(contract.file_url, "_blank", "noopener,noreferrer");
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ const fileWindow = window.open("", "_blank");
|
|
|
+
|
|
|
+ generatingId.value = contract.id;
|
|
|
+
|
|
|
+ try {
|
|
|
+ const updated = await generateStudentContractFile(contract.id);
|
|
|
+
|
|
|
+ const index = rows.value.findIndex((row) => row.id === contract.id);
|
|
|
+
|
|
|
+ if (index !== -1) {
|
|
|
+ rows.value[index] = {
|
|
|
+ ...rows.value[index],
|
|
|
+ ...updated,
|
|
|
+ };
|
|
|
+ }
|
|
|
+
|
|
|
+ if (updated.file_url && fileWindow) {
|
|
|
+ fileWindow.location.href = updated.file_url;
|
|
|
+ } else {
|
|
|
+ fileWindow?.close();
|
|
|
+
|
|
|
+ throw new Error("A API não retornou o arquivo gerado.");
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ fileWindow?.close();
|
|
|
+
|
|
|
+ console.error(error);
|
|
|
+
|
|
|
+ $q.notify({
|
|
|
+ message: "Erro ao gerar o arquivo do contrato.",
|
|
|
+ type: "negative",
|
|
|
+ });
|
|
|
+ } finally {
|
|
|
+ generatingId.value = null;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
const handleReactivate = (contract) => {
|
|
|
confirmAction(
|
|
|
"Reativar Contrato",
|
|
|
@@ -301,23 +344,21 @@ const onFileSelected = async (event) => {
|
|
|
|
|
|
formData.append("file", file);
|
|
|
|
|
|
- const updated = await attachContractFile(
|
|
|
- pendingContractId,
|
|
|
- formData,
|
|
|
- );
|
|
|
+ const updated = await attachSignedContractFile(pendingContractId, formData);
|
|
|
|
|
|
- const index = rows.value.findIndex(
|
|
|
- (row) => row.id === pendingContractId,
|
|
|
- );
|
|
|
+ const index = rows.value.findIndex((row) => row.id === pendingContractId);
|
|
|
|
|
|
if (index !== -1) {
|
|
|
- rows.value[index] = updated;
|
|
|
+ rows.value[index] = {
|
|
|
+ ...rows.value[index],
|
|
|
+ ...updated,
|
|
|
+ };
|
|
|
}
|
|
|
} catch (error) {
|
|
|
console.error(error);
|
|
|
|
|
|
$q.notify({
|
|
|
- message: "Erro ao anexar arquivo.",
|
|
|
+ message: "Erro ao anexar o contrato assinado.",
|
|
|
type: "negative",
|
|
|
});
|
|
|
} finally {
|
|
|
@@ -360,4 +401,4 @@ const triggerFileInput = (row) => {
|
|
|
};
|
|
|
|
|
|
onMounted(loadContracts);
|
|
|
-</script>
|
|
|
+</script>
|