Ver código fonte

feat(treasury): refactor dialogs for account and launch management

ebagabee 4 semanas atrás
pai
commit
ecf2e1d3ae

+ 26 - 208
src/pages/financial/TreasuryPage.vue

@@ -101,168 +101,31 @@
         </template>
       </DefaultTable>
     </div>
-
-    <!-- Diálogo conta -->
-    <q-dialog v-model="accountDialog">
-      <q-card class="treasury-dialog-card">
-        <DefaultDialogHeader
-          :title="editingAccount ? 'Editar conta' : 'Nova conta'"
-          @close="accountDialog = false"
-        />
-        <q-form ref="accountFormRef">
-          <q-card-section class="row q-col-gutter-md q-px-lg q-pt-md q-pb-sm">
-            <DefaultInput
-              v-model="accountForm.name"
-              label="Nome (ex.: Banco do Brasil, Caixa Loja)"
-              class="col-12"
-              outlined
-              :rules="[(v) => !!v || 'Informe o nome']"
-            />
-
-            <DefaultInput
-              v-model="accountForm.bank_name"
-              label="Banco"
-              class="col-12 col-sm-6"
-              outlined
-            />
-            <DefaultInput
-              v-model="accountForm.bank_agency"
-              label="Agência"
-              class="col-12 col-sm-6"
-              outlined
-            />
-            <DefaultInput
-              v-model="accountForm.bank_account"
-              label="Conta"
-              class="col-12 col-sm-6"
-              outlined
-            />
-            <DefaultSelect
-              v-model="accountForm.bank_type_account"
-              label="Tipo"
-              :options="accountTypeOptions"
-              class="col-12 col-sm-6"
-              outlined
-              emit-value
-              map-options
-            />
-          </q-card-section>
-          <q-card-actions align="right" class="q-px-lg q-pt-md q-pb-lg q-gutter-sm">
-            <q-btn flat label="Cancelar" color="grey-7" @click="accountDialog = false" />
-            <q-btn color="primary" label="Salvar" :loading="savingAccount" @click="saveAccount" />
-          </q-card-actions>
-        </q-form>
-      </q-card>
-    </q-dialog>
-
-    <!-- Diálogo movimentação -->
-    <q-dialog v-model="launchDialog">
-      <q-card class="treasury-dialog-card treasury-dialog-card--compact">
-        <DefaultDialogHeader title="Nova movimentação" @close="launchDialog = false" />
-        <q-form ref="launchFormRef">
-          <q-card-section class="row q-col-gutter-md q-px-lg q-pt-md q-pb-sm">
-            <DefaultSelect
-              v-model="launchForm.transaction_type"
-              label="Tipo"
-              :options="transactionTypeOptions"
-              class="col-12"
-              outlined
-              emit-value
-              map-options
-            />
-            <DefaultInput
-              v-model="launchForm.description"
-              label="Descrição"
-              class="col-12"
-              outlined
-              :rules="[(v) => !!v || 'Informe a descrição']"
-            />
-            <DefaultCurrencyInput
-              v-model="launchForm.amount"
-              label="Valor"
-              class="col-12 col-sm-6"
-              outlined
-            />
-            <DefaultInputDatePicker
-              v-model="launchForm.launch_date"
-              label="Data"
-              class="col-12 col-sm-6"
-            />
-          </q-card-section>
-          <q-card-actions align="right" class="q-px-lg q-pt-md q-pb-lg q-gutter-sm">
-            <q-btn flat label="Cancelar" color="grey-7" @click="launchDialog = false" />
-            <q-btn color="primary-2" label="Salvar" :loading="savingLaunch" @click="saveLaunch" />
-          </q-card-actions>
-        </q-form>
-      </q-card>
-    </q-dialog>
   </div>
 </template>
 
 <script setup>
-import { computed, onMounted, ref } from "vue";
+import { computed, defineAsyncComponent, onMounted, ref } from "vue";
+import { useQuasar } from "quasar";
 import {
   getTreasuryAccountsMe,
-  createTreasuryAccountMe,
-  updateTreasuryAccountMe,
   getTreasuryLaunchesMe,
-  createTreasuryLaunchMe,
 } from "src/api/treasury";
 
 import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
 import DefaultTable from "src/components/defaults/DefaultTable.vue";
