diff --git a/src/components/CrudModel.vue b/src/components/CrudModel.vue
index 0386e037b3..b93fbdad17 100644
--- a/src/components/CrudModel.vue
+++ b/src/components/CrudModel.vue
@@ -1,6 +1,6 @@
{
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"
/>
{
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"
/>
diff --git a/src/components/FormModel.vue b/src/components/FormModel.vue
index 05f947cf39..cf350cc1b9 100644
--- a/src/components/FormModel.vue
+++ b/src/components/FormModel.vue
@@ -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)"
/>
diff --git a/src/composables/useArrayData.js b/src/composables/useArrayData.js
index 651bcefb03..a6d92248b3 100644
--- a/src/composables/useArrayData.js
+++ b/src/composables/useArrayData.js
@@ -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();
diff --git a/src/pages/Claim/Card/ClaimDevelopment.vue b/src/pages/Claim/Card/ClaimDevelopment.vue
index 61d9f58585..2f88325abf 100644
--- a/src/pages/Claim/Card/ClaimDevelopment.vue
+++ b/src/pages/Claim/Card/ClaimDevelopment.vue
@@ -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
+ "
/>
@@ -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
+ "
/>