AddEditGroupDialog.vue 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <template>
  2. <q-dialog ref="dialogRef" @hide="onDialogHide">
  3. <div style="width: 100%; max-width: 520px">
  4. <q-card class="overflow-hidden" style="width: 100%">
  5. <DefaultDialogHeader
  6. :title="isEdit ? 'Editar Grupo' : 'Adicionar Novo Grupo'"
  7. @close="onDialogCancel"
  8. />
  9. <DefaultForm ref="formRef" @submit="onOKClick">
  10. <q-scroll-area class="form-dialog-scroll-area">
  11. <q-card-section class="q-pt-sm column q-gutter-y-sm">
  12. <DefaultInput
  13. v-model="form.name"
  14. label="Nome do Grupo"
  15. outlined
  16. :rules="[inputRules.required]"
  17. />
  18. <q-select
  19. v-model="form.unit_ids"
  20. :options="unitOptions"
  21. label="Unidades"
  22. label-color="secondary"
  23. outlined
  24. multiple
  25. use-chips
  26. emit-value
  27. map-options
  28. hide-dropdown-icon
  29. :loading="loadingUnits"
  30. >
  31. <template #append>
  32. <q-icon name="mdi-chevron-down" color="secondary" />
  33. </template>
  34. </q-select>
  35. </q-card-section>
  36. </q-scroll-area>
  37. <q-card-actions align="right" class="q-px-md q-pb-md">
  38. <q-btn
  39. label="Cancelar"
  40. outline
  41. color="primary-2"
  42. @click="onDialogCancel"
  43. />
  44. <q-btn
  45. label="Salvar"
  46. color="primary-2"
  47. type="submit"
  48. :loading="loading"
  49. />
  50. </q-card-actions>
  51. </DefaultForm>
  52. </q-card>
  53. </div>
  54. </q-dialog>
  55. </template>
  56. <script setup>
  57. import { ref, computed, onMounted } from "vue";
  58. import { useDialogPluginComponent } from "quasar";
  59. import { useInputRules } from "src/composables/useInputRules";
  60. import { getUnitsForSelect } from "src/api/unit";
  61. import { createGroup, updateGroup } from "src/api/group";
  62. import { formatUnitName } from "src/helpers/utils";
  63. import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
  64. import DefaultInput from "src/components/defaults/DefaultInput.vue";
  65. const props = defineProps({
  66. group: {
  67. type: Object,
  68. default: null,
  69. },
  70. });
  71. defineEmits([...useDialogPluginComponent.emits]);
  72. const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
  73. useDialogPluginComponent();
  74. const { inputRules } = useInputRules();
  75. const formRef = ref(null);
  76. const loading = ref(false);
  77. const loadingUnits = ref(true);
  78. const unitOptions = ref([]);
  79. const isEdit = computed(() => !!props.group);
  80. const form = ref({
  81. name: props.group?.name ?? "",
  82. unit_ids: props.group?.unit_ids ?? [],
  83. });
  84. onMounted(async () => {
  85. try {
  86. const units = await getUnitsForSelect();
  87. unitOptions.value = units.map((u) => ({
  88. label: formatUnitName(u),
  89. value: u.id,
  90. }));
  91. } catch (error) {
  92. console.error("Failed to load units:", error);
  93. } finally {
  94. loadingUnits.value = false;
  95. }
  96. });
  97. const onOKClick = async () => {
  98. loading.value = true;
  99. try {
  100. const payload = {
  101. name: form.value.name,
  102. unit_ids: form.value.unit_ids,
  103. };
  104. const result = isEdit.value
  105. ? await updateGroup(props.group.id, payload)
  106. : await createGroup(payload);
  107. onDialogOK(result);
  108. } finally {
  109. loading.value = false;
  110. }
  111. };
  112. </script>