-import DefaultInput from "src/components/defaults/DefaultInput.vue";
-import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
-import DefaultCurrencyInput from "src/components/defaults/DefaultCurrencyInput.vue";
-import DefaultInputDatePicker from "src/components/defaults/DefaultInputDatePicker.vue";
-import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
+
+const AddEditTreasuryAccountDialog = defineAsyncComponent(
+  () => import("src/pages/financial/components/AddEditTreasuryAccountDialog.vue"),
+);
+const AddTreasuryLaunchDialog = defineAsyncComponent(
+  () => import("src/pages/financial/components/AddTreasuryLaunchDialog.vue"),
+);
 
 const accounts = ref([]);
 const launches = ref([]);
 const selectedId = ref(null);
-
-const accountDialog = ref(false);
-const savingAccount = ref(false);
-const editingAccount = ref(false);
-const editingAccountId = ref(null);
-const accountFormRef = ref(null);
-
-const launchDialog = ref(false);
-const savingLaunch = ref(false);
-const launchFormRef = ref(null);
-
-const accountForm = ref(defaultAccountForm());
-const launchForm = ref(defaultLaunchForm());
-
-function defaultAccountForm() {
-  return {
-    name: "",
-    treasury_type: "bank",
-    bank_name: "",
-    bank_agency: "",
-    bank_account: "",
-    bank_type_account: null,
-  };
-}
-
-function defaultLaunchForm() {
-  return {
-    transaction_type: "entrada",
-    description: "",
-    amount: 0,
-    launch_date: new Date().toISOString().slice(0, 10),
-  };
-}
-
-const accountTypeOptions = [
-  { label: "Corrente", value: "corrente" },
-  { label: "Poupança", value: "poupanca" },
-];
-
-const transactionTypeOptions = [
-  { label: "Entrada", value: "entrada" },
-  { label: "Saída", value: "saida" },
-];
+const $q = useQuasar();
 
 const launchColumns = [
   { name: "launch_date", label: "Data", field: "launch_date", align: "left" },
@@ -308,67 +171,30 @@ function selectAccount(acc) {
 }
 
 function openAccountCreate() {
-  editingAccount.value = false;
-  editingAccountId.value = null;
-  accountForm.value = defaultAccountForm();
-  accountDialog.value = true;
+  $q.dialog({
+    component: AddEditTreasuryAccountDialog,
+  }).onOk(loadAccounts);
 }
 
 function openAccountEdit(acc) {
-  editingAccount.value = true;
-  editingAccountId.value = acc.id;
-  accountForm.value = {
-    name: acc.name,
-    treasury_type: "bank",
-    bank_name: acc.bank_name || "",
-    bank_agency: acc.bank_agency || "",
-    bank_account: acc.bank_account || "",
-    bank_type_account: acc.bank_type_account || null,
-  };
-  accountDialog.value = true;
-}
-
-async function saveAccount() {
-  const valid = await accountFormRef.value?.validate();
-  if (!valid) return;
-  savingAccount.value = true;
-  try {
-    if (editingAccount.value) {
-      await updateTreasuryAccountMe(editingAccountId.value, accountForm.value);
-    } else {
-      await createTreasuryAccountMe(accountForm.value);
-    }
-    accountDialog.value = false;
-    await loadAccounts();
-  } catch (e) {
-    console.error(e);
-  } finally {
-    savingAccount.value = false;
-  }
+  $q.dialog({
+    component: AddEditTreasuryAccountDialog,
+    componentProps: {
+      account: acc,
+    },
+  }).onOk(loadAccounts);
 }
 
 function openLaunchCreate() {
-  launchForm.value = defaultLaunchForm();
-  launchDialog.value = true;
-}
-
-async function saveLaunch() {
-  const valid = await launchFormRef.value?.validate();
-  if (!valid) return;
-  savingLaunch.value = true;
-  try {
-    await createTreasuryLaunchMe({
-      account_id: selectedId.value,
-      ...launchForm.value,
-    });
-    launchDialog.value = false;
+  $q.dialog({
+    component: AddTreasuryLaunchDialog,
+    componentProps: {
+      accountId: selectedId.value,
+    },
+  }).onOk(async () => {
     await loadAccounts();
     await loadLaunches();
-  } catch (e) {
-    console.error(e);
-  } finally {
-    savingLaunch.value = false;
-  }
+  });
 }
 
 onMounted(loadAccounts);
@@ -380,12 +206,4 @@ onMounted(loadAccounts);
   border-width: 2px;
 }
 
