Form.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179
  1. <template>
  2. <main>
  3. <v-form
  4. ref="form"
  5. v-model="properties.valid"
  6. lazy-validation
  7. :readonly="readOnly"
  8. >
  9. <v-container fluid class="container btnActions">
  10. <v-row>
  11. <v-col cols="12" sm="12">
  12. <slot name="form.button"></slot>
  13. <v-btn v-if="!readOnly" class="mr-4 ot_green ot_white--text" @click="submit">
  14. {{$t('save')}}
  15. </v-btn>
  16. </v-col>
  17. </v-row>
  18. </v-container>
  19. <slot name="form.input" v-bind="{entry,updateRepository}"></slot>
  20. <v-container fluid class="container btnActions">
  21. <v-row>
  22. <v-col cols="12" sm="12">
  23. <slot name="form.button"></slot>
  24. <v-btn v-if="!readOnly" class="mr-4 ot_green ot_white--text" @click="submit">
  25. {{$t('save')}}
  26. </v-btn>
  27. </v-col>
  28. </v-row>
  29. </v-container>
  30. </v-form>
  31. <lazy-LayoutDialog
  32. :show="showDialog"
  33. >
  34. <template v-slot:dialogText>
  35. <v-card-title class="text-h5 grey lighten-2">
  36. {{$t('attention')}}
  37. </v-card-title>
  38. <v-card-text>
  39. <br>
  40. <p>{{$t('quit_without_saving_warning')}}</p>
  41. </v-card-text>
  42. </template>
  43. <template v-slot:dialogBtn>
  44. <v-btn class="mr-4 submitBtn ot_green ot_white--text" @click="closeDialog">
  45. {{$t('back_to_form')}}
  46. </v-btn>
  47. <v-btn class="mr-4 submitBtn ot_green ot_white--text" @click="saveAndQuit">
  48. {{$t('save_and_quit')}}
  49. </v-btn>
  50. <v-btn class="mr-4 submitBtn ot_danger ot_white--text" @click="goEvenUnsavedData">
  51. {{$t('quit_form')}}
  52. </v-btn>
  53. </template>
  54. </lazy-LayoutDialog>
  55. </main>
  56. </template>
  57. <script lang="ts">
  58. import {computed, defineComponent, onBeforeMount, onBeforeUnmount, onUnmounted, reactive, toRefs, useContext, watch, ref} from '@nuxtjs/composition-api'
  59. import {repositoryHelper} from "~/services/store/repository";
  60. import {queryHelper} from "~/services/store/query";
  61. import {Query} from "@vuex-orm/core";
  62. import {QUERY_TYPE, TYPE_ALERT} from "~/types/enums";
  63. import {alert} from "~/types/interfaces";
  64. import {$useDirtyForm} from "~/use/form/useDirtyForm";
  65. export default defineComponent({
  66. props: {
  67. model: {
  68. type: Function,
  69. required: true
  70. },
  71. id: {
  72. type: Number,
  73. required: true
  74. },
  75. query: {
  76. type: Object as () => Query,
  77. required: true
  78. },
  79. },
  80. setup: function (props) {
  81. const {$dataPersister, store, app: {router, i18n}} = useContext()
  82. const {markFormAsDirty, markFormAsNotDirty} = $useDirtyForm(store)
  83. const {id, query} = toRefs(props)
  84. const properties = reactive({
  85. valid: false,
  86. saveOk: false,
  87. saveKo: false
  88. })
  89. const readOnly = computed(() => {
  90. return false
  91. })
  92. const entry = computed(() => {
  93. return queryHelper.getFlattenEntry(query.value, id.value)
  94. })
  95. const updateRepository = (newValue: string, field: string) => {
  96. markFormAsDirty()
  97. repositoryHelper.updateStoreFromField(props.model, entry.value, newValue, field)
  98. }
  99. const submit = async () => {
  100. try {
  101. markFormAsNotDirty()
  102. await $dataPersister.invoke({
  103. type: QUERY_TYPE.MODEL,
  104. model: props.model,
  105. id: id.value
  106. })
  107. const alert:alert = {
  108. type: TYPE_ALERT.SUCCESS,
  109. message: i18n.t('saveSuccess') as string
  110. }
  111. store.commit('page/setAlert', alert)
  112. } catch (error) {
  113. const alert:alert = {
  114. type: TYPE_ALERT.ALERT,
  115. message: error.message
  116. }
  117. store.commit('page/setAlert', alert)
  118. }
  119. }
  120. const showDialog = computed(() => {
  121. return store.state.form.showConfirmToLeave
  122. })
  123. const closeDialog = () => {
  124. store.commit('form/setShowConfirmToLeave', false)
  125. }
  126. const saveAndQuit = async () => {
  127. await submit()
  128. goEvenUnsavedData()
  129. }
  130. const goEvenUnsavedData = () => {
  131. markFormAsNotDirty()
  132. store.commit('form/setShowConfirmToLeave', false)
  133. const entryCopy = query.value.first()
  134. if (entryCopy && entryCopy.$getAttributes()['originalState']) {
  135. repositoryHelper.persist(props.model, entryCopy.$getAttributes()['originalState'])
  136. }
  137. if (router) {
  138. router.push(store.state.form.goAfterLeave)
  139. }
  140. }
  141. return {
  142. submit,
  143. updateRepository,
  144. properties,
  145. readOnly,
  146. showDialog,
  147. entry,
  148. goEvenUnsavedData,
  149. closeDialog,
  150. saveAndQuit
  151. }
  152. }
  153. })
  154. </script>
  155. <style scoped>
  156. .btnActions {
  157. text-align: right;
  158. }
  159. </style>