AddEditPermissionGroupDialog.vue 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. <template>
  2. <q-dialog ref="dialogRef" @hide="onDialogHide">
  3. <q-card style="min-width: 440px">
  4. <DefaultDialogHeader :title="dialogTitle" @close="onDialogCancel" />
  5. <DefaultForm ref="formRef" @submit="onSave">
  6. <q-card-section class="column q-gutter-md">
  7. <DefaultInput
  8. v-model="form.label"
  9. label="Nome"
  10. outlined
  11. autofocus
  12. :rules="[inputRules.required]"
  13. @update:model-value="onLabelChange"
  14. />
  15. <DefaultInput
  16. v-model="form.slug"
  17. label="Código"
  18. outlined
  19. hint="Identificador único do grupo. Ex.: FINANCEIRO"
  20. :rules="[inputRules.required, slugRule]"
  21. @update:model-value="onSlugTouched"
  22. />
  23. </q-card-section>
  24. <q-card-actions align="right">
  25. <q-btn
  26. label="Cancelar"
  27. color="primary"
  28. outline
  29. @click="onDialogCancel"
  30. />
  31. <q-btn
  32. label="Salvar"
  33. color="primary"
  34. type="submit"
  35. :loading="loading"
  36. />
  37. </q-card-actions>
  38. </DefaultForm>
  39. </q-card>
  40. </q-dialog>
  41. </template>
  42. <script setup>
  43. import { computed, ref, useTemplateRef } from "vue";
  44. import { useDialogPluginComponent } from "quasar";
  45. import { useInputRules } from "src/composables/useInputRules";
  46. import { useSubmitHandler } from "src/composables/useSubmitHandler";
  47. import { createUserType, updateUserType } from "src/api/user_type";
  48. import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
  49. import DefaultInput from "src/components/defaults/DefaultInput.vue";
  50. const { group } = defineProps({
  51. group: {
  52. type: Object,
  53. default: null,
  54. },
  55. });
  56. defineEmits([...useDialogPluginComponent.emits]);
  57. const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
  58. useDialogPluginComponent();
  59. const { inputRules } = useInputRules();
  60. const formRef = useTemplateRef("formRef");
  61. const isEdit = computed(() => !!group);
  62. const dialogTitle = computed(() =>
  63. isEdit.value ? "Editar Grupo de Permissões" : "Novo Grupo de Permissões",
  64. );
  65. const form = ref({
  66. label: group?.label ?? "",
  67. slug: group?.slug ?? "",
  68. });
  69. // Ao editar, o código já existe e não deve ser re-derivado do nome.
  70. const slugTouched = ref(isEdit.value);
  71. const toSlug = (value) =>
  72. (value ?? "")
  73. .normalize("NFD")
  74. .replace(/\p{Diacritic}/gu, "")
  75. .toUpperCase()
  76. .replace(/[^A-Z0-9]+/g, "_")
  77. .replace(/^_+|_+$/g, "");
  78. const slugRule = (value) =>
  79. /^[A-Z0-9_]+$/.test(value ?? "") ||
  80. "Use apenas letras maiúsculas, números e underline.";
  81. const onLabelChange = (value) => {
  82. if (!slugTouched.value) {
  83. form.value.slug = toSlug(value);
  84. }
  85. };
  86. const onSlugTouched = (value) => {
  87. slugTouched.value = true;
  88. form.value.slug = toSlug(value);
  89. };
  90. const { loading, execute } = useSubmitHandler({
  91. formRef,
  92. onSuccess: () => onDialogOK(),
  93. });
  94. const onSave = async () => {
  95. const payload = { label: form.value.label, slug: form.value.slug };
  96. await execute(() =>
  97. isEdit.value ? updateUserType(group.id, payload) : createUserType(payload),
  98. );
  99. };
  100. </script>