-.treasury-dialog-card {
-  width: 520px;
-  max-width: calc(100vw - 32px);
-}
-
-.treasury-dialog-card--compact {
-  width: 480px;
-}
 </style>

+ 124 - 0
src/pages/financial/components/AddEditTreasuryAccountDialog.vue

@@ -0,0 +1,124 @@
+<template>
+  <q-dialog ref="dialogRef" @hide="onDialogHide">
+    <q-card class="q-dialog-plugin overflow-hidden treasury-dialog-card">
+      <DefaultDialogHeader :title="title" @close="onDialogCancel" />
+
+      <q-form ref="formRef" @submit="onOKClick">
+        <q-card-section class="row q-col-gutter-md q-px-lg q-pt-md q-pb-sm">
+          <DefaultInput
+            v-model="form.name"
+            label="Nome (ex.: Banco do Brasil, Caixa Loja)"
+            class="col-12"
+            outlined
+            :rules="[(v) => !!v || 'Informe o nome']"
+          />
+
+          <DefaultInput
+            v-model="form.bank_name"
+            label="Banco"
+            class="col-12 col-sm-6"
+            outlined
+          />
+          <DefaultInput
+            v-model="form.bank_agency"
+            label="Agência"
+            class="col-12 col-sm-6"
+            outlined
+          />
+          <DefaultInput
+            v-model="form.bank_account"
+            label="Conta"
+            class="col-12 col-sm-6"
+            outlined
+          />
+          <DefaultSelect
+            v-model="form.bank_type_account"
+            label="Tipo"
+            :options="accountTypeOptions"
+            class="col-12 col-sm-6"
+            outlined
+            emit-value
+            map-options
+          />
+        </q-card-section>
+
+        <q-card-actions align="right" class="q-px-lg q-pt-md q-pb-lg q-gutter-sm">
+          <q-btn flat label="Cancelar" color="grey-7" @click="onDialogCancel" />
+          <q-btn color="primary" label="Salvar" type="submit" :loading="loading" />
+        </q-card-actions>
+      </q-form>
+    </q-card>
+  </q-dialog>
+</template>
+
+<script setup>
+import { computed, ref } from "vue";
+import { useDialogPluginComponent } from "quasar";
+import {
+  createTreasuryAccountMe,
+  updateTreasuryAccountMe,
+} from "src/api/treasury";
+
+import DefaultDialogHeader from "src/components/defaults/DefaultDialogHeader.vue";
+import DefaultInput from "src/components/defaults/DefaultInput.vue";
+import DefaultSelect from "src/components/defaults/DefaultSelect.vue";
+
+defineEmits([...useDialogPluginComponent.emits]);
+
+const props = defineProps({
+  account: {
+    type: Object,
+    default: null,
+  },
+});
+
+const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
+  useDialogPluginComponent();
+
+const formRef = ref(null);
+const loading = ref(false);
+const isEdit = computed(() => !!props.account?.id);
+const title = computed(() => (isEdit.value ? "Editar conta" : "Nova conta"));
+
+const accountTypeOptions = [
+  { label: "Corrente", value: "corrente" },
+  { label: "Poupança", value: "poupanca" },
+];
+
+const form = ref({
+  name: props.account?.name ?? "",
+  treasury_type: "bank",
+  bank_name: props.account?.bank_name ?? "",
+  bank_agency: props.account?.bank_agency ?? "",
+  bank_account: props.account?.bank_account ?? "",
+  bank_type_account: props.account?.bank_type_account ?? null,
+});
+
+async function onOKClick() {
+  const valid = await formRef.value?.validate();
+  if (!valid) return;
+
+  loading.value = true;
+
+  try {
+    if (isEdit.value) {
+      await updateTreasuryAccountMe(props.account.id, form.value);
+    } else {
+      await createTreasuryAccountMe(form.value);
+    }
+
+    onDialogOK(true);
+  } catch (e) {
+    console.error(e);
+  } finally {
+    loading.value = false;
+  }
+}
+</script>
+
+<style scoped>
+.treasury-dialog-card {
+  width: 520px;
+  max-width: calc(100vw - 32px);
+}
+</style>

