Переглянути джерело

feat: adiciona a funcionalidade de editar e excluir

ebagabee 1 місяць тому
батько
коміт
4f41cb7125

+ 19 - 1
src/components/charts/FeriadosCard.vue

@@ -24,7 +24,7 @@
 
     <q-list v-else class="q-mt-md" dense>
       <template v-for="(holiday, index) in currentMonthHolidays" :key="holiday.id">
-        <q-item class="q-px-none person-item">
+        <q-item class="q-px-none person-item cursor-pointer" clickable @click="openEdit(holiday)">
           <q-item-section avatar style="min-width: 36px">
             <div class="day-badge">{{ holiday.day }}</div>
           </q-item-section>
@@ -32,6 +32,9 @@
             <q-item-label class="text-body2">{{ holiday.description }}</q-item-label>
             <q-item-label caption>{{ typeLabel(holiday.type) }}</q-item-label>
           </q-item-section>
+          <q-item-section side>
+            <q-icon name="mdi-pencil-outline" color="grey-5" size="xs" />
+          </q-item-section>
         </q-item>
         <q-separator v-if="index < currentMonthHolidays.length - 1" />
       </template>
@@ -43,6 +46,7 @@
 import { ref, computed, onMounted } from "vue";
 import { useQuasar } from "quasar";
 import FeriadosDialog from "src/pages/dashboard/components/FeriadosDialog.vue";
+import FeriadosEditDialog from "src/pages/dashboard/components/FeriadosEditDialog.vue";
 import { getBaseHolidays } from "src/api/holiday";
 
 const $q = useQuasar();
@@ -84,6 +88,20 @@ function openDialog() {
     holidays.value = updated;
   });
 }
+
+function openEdit(holiday) {
+  $q.dialog({
+    component: FeriadosEditDialog,
+    componentProps: { holiday },
+  }).onOk(({ action, holiday: updated, id }) => {
+    if (action === "update") {
+      const idx = holidays.value.findIndex((h) => h.id === updated.id);
+      if (idx !== -1) holidays.value[idx] = updated;
+    } else if (action === "delete") {
+      holidays.value = holidays.value.filter((h) => h.id !== id);
+    }
+  });
+}
 </script>
 
 <style scoped>

+ 18 - 23
src/pages/dashboard/components/FeriadosDialog.vue

@@ -86,7 +86,9 @@
               <q-item
                 v-for="holiday in monthHolidays"
                 :key="holiday.id"
-                class="q-pa-sm"
+                class="q-pa-sm cursor-pointer"
+                clickable
+                @click="openEdit(holiday)"
               >
                 <q-item-section avatar>
                   <q-avatar
@@ -103,16 +105,7 @@
                   <q-item-label caption>{{ typeLabel(holiday.type) }}</q-item-label>
                 </q-item-section>
                 <q-item-section side>
-                  <q-btn
-                    flat
-                    round
-                    dense
-                    icon="mdi-trash-can-outline"
-                    color="grey-5"
-                    size="sm"
-                    :loading="deletingId === holiday.id"
-                    @click="removeHoliday(holiday)"
-                  />
+                  <q-icon name="mdi-pencil-outline" color="grey-5" size="xs" />
                 </q-item-section>
               </q-item>
             </q-list>
@@ -184,7 +177,8 @@ import { useDialogPluginComponent, useQuasar } from "quasar";
 import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
 import DefaultInput from "src/components/defaults/DefaultInput.vue";
 import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
-import { createBaseHoliday, deleteBaseHoliday } from "src/api/holiday";
+import { createBaseHoliday } from "src/api/holiday";
+import FeriadosEditDialog from "src/pages/dashboard/components/FeriadosEditDialog.vue";
 
 defineEmits([...useDialogPluginComponent.emits]);
 
@@ -200,7 +194,6 @@ const selectedDay = ref(null);
 const newDescription = ref("");
 const newType = ref("feriado");
 const saving = ref(false);
