diff --git a/package-lock.json b/package-lock.json index 2e96d2ccf..9db93eff3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,14 @@ { "name": "salix-front", - "version": "23.36.01", + "version": "23.52.01", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "salix-front", - "version": "0.0.1", + "version": "23.52.01", "dependencies": { - "@quasar/cli": "^2.2.1", + "@quasar/cli": "^2.3.0", "@quasar/extras": "^1.16.4", "axios": "^1.4.0", "chromium": "^3.0.3", @@ -946,9 +946,9 @@ } }, "node_modules/@quasar/cli": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@quasar/cli/-/cli-2.2.1.tgz", - "integrity": "sha512-PMwJ76IeeNRRBw+08hUMjhqGC6JKJ/t1zIb+IOiyR5D4rkBR26Ha/Z46OD3KfwUprq4Q8s4ieB1+d3VY8FhPKg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@quasar/cli/-/cli-2.3.0.tgz", + "integrity": "sha512-DNFDemicj3jXe5+Ib+5w9Bwj1U3yoHQkqn0bU/qysIl/p0MmGA1yqOfUF0V4fw/5or1dfCvStIA/oZxUcC+2pQ==", "dependencies": { "@quasar/ssl-certificate": "^1.0.0", "ci-info": "^3.8.0", diff --git a/src/boot/vnDate.js b/src/boot/vnDate.js index c78886b57..33d5ac27f 100644 --- a/src/boot/vnDate.js +++ b/src/boot/vnDate.js @@ -15,4 +15,14 @@ export default boot(() => { Date.vnNow = () => { return new Date(Date.vnUTC()).getTime(); }; + + Date.vnFirstDayOfMonth = () => { + const date = new Date(Date.vnUTC()); + return new Date(date.getFullYear(), date.getMonth(), 1); + }; + + Date.vnLastDayOfMonth = () => { + const date = new Date(Date.vnUTC()); + return new Date(date.getFullYear(), date.getMonth() + 1, 0); + }; }); diff --git a/src/components/FormModel.vue b/src/components/FormModel.vue index e8a9e4c17..453b3ffe1 100644 --- a/src/components/FormModel.vue +++ b/src/components/FormModel.vue @@ -6,6 +6,7 @@ import { useQuasar } from 'quasar'; import { useState } from 'src/composables/useState'; import { useStateStore } from 'stores/useStateStore'; import { useValidator } from 'src/composables/useValidator'; +import useNotify from 'src/composables/useNotify.js'; import SkeletonForm from 'components/ui/SkeletonForm.vue'; const quasar = useQuasar(); @@ -13,6 +14,7 @@ const state = useState(); const stateStore = useStateStore(); const { t } = useI18n(); const { validate } = useValidator(); +const { notify } = useNotify(); const $props = defineProps({ url: { @@ -31,10 +33,28 @@ const $props = defineProps({ type: String, default: null, }, + urlCreate: { + type: String, + default: null, + }, defaultActions: { type: Boolean, default: true, }, + autoLoad: { + type: Boolean, + default: false, + }, + formInitialData: { + type: Object, + default: () => {}, + }, + observeFormChanges: { + type: Boolean, + default: true, + description: + 'Esto se usa principalmente para permitir guardar sin hacer cambios (Útil para la feature de clonar ya que en este caso queremos poder guardar de primeras)', + }, }); const emit = defineEmits(['onFetch']); @@ -43,44 +63,73 @@ defineExpose({ save, }); -onMounted(async () => await fetch()); +onMounted(async () => { + // Podemos enviarle al form la estructura de data inicial sin necesidad de fetchearla + if ($props.formInitialData && !$props.autoLoad) { + state.set($props.model, $props.formInitialData); + } else { + await fetch(); + } + + // Disparamos el watcher del form después de que se haya cargado la data inicial, si así se desea + if ($props.observeFormChanges) { + startFormWatcher(); + } +}); onUnmounted(() => { state.unset($props.model); }); const isLoading = ref(false); -const hasChanges = ref(false); -const originalData = ref(); +// Si elegimos observar los cambios del form significa que inicialmente las actions estaran deshabilitadas +const hasChanges = ref(!$props.observeFormChanges); +const originalData = ref({...$props.formInitialData}); const formData = computed(() => state.get($props.model)); const formUrl = computed(() => $props.url); +const startFormWatcher = () => { + watch( + () => formData.value, + (val) => { + if (val) hasChanges.value = true; + }, + { deep: true } + ); +}; + function tMobile(...args) { if (!quasar.platform.is.mobile) return t(...args); } async function fetch() { const { data } = await axios.get($props.url, { - params: { filter: $props.filter }, + params: { filter: JSON.stringify($props.filter) }, }); state.set($props.model, data); originalData.value = data && JSON.parse(JSON.stringify(data)); - watch(formData.value, () => (hasChanges.value = true)); - emit('onFetch', state.get($props.model)); } async function save() { if (!hasChanges.value) { - return quasar.notify({ - type: 'negative', - message: t('globals.noChanges'), - }); + notify('globals.noChanges', 'negative'); + return; } isLoading.value = true; - await axios.patch($props.urlUpdate || $props.url, formData.value); + + try { + if ($props.urlCreate) { + await axios.post($props.urlCreate, formData.value); + notify('globals.dataCreated', 'positive'); + } else { + await axios.patch($props.urlUpdate || $props.url, formData.value); + } + } catch (err) { + notify('errors.create', 'negative'); + } originalData.value = JSON.parse(JSON.stringify(formData.value)); hasChanges.value = false; @@ -91,11 +140,12 @@ function reset() { state.set($props.model, originalData.value); originalData.value = JSON.parse(JSON.stringify(originalData.value)); - watch(formData.value, () => (hasChanges.value = true)); - emit('onFetch', state.get($props.model)); - hasChanges.value = false; + if ($props.observeFormChanges) { + hasChanges.value = false; + } } + // eslint-disable-next-line vue/no-dupe-keys function filter(value, update, filterOptions) { update( @@ -118,7 +168,7 @@ watch(formUrl, async () => { });