+ 110 - 0
src/pages/financial/components/AddTreasuryLaunchDialog.vue

@@ -0,0 +1,110 @@
+<template>
+  <q-dialog ref="dialogRef" @hide="onDialogHide">
+    <q-card class="q-dialog-plugin overflow-hidden treasury-dialog-card">
+      <DefaultDialogHeader title="Nova movimentação" @close="onDialogCancel" />
+
+      <q-form ref="formRef" @submit="onOKClick">
+        <q-card-section class="row q-col-gutter-md q-px-lg q-pt-md q-pb-sm">
+          <DefaultSelect
+            v-model="form.transaction_type"
+            label="Tipo"
+            :options="transactionTypeOptions"
+            class="col-12"
+            outlined
+            emit-value
+            map-options
+          />
+          <DefaultInput
+            v-model="form.description"
+            label="Descrição"
+            class="col-12"
+            outlined
+            :rules="[(v) => !!v || 'Informe a descrição']"
+          />
+          <DefaultCurrencyInput
+            v-model="form.amount"
+            label="Valor"
+            class="col-12 col-sm-6"
+            outlined
+          />
+          <DefaultInputDatePicker
+            v-model="form.launch_date"
+            label="Data"
+            class="col-12 col-sm-6"
+          />
+        </q-card-section>
+
+        <q-card-actions align="right" class="q-px-lg q-pt-md q-pb-lg q-gutter-sm">
+          <q-btn flat label="Cancelar" color="grey-7" @click="onDialogCancel" />
+          <q-btn color="primary-2" label="Salvar" type="submit" :loading="loading" />
+        </q-card-actions>
+      </q-form>
+    </q-card>
+  </q-dialog>
+</template>
+
+<script setup>
+import { ref } from "vue";
+import { useDialogPluginComponent } from "quasar";
+import { createTreasuryLaunchMe } from "src/api/treasury";
+
+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 DefaultCurrencyInput from "src/components/defaults/DefaultCurrencyInput.vue";
+import DefaultInputDatePicker from "src/components/defaults/DefaultInputDatePicker.vue";
+
+defineEmits([...useDialogPluginComponent.emits]);
+
+const props = defineProps({
+  accountId: {
+    type: Number,
+    required: true,
+  },
+});
+
+const { dialogRef, onDialogHide, onDialogOK, onDialogCancel } =
+  useDialogPluginComponent();
+
+const formRef = ref(null);
+const loading = ref(false);
+
+const transactionTypeOptions = [
+  { label: "Entrada", value: "entrada" },
+  { label: "Saída", value: "saida" },
+];
+
+const form = ref({
+  transaction_type: "entrada",
+  description: "",
+  amount: 0,
+  launch_date: new Date().toISOString().slice(0, 10),
+});
+
+async function onOKClick() {
+  const valid = await formRef.value?.validate();
+  if (!valid) return;
+
+  loading.value = true;
+
+  try {
+    await createTreasuryLaunchMe({
+      account_id: props.accountId,
+      ...form.value,
+    });
+
+    onDialogOK(true);
+  } catch (e) {
+    console.error(e);
+  } finally {
+    loading.value = false;
+  }
+}
+</script>
+
+<style scoped>
+.treasury-dialog-card {
+  width: 480px;
+  max-width: calc(100vw - 32px);
+}
+</style>