-const deletingId = ref(null);
 
 const props = defineProps({
   initialHolidays: {
@@ -334,16 +327,18 @@ async function saveNewRecord() {
   }
 }
 
-async function removeHoliday(holiday) {
-  deletingId.value = holiday.id;
-  try {
-    await deleteBaseHoliday(holiday.id);
-    holidays.value = holidays.value.filter((h) => h.id !== holiday.id);
-  } catch {
-    $q.notify({ type: "negative", message: "Erro ao remover feriado." });
-  } finally {
-    deletingId.value = null;
-  }
+function openEdit(holiday) {
+  $q.dialog({
+    component: FeriadosEditDialog,
+    componentProps: { holiday },
+  }).onOk(({ action, holiday: updated, id }) => {
+    if (action === "update") {
+      const idx = holidays.value.findIndex((h) => h.id === updated.id);
+      if (idx !== -1) holidays.value[idx] = updated;
+    } else if (action === "delete") {
+      holidays.value = holidays.value.filter((h) => h.id !== id);
+    }
+  });
 }
 
 function onClose() {

+ 145 - 0
src/pages/dashboard/components/FeriadosEditDialog.vue

@@ -0,0 +1,145 @@
+<template>
+  <q-dialog ref="dialogRef" @hide="onDialogHide">
+    <q-card class="q-dialog-plugin feriados-edit-dialog">
+      <DefaultDialogHeader :title="dialogTitle" @close="onDialogCancel" />
+
+      <q-card-section class="column q-gutter-md q-pt-sm">
+        <DefaultInput
+          v-model="description"
+          label="Nome do Evento"
+          placeholder="Ex: Ponto facultativo, Natal..."
+          icon="mdi-pencil-outline"
+          outlined
+          autofocus
+        />
+
+        <DefaultSelect
+          v-model="type"
+          label="Selecione o Tipo."
+          :options="typeOptions"
+          emit-value
+          map-options
+          outlined
+        />
+      </q-card-section>
+
+      <q-separator />
+
+      <q-card-actions align="between">
+        <q-btn
+          outline
+          color="negative"
+          label="EXCLUIR"
+          no-caps
+          :loading="deleting"
+          @click="confirmDelete"
+        />
+        <div class="row q-gutter-sm">
+          <q-btn outline color="primary" label="CANCELAR" no-caps @click="onDialogCancel" />
+          <q-btn
+            unelevated
+            color="primary"
+            label="SALVAR"
+            no-caps
+            :disable="!description.trim()"
+            :loading="saving"
+            @click="save"
+          />
+        </div>
+      </q-card-actions>
+    </q-card>
+  </q-dialog>
+</template>
+
+<script setup>
+import { ref, computed } from "vue";
+import { useDialogPluginComponent, useQuasar } from "quasar";
+import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
+import DefaultInput from "src/components/defaults/DefaultInput.vue";
+import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
+import { updateBaseHoliday, deleteBaseHoliday } from "src/api/holiday";
+
+defineEmits([...useDialogPluginComponent.emits]);
+
+const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } = useDialogPluginComponent();
+const $q = useQuasar();
+
+const props = defineProps({
+  holiday: {
+    type: Object,
+    required: true,
+  },
+});
+
+const description = ref(props.holiday.description);
+const type = ref(props.holiday.type ?? "feriado");
+const saving = ref(false);
+const deleting = ref(false);
+
+const typeOptions = [
+  { label: "Feriado", value: "feriado" },
+  { label: "Ponto Facultativo", value: "facultativo" },
+];
+
+const dialogTitle = computed(() => {
+  const dd = String(props.holiday.day).padStart(2, "0");
+  const mm = String(props.holiday.month).padStart(2, "0");
+  return `${dd}/${mm}/${props.holiday.year}`;
+});
+
+async function save() {
+  const desc = description.value.trim();
+  if (!desc) return;
+
+  const mm = String(props.holiday.month).padStart(2, "0");
+  const dd = String(props.holiday.day).padStart(2, "0");
+
+  saving.value = true;
+  try {
+    const updated = await updateBaseHoliday(props.holiday.id, {
+      description: desc,
+      holiday_date: `${props.holiday.year}-${mm}-${dd}`,
+      type: type.value,
+    });
+
+    onDialogOK({
+      action: "update",
+      holiday: {
+        ...props.holiday,
+        description: updated.description,
+        type: updated.type,
+      },
+    });
+  } catch {
+    $q.notify({ type: "negative", message: "Erro ao salvar feriado." });
+  } finally {
+    saving.value = false;
+  }
+}
+
+function confirmDelete() {
+  $q.dialog({
+    title: "Excluir feriado",
+    message: `Deseja excluir "${props.holiday.description}"?`,
+    cancel: { label: "Cancelar", flat: true, color: "primary" },
+    ok: { label: "Excluir", unelevated: true, color: "negative" },
+  }).onOk(async () => {
+    deleting.value = true;
+    try {
+      await deleteBaseHoliday(props.holiday.id);
+      onDialogOK({ action: "delete", id: props.holiday.id });
+    } catch {
+      $q.notify({ type: "negative", message: "Erro ao excluir feriado." });
+    } finally {
+      deleting.value = false;
+    }
+  });
+}
+</script>
+
+<style scoped>
+.feriados-edit-dialog {
+  width: 420px;
+  max-width: 95vw;
+}
+</style>