salix-front/src/components/FormModel.vue

119 lines
3.0 KiB
Vue
Raw Normal View History

2022-10-27 12:59:19 +00:00
<script setup>
import { onMounted, onUnmounted, computed, ref, watch } from 'vue';
import { useI18n } from 'vue-i18n';
import { useQuasar } from 'quasar';
import axios from 'axios';
import { useState } from 'src/composables/useState';
2022-10-31 08:34:01 +00:00
import { useValidator } from 'src/composables/useValidator';
2022-10-27 12:59:19 +00:00
import SkeletonForm from 'src/components/SkeletonForm.vue';
const quasar = useQuasar();
const { t } = useI18n();
const state = useState();
2022-10-31 08:34:01 +00:00
const { validate } = useValidator();
2022-10-27 12:59:19 +00:00
const $props = defineProps({
url: {
type: String,
default: '',
},
model: {
type: String,
default: '',
},
filter: {
type: Object,
default: null,
},
});
2022-10-31 08:34:01 +00:00
const emit = defineEmits(['onFetch']);
2022-10-27 12:59:19 +00:00
defineExpose({
save,
});
onMounted(async () => await fetch());
onUnmounted(() => {
state.unset($props.model);
});
const isLoading = ref(false);
const hasChanges = ref(false);
const formData = computed(() => state.get($props.model));
const originalData = ref();
async function fetch() {
const { data } = await axios.get($props.url, {
params: { filter: $props.filter },
});
state.set($props.model, data);
originalData.value = Object.assign({}, data);
watch(formData.value, () => (hasChanges.value = true));
2022-10-31 08:34:01 +00:00
emit('onFetch', state.get($props.model));
2022-10-27 12:59:19 +00:00
}
async function save() {
if (!hasChanges.value) {
return quasar.notify({
type: 'negative',
message: t('globals.noChanges'),
});
}
isLoading.value = true;
await axios.patch($props.url, formData.value);
2022-10-31 08:34:01 +00:00
originalData.value = formData.value;
hasChanges.value = false;
2022-10-27 12:59:19 +00:00
isLoading.value = false;
}
function reset() {
state.set($props.model, originalData.value);
hasChanges.value = false;
}
2022-10-31 08:34:01 +00:00
function filter(value, update, filterOptions) {
update(
() => {
const { options, filterFn } = filterOptions;
options.value = filterFn(options, value);
},
(ref) => {
ref.setOptionIndex(-1);
ref.moveOptionSelection(1, true);
}
);
}
2022-10-27 12:59:19 +00:00
</script>
<template>
2022-10-31 08:34:01 +00:00
<q-banner v-if="hasChanges" class="text-white bg-warning">
<q-icon name="warning" size="md" class="q-mr-md" />
<span>{{ t('globals.changesToSave') }}</span>
</q-banner>
2022-10-27 12:59:19 +00:00
<q-form v-if="formData" @submit="save" @reset="reset" class="q-pa-md">
2022-10-31 08:34:01 +00:00
<slot name="form" :data="formData" :validate="validate" :filter="filter"></slot>
<div class="q-mt-lg">
<slot name="actions">
<q-btn :label="t('globals.save')" type="submit" color="primary" />
<q-btn
:label="t('globals.reset')"
type="reset"
class="q-ml-sm"
color="primary"
flat
:disable="!hasChanges"
/>
</slot>
</div>
2022-10-27 12:59:19 +00:00
</q-form>
<skeleton-form v-if="!formData" />
<q-inner-loading :showing="isLoading" :label="t('globals.pleaseWait')" color="primary" />
</template>