forked from verdnatura/salix-front
feat: add useAcl checkUrl
This commit is contained in:
parent
bb85e8b3cb
commit
9d3569ff6e
|
@ -1,6 +1,6 @@
|
|||
<script setup>
|
||||
import axios from 'axios';
|
||||
import { computed, ref, watch } from 'vue';
|
||||
import { computed, ref, watch, onMounted } from 'vue';
|
||||
import { useRouter, onBeforeRouteLeave } from 'vue-router';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { useQuasar } from 'quasar';
|
||||
|
@ -10,12 +10,14 @@ import VnPaginate from 'components/ui/VnPaginate.vue';
|
|||
import VnConfirm from 'components/ui/VnConfirm.vue';
|
||||
import SkeletonTable from 'components/ui/SkeletonTable.vue';
|
||||
import { tMobile } from 'src/composables/tMobile';
|
||||
import { useAcl } from 'src/composables/useAcl';
|
||||
|
||||
const { push } = useRouter();
|
||||
const quasar = useQuasar();
|
||||
const stateStore = useStateStore();
|
||||
const { t } = useI18n();
|
||||
const { validate } = useValidator();
|
||||
const { checkUrl } = useAcl();
|
||||
|
||||
const $props = defineProps({
|
||||
model: {
|
||||
|
@ -71,6 +73,10 @@ const $props = defineProps({
|
|||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
checkPermissions: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
});
|
||||
|
||||
const isLoading = ref(false);
|
||||
|
@ -80,6 +86,9 @@ const vnPaginateRef = ref();
|
|||
const formData = ref();
|
||||
const saveButtonRef = ref(null);
|
||||
const watchChanges = ref();
|
||||
const saveChangeUrl = ref();
|
||||
const hasWritePremission = ref();
|
||||
const accessDeniedTitle = ref(t('errors.statusUnauthorized'));
|
||||
const formUrl = computed(() => $props.url);
|
||||
|
||||
const emit = defineEmits(['onFetch', 'update:selected', 'saveChanges']);
|
||||
|
@ -95,6 +104,8 @@ defineExpose({
|
|||
getChanges,
|
||||
formData,
|
||||
vnPaginateRef,
|
||||
hasWritePremission,
|
||||
accessDeniedTitle,
|
||||
});
|
||||
|
||||
onBeforeRouteLeave((to, from, next) => {
|
||||
|
@ -110,6 +121,17 @@ onBeforeRouteLeave((to, from, next) => {
|
|||
else next();
|
||||
});
|
||||
|
||||
onMounted(() => {
|
||||
saveChangeUrl.value = $props.saveUrl || $props.url + '/crud';
|
||||
hasWritePremission.value =
|
||||
!$props.checkPermissions || checkUrl(saveChangeUrl.value, 'post');
|
||||
});
|
||||
|
||||
watch(formUrl, async () => {
|
||||
originalData.value = null;
|
||||
reset();
|
||||
});
|
||||
|
||||
async function fetch(data) {
|
||||
resetData(data);
|
||||
emit('onFetch', data);
|
||||
|
@ -173,7 +195,7 @@ async function saveChanges(data) {
|
|||
}
|
||||
const changes = data || getChanges();
|
||||
try {
|
||||
await axios.post($props.saveUrl || $props.url + '/crud', changes);
|
||||
await axios.post(saveChangeUrl.value, changes);
|
||||
} catch (e) {
|
||||
return (isLoading.value = false);
|
||||
}
|
||||
|
@ -299,11 +321,6 @@ async function reload(params) {
|
|||
const data = await vnPaginateRef.value.fetch(params);
|
||||
fetch(data);
|
||||
}
|
||||
|
||||
watch(formUrl, async () => {
|
||||
originalData.value = null;
|
||||
reset();
|
||||
});
|
||||
</script>
|
||||
<template>
|
||||
<VnPaginate
|
||||
|
@ -337,8 +354,8 @@ watch(formUrl, async () => {
|
|||
icon="delete"
|
||||
flat
|
||||
@click="remove(selected)"
|
||||
:disable="!selected?.length"
|
||||
:title="t('globals.remove')"
|
||||
:disable="!selected?.length || !hasWritePremission"
|
||||
:title="hasWritePremission ? t('globals.remove') : accessDeniedTitle"
|
||||
v-if="$props.defaultRemove"
|
||||
/>
|
||||
<QBtn
|
||||
|
@ -355,8 +372,10 @@ watch(formUrl, async () => {
|
|||
v-if="$props.goTo && $props.defaultSave"
|
||||
@click="onSubmitAndGo"
|
||||
:label="tMobile('globals.saveAndContinue')"
|
||||
:title="t('globals.saveAndContinue')"
|
||||
:disable="!hasChanges"
|
||||
:title="
|
||||
hasWritePremission ? t('globals.saveAndContinue') : accessDeniedTitle
|
||||
"
|
||||
:disable="!hasChanges || !hasWritePremission"
|
||||
color="primary"
|
||||
icon="save"
|
||||
split
|
||||
|
@ -390,8 +409,8 @@ watch(formUrl, async () => {
|
|||
color="primary"
|
||||
icon="save"
|
||||
@click="onSubmit"
|
||||
:disable="!hasChanges"
|
||||
:title="t('globals.save')"
|
||||
:disable="!hasChanges || !hasWritePremission"
|
||||
:title="hasWritePremission ? t('globals.save') : accessDeniedTitle"
|
||||
/>
|
||||
<slot name="moreAfterActions" />
|
||||
</QBtnGroup>
|
||||
|
|
|
@ -13,6 +13,7 @@ import VnConfirm from './ui/VnConfirm.vue';
|
|||
import { tMobile } from 'src/composables/tMobile';
|
||||
import { useArrayData } from 'src/composables/useArrayData';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useAcl } from 'src/composables/useAcl';
|
||||
|
||||
const { push } = useRouter();
|
||||
const quasar = useQuasar();
|
||||
|
@ -21,6 +22,8 @@ const stateStore = useStateStore();
|
|||
const { t } = useI18n();
|
||||
const { validate } = useValidator();
|
||||
const { notify } = useNotify();
|
||||
const { checkUrl } = useAcl();
|
||||
|
||||
const route = useRoute();
|
||||
const myForm = ref(null);
|
||||
const $props = defineProps({
|
||||
|
@ -91,6 +94,10 @@ const $props = defineProps({
|
|||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
checkPermissions: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
});
|
||||
const emit = defineEmits(['onFetch', 'onDataSaved']);
|
||||
const modelValue = computed(
|
||||
|
@ -104,6 +111,15 @@ const isResetting = ref(false);
|
|||
const hasChanges = ref(!$props.observeFormChanges);
|
||||
const originalData = ref({});
|
||||
const formData = computed(() => state.get(modelValue));
|
||||
const saveUrl = computed(
|
||||
() => $props.urlCreate || $props.urlUpdate || $props.url || arrayData.store.url
|
||||
);
|
||||
const saveMethod = computed(() => ($props.urlCreate ? 'post' : 'patch'));
|
||||
const hasWritePremission = computed(
|
||||
() =>
|
||||
$props.saveFn ||
|
||||
(!$props.checkPermissions && checkUrl(saveUrl.value, saveMethod.value))
|
||||
);
|
||||
const defaultButtons = computed(() => ({
|
||||
save: {
|
||||
color: 'primary',
|
||||
|
@ -184,6 +200,7 @@ onUnmounted(() => {
|
|||
|
||||
async function fetch() {
|
||||
try {
|
||||
checkUrl($props.url, 'get', true);
|
||||
let { data } = await axios.get($props.url, {
|
||||
params: { filter: JSON.stringify($props.filter) },
|
||||
});
|
||||
|
@ -204,13 +221,10 @@ async function save() {
|
|||
try {
|
||||
formData.value = trimData(formData.value);
|
||||
const body = $props.mapper ? $props.mapper(formData.value) : formData.value;
|
||||
const method = $props.urlCreate ? 'post' : 'patch';
|
||||
const url =
|
||||
$props.urlCreate || $props.urlUpdate || $props.url || arrayData.store.url;
|
||||
let response;
|
||||
|
||||
if ($props.saveFn) response = await $props.saveFn(body);
|
||||
else response = await axios[method](url, body);
|
||||
else response = await axios[saveMethod.value](saveUrl.value, body);
|
||||
|
||||
if ($props.urlCreate) notify('globals.dataCreated', 'positive');
|
||||
|
||||
|
@ -323,7 +337,7 @@ defineExpose({
|
|||
@click="saveAndGo"
|
||||
:label="tMobile('globals.saveAndContinue')"
|
||||
:title="t('globals.saveAndContinue')"
|
||||
:disable="!hasChanges"
|
||||
:disable="!hasChanges || !hasWritePremission"
|
||||
color="primary"
|
||||
icon="save"
|
||||
split
|
||||
|
@ -355,7 +369,7 @@ defineExpose({
|
|||
color="primary"
|
||||
icon="save"
|
||||
@click="defaultButtons.save.click"
|
||||
:disable="!hasChanges"
|
||||
:disable="!hasChanges || !hasWritePremission"
|
||||
:title="t(defaultButtons.save.label)"
|
||||
/>
|
||||
</QBtnGroup>
|
||||
|
|
|
@ -3,6 +3,7 @@ import { useRouter, useRoute } from 'vue-router';
|
|||
import axios from 'axios';
|
||||
import { useArrayDataStore } from 'stores/useArrayDataStore';
|
||||
import { buildFilter } from 'filters/filterPanel';
|
||||
import { useAcl } from 'src/composables/useAcl';
|
||||
|
||||
const arrayDataStore = useArrayDataStore();
|
||||
|
||||
|
@ -14,6 +15,8 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
|||
const store = arrayDataStore.get(key);
|
||||
const route = useRoute();
|
||||
const router = useRouter();
|
||||
const { checkUrl } = useAcl();
|
||||
|
||||
let canceller = null;
|
||||
|
||||
onMounted(() => {
|
||||
|
@ -65,6 +68,7 @@ export function useArrayData(key = useRoute().meta.moduleName, userOptions) {
|
|||
|
||||
async function fetch({ append = false, updateRouter = true }) {
|
||||
if (!store.url) return;
|
||||
if (store.checkAcl) checkUrl(store.url, 'get', true);
|
||||
|
||||
cancelRequest();
|
||||
canceller = new AbortController();
|
||||
|
|
|
@ -11,7 +11,7 @@ const route = useRoute();
|
|||
|
||||
const { t } = useI18n();
|
||||
|
||||
const claimDevelopmentForm = ref();
|
||||
const claimDevelopmentForm = ref({});
|
||||
const claimReasons = ref([]);
|
||||
const claimResults = ref([]);
|
||||
const claimResponsibles = ref([]);
|
||||
|
@ -222,9 +222,16 @@ const columns = computed(() => [
|
|||
ref="saveButtonRef"
|
||||
color="primary"
|
||||
icon="save"
|
||||
:disable="!claimDevelopmentForm?.hasChanges"
|
||||
:disable="
|
||||
!claimDevelopmentForm?.hasChanges ||
|
||||
!claimDevelopmentForm.hasWritePremission
|
||||
"
|
||||
@click="claimDevelopmentForm?.onSubmit"
|
||||
:title="t('globals.save')"
|
||||
:title="
|
||||
claimDevelopmentForm.hasWritePremission
|
||||
? t('globals.save')
|
||||
: claimDevelopmentForm.accessDeniedTitle
|
||||
"
|
||||
/>
|
||||
</template>
|
||||
</CrudModel>
|
||||
|
@ -235,6 +242,11 @@ const columns = computed(() => [
|
|||
icon="add"
|
||||
@keydown.tab.prevent="saveButtonRef.$el.focus()"
|
||||
@click="claimDevelopmentForm.insert()"
|
||||
:disable="!claimDevelopmentForm.hasWritePremission"
|
||||
:title="
|
||||
!claimDevelopmentForm.hasWritePremission &&
|
||||
claimDevelopmentForm.accessDeniedTitle
|
||||
"
|
||||
/>
|
||||
</QPageSticky>
|
||||
</template>
|
||||
|
|
Loading…
Reference in New Issue