Просмотр исходного кода

feat: adiciona modulo de grupos

ebagabee 3 недель назад
Родитель
Сommit
acf1021736

+ 26 - 0
src/api/group.js

@@ -0,0 +1,26 @@
+import api from "src/api";
+
+export const getGroups = async () => {
+  const { data } = await api.get("/group");
+  return data.payload;
+};
+
+export const getGroup = async (id) => {
+  const { data } = await api.get(`/group/${id}`);
+  return data.payload;
+};
+
+export const createGroup = async (payload) => {
+  const { data } = await api.post("/group", payload);
+  return data.payload;
+};
+
+export const updateGroup = async (id, payload) => {
+  const { data } = await api.put(`/group/${id}`, payload);
+  return data.payload;
+};
+
+export const deleteGroup = async (id) => {
+  const { data } = await api.delete(`/group/${id}`);
+  return data;
+};

+ 64 - 6
src/pages/cadastros/components/AddEditGroupDialog.vue

@@ -1,17 +1,38 @@
 <template>
   <q-dialog ref="dialogRef" @hide="onDialogHide">
-    <div style="width: 100%; max-width: 480px">
+    <div style="width: 100%; max-width: 520px">
       <q-card class="overflow-hidden" style="width: 100%">
-        <DefaultDialogHeader title="Adicionar Novo Grupo" @close="onDialogCancel" />
+        <DefaultDialogHeader
+          :title="isEdit ? 'Editar Grupo' : 'Adicionar Novo Grupo'"
+          @close="onDialogCancel"
+        />
 
         <q-form ref="formRef" @submit="onOKClick">
-          <q-card-section class="q-pt-sm">
+          <q-card-section class="q-pt-sm column q-gutter-y-sm">
             <DefaultInput
               v-model="form.name"
               label="Nome do Grupo"
               outlined
               :rules="[inputRules.required]"
             />
+
+            <q-select
+              v-model="form.unit_ids"
+              :options="unitOptions"
+              label="Unidades"
+              label-color="secondary"
+              outlined
+              multiple
+              use-chips
+              emit-value
+              map-options
+              hide-dropdown-icon
+              :loading="loadingUnits"
+            >
+              <template #append>
+                <q-icon name="mdi-chevron-down" color="secondary" />
+              </template>
+            </q-select>
           </q-card-section>
 
           <q-card-actions align="right" class="q-px-md q-pb-md">
@@ -35,12 +56,21 @@
 </template>
 
 <script setup>
-import { ref } from "vue";
+import { ref, computed, onMounted } from "vue";
 import { useDialogPluginComponent } from "quasar";
 import { useInputRules } from "src/composables/useInputRules";
+import { getUnitsForSelect } from "src/api/unit";
+import { createGroup, updateGroup } from "src/api/group";
 import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
 import DefaultInput from "src/components/defaults/DefaultInput.vue";
 
+const props = defineProps({
+  group: {
+    type: Object,
+    default: null,
+  },
+});
+
 defineEmits([...useDialogPluginComponent.emits]);
 
 const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
@@ -50,15 +80,43 @@ const { inputRules } = useInputRules();
 
 const formRef = ref(null);
 const loading = ref(false);
+const loadingUnits = ref(true);
+const unitOptions = ref([]);
+
+const isEdit = computed(() => !!props.group);
 
 const form = ref({
-  name: "",
+  name: props.group?.name ?? "",
+  unit_ids: props.group?.unit_ids ?? [],
+});
+
+onMounted(async () => {
+  try {
+    const units = await getUnitsForSelect();
+    unitOptions.value = units.map((u) => ({
+      label: u.fantasy_name,
+      value: u.id,
+    }));
+  } catch (error) {
+    console.error("Failed to load units:", error);
+  } finally {
+    loadingUnits.value = false;
+  }
 });
 
 const onOKClick = async () => {
   loading.value = true;
   try {
-    onDialogOK(form.value);
+    const payload = {
+      name: form.value.name,
+      unit_ids: form.value.unit_ids,
+    };
+
+    const result = isEdit.value
+      ? await updateGroup(props.group.id, payload)
+      : await createGroup(payload);
+
+    onDialogOK(result);
   } finally {
     loading.value = false;
   }

+ 36 - 8
src/pages/cadastros/tabs/GruposTab.vue

@@ -6,6 +6,7 @@
       :columns
       description="Grupos"
       :female="false"
+      :loading="loading"
       no-api-call
       add-item
       @on-add-item="handleAdd"
@@ -27,14 +28,14 @@
               icon="mdi-pencil-outline"
               style="width: 36px"
               class="q-mr-sm"
-              @click.prevent.stop="onEdit(row)"
+              @click.prevent.stop="handleEdit(row)"
             />
             <q-btn
               outline
               icon="mdi-trash-can-outline"
               style="width: 36px"
               class="q-mr-sm"
-              @click.prevent.stop="onDelete(row)"
+              @click.prevent.stop="handleDelete(row)"
             />
           </q-item-section>
         </q-td>
@@ -44,14 +45,16 @@
 </template>
 
 <script setup>
-import { ref } from "vue";
+import { ref, onMounted } from "vue";
 import { useQuasar } from "quasar";
 import DefaultTable from "src/components/defaults/DefaultTable.vue";
 import AddEditGroupDialog from "../components/AddEditGroupDialog.vue";
+import { getGroups, deleteGroup } from "src/api/group";
 
 const $q = useQuasar();
 
 const rows = ref([]);
+const loading = ref(false);
 
 const columns = ref([
   { name: "name", label: "Nome", field: "name", align: "left" },
@@ -60,15 +63,40 @@ const columns = ref([
   { name: "actions", label: "Ações", field: null, align: "center" },
 ]);
 
+async function fetchGroups() {
+  loading.value = true;
+  try {
+    rows.value = await getGroups();
+  } catch (error) {
+    console.error("Failed to load groups:", error);
+  } finally {
+    loading.value = false;
+  }
+}
+
 function handleAdd() {
-  $q.dialog({ component: AddEditGroupDialog });
+  $q.dialog({ component: AddEditGroupDialog }).onOk(() => fetchGroups());
 }
 
-function onEdit(row) {
-  console.log("edit", row);
+function handleEdit(row) {
+  $q.dialog({ component: AddEditGroupDialog, componentProps: { group: row } }).onOk(() => fetchGroups());
 }
 
-function onDelete(row) {
-  console.log("delete", row);
+function handleDelete(row) {
+  $q.dialog({
+    title: "Confirmar exclusão",
+    message: `Deseja excluir o grupo "${row.name}"?`,
+    ok: { color: "negative", label: "Excluir" },
+    cancel: { color: "primary", outline: true, label: "Cancelar" },
+  }).onOk(async () => {
+    try {
+      await deleteGroup(row.id);
+      await fetchGroups();
+    } catch (error) {
+      console.error("Failed to delete group:", error);
+    }
+  });
 }
+
+onMounted(fetchGroups);
 </script>