AddEditCityDialog.vue 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. <template>
  2. <q-dialog ref="dialogRef" @hide="onDialogHide">
  3. <q-card class="q-dialog-plugin overflow-hidden" style="width: 800px">
  4. <DefaultDialogHeader :title="title" @close="onDialogCancel" />
  5. <q-form ref="formRef" @submit="onOKClick">
  6. <q-card-section class="row q-col-gutter-sm">
  7. <q-input
  8. v-model="form.name"
  9. :label="$t('common.terms.name')"
  10. :rules="[inputRules.required]"
  11. :error="!!serverErrors?.name"
  12. :error-message="serverErrors?.name"
  13. class="col-md-6 col-12"
  14. @update:model-value="serverErrors.name = null"
  15. />
  16. <CountrySelect
  17. ref="countrySelectRef"
  18. v-model="selectedCountry"
  19. :label="$t('ui.navigation.country')"
  20. :rules="[inputRules.required]"
  21. :error="!!serverErrors?.country_id"
  22. :error-message="serverErrors?.country_id"
  23. :initial-id="city ? city.country_id : null"
  24. class="col-md-6 col-12"
  25. @update:model-value="serverErrors.country_id = null"
  26. />
  27. <StateSelect
  28. v-model="selectedState"
  29. :country="selectedCountry"
  30. :initial-id="form.state_id"
  31. :label="$t('ui.navigation.state')"
  32. :rules="[inputRules.required]"
  33. :error="!!serverErrors?.state_id"
  34. :error-message="serverErrors?.state_id"
  35. class="col-md-6 col-12"
  36. @selected-country-id="countrySelectRef.selectCountryById($event)"
  37. @update:model-value="serverErrors.state_id = null"
  38. />
  39. <q-select
  40. v-model="selectedStatus"
  41. :label="$t('common.terms.status')"
  42. :options="statusOptions"
  43. :rules="[inputRules.required]"
  44. :error="!!serverErrors?.status"
  45. :error-message="serverErrors?.status"
  46. class="col-md-6 col-12"
  47. @update:model-value="serverErrors.status = null"
  48. />
  49. </q-card-section>
  50. <q-card-actions align="center">
  51. <q-btn color="primary" label="Cancel" @click="onDialogCancel" />
  52. <q-space />
  53. <q-btn
  54. color="primary"
  55. label="OK"
  56. :type="'submit'"
  57. :loading="loading"
  58. :disable="!hasUpdatedFields"
  59. />
  60. </q-card-actions>
  61. </q-form>
  62. </q-card>
  63. </q-dialog>
  64. </template>
  65. <script setup>
  66. import { ref, useTemplateRef, onMounted, watch } from "vue";
  67. import { useInputRules } from "src/composables/useInputRules";
  68. import { useDialogPluginComponent } from "quasar";
  69. import { useI18n } from "vue-i18n";
  70. import { createCity, updateCity } from "src/api/city";
  71. import { useFormUpdateTracker } from "src/composables/useFormUpdateTracker";
  72. import { useSubmitHandler } from "src/composables/useSubmitHandler";
  73. import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
  74. import CountrySelect from "src/components/regions/CountrySelect.vue";
  75. import StateSelect from "src/components/regions/StateSelect.vue";
  76. defineEmits([
  77. // REQUIRED; need to specify some events that your
  78. // component will emit through useDialogPluginComponent()
  79. ...useDialogPluginComponent.emits,
  80. ]);
  81. const { city, title } = defineProps({
  82. city: {
  83. type: Object,
  84. default: null,
  85. },
  86. title: {
  87. type: Function,
  88. default: () => useI18n().t("common.terms.title"),
  89. },
  90. });
  91. const { t } = useI18n();
  92. const { inputRules } = useInputRules();
  93. const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
  94. useDialogPluginComponent();
  95. const formRef = useTemplateRef("formRef");
  96. const countrySelectRef = useTemplateRef("countrySelectRef");
  97. const { form, getUpdatedFields, hasUpdatedFields } = useFormUpdateTracker({
  98. name: city ? city?.name : "",
  99. country_id: city ? city?.country_id : null,
  100. state_id: city ? city?.state_id : null,
  101. status: city ? city?.status : "ACTIVE",
  102. });
  103. const {
  104. loading,
  105. serverErrors,
  106. execute: submitForm,
  107. } = useSubmitHandler({
  108. onSuccess: () => onDialogOK(true),
  109. formRef: formRef,
  110. });
  111. const selectedCountry = ref(null);
  112. const selectedState = ref(null);
  113. const selectedStatus = ref({
  114. label: t("common.status.active"),
  115. value: "ACTIVE",
  116. });
  117. const statusOptions = ref([
  118. { label: t("common.status.active"), value: "ACTIVE" },
  119. { label: t("common.status.inactive"), value: "INACTIVE" },
  120. ]);
  121. const onOKClick = async () => {
  122. if (city) {
  123. await submitForm(() => updateCity(getUpdatedFields.value, city.id));
  124. } else {
  125. await submitForm(() => createCity({ ...form }));
  126. }
  127. };
  128. watch(selectedStatus, () => {
  129. form.status = selectedStatus.value?.value;
  130. });
  131. watch(selectedCountry, () => {
  132. form.country_id = selectedCountry.value?.value;
  133. });
  134. watch(selectedState, () => {
  135. form.state_id = selectedState.value?.value;
  136. });
  137. onMounted(async () => {
  138. if (city) {
  139. selectedStatus.value = statusOptions.value.find(
  140. (status) => status.value === city.status,
  141. );
  142. }
  143. });
  144. </script>