diff --git a/app/src/interfaces/many-to-many/many-to-many.vue b/app/src/interfaces/many-to-many/many-to-many.vue index c562c3db6f..d04168e26c 100644 --- a/app/src/interfaces/many-to-many/many-to-many.vue +++ b/app/src/interfaces/many-to-many/many-to-many.vue @@ -39,8 +39,8 @@
- {{ $t('create_new') }} - + {{ $t('create_new') }} + {{ $t('add_existing') }}
@@ -85,6 +85,7 @@ import useSelection from './use-selection'; import useSort from './use-sort'; import { getFieldsFromTemplate } from '@/utils/get-fields-from-template'; import adjustFieldsForDisplays from '@/utils/adjust-fields-for-displays'; +import { usePermissionsStore, useUserStore } from '@/stores'; export default defineComponent({ components: { DrawerItem, DrawerCollection, Draggable }, @@ -113,8 +114,19 @@ export default defineComponent({ type: Boolean, default: false, }, + enableCreate: { + type: Boolean, + default: true, + }, + enableSelect: { + type: Boolean, + default: true, + }, }, setup(props, { emit }) { + const permissionsStore = usePermissionsStore(); + const userStore = useUserStore(); + const { value, collection, field } = toRefs(props); const { junction, junctionCollection, relation, relationCollection, relationInfo } = useRelation(collection, field); @@ -173,9 +185,10 @@ export default defineComponent({ } = useEdit(value, relationInfo, emitter); const { stageSelection, selectModalActive, selectionFilters } = useSelection(value, items, relationInfo, emitter); - const { sort, sortItems, sortedItems } = useSort(relationInfo, fields, items, emitter); + const { createAllowed, selectAllowed } = usePermissions(); + return { junction, relation, @@ -201,11 +214,46 @@ export default defineComponent({ sortItems, sortedItems, templateWithDefaults, + createAllowed, + selectAllowed, }; function emitter(newVal: any[] | null) { emit('input', newVal); } + + function usePermissions() { + const createAllowed = computed(() => { + const admin = userStore.state?.currentUser?.role.admin_access === true; + if (admin) return true; + + const hasJunctionPermissions = !!permissionsStore.state.permissions.find( + (permission) => + permission.action === 'create' && permission.collection === junctionCollection.value.collection + ); + + const hasRelatedPermissions = !!permissionsStore.state.permissions.find( + (permission) => + permission.action === 'create' && permission.collection === relationCollection.value.collection + ); + + return hasJunctionPermissions && hasRelatedPermissions; + }); + + const selectAllowed = computed(() => { + const admin = userStore.state?.currentUser?.role.admin_access === true; + if (admin) return true; + + const hasJunctionPermissions = !!permissionsStore.state.permissions.find( + (permission) => + permission.action === 'create' && permission.collection === junctionCollection.value.collection + ); + + return hasJunctionPermissions; + }); + + return { createAllowed, selectAllowed }; + } }, }); @@ -217,10 +265,10 @@ export default defineComponent({ .actions { margin-top: 12px; -} -.existing { - margin-left: 12px; + .v-button + .v-button { + margin-left: 12px; + } } .deselect { diff --git a/app/src/interfaces/many-to-many/options.vue b/app/src/interfaces/many-to-many/options.vue index a8d83e690e..671ef0d922 100644 --- a/app/src/interfaces/many-to-many/options.vue +++ b/app/src/interfaces/many-to-many/options.vue @@ -15,6 +15,16 @@ " /> + +
+

{{ $t('creating_items') }}

+ +
+ +
+

{{ $t('selecting_items') }}

+ +
@@ -65,6 +75,30 @@ export default defineComponent({ }, }); + const enableCreate = computed({ + get() { + return props.value?.enableCreate ?? true; + }, + set(val: boolean) { + emit('input', { + ...(props.value || {}), + enableCreate: val, + }); + }, + }); + + const enableSelect = computed({ + get() { + return props.value?.enableSelect ?? true; + }, + set(val: boolean) { + emit('input', { + ...(props.value || {}), + enableSelect: val, + }); + }, + }); + const junctionCollection = computed(() => { if (!props.fieldData || !props.relations || props.relations.length === 0) return null; const { field } = props.fieldData; @@ -80,7 +114,7 @@ export default defineComponent({ return collectionsStore.getCollection(junctionCollection.value); }); - return { template, junctionCollection, junctionCollectionInfo }; + return { template, enableCreate, enableSelect, junctionCollection, junctionCollectionInfo }; }, }); diff --git a/app/src/interfaces/one-to-many/one-to-many.vue b/app/src/interfaces/one-to-many/one-to-many.vue index 130faa3ccd..152913a2e4 100644 --- a/app/src/interfaces/one-to-many/one-to-many.vue +++ b/app/src/interfaces/one-to-many/one-to-many.vue @@ -28,19 +28,22 @@ v-for="item in sortedItems" :key="item.id" block + :disabled="disabled || updateAllowed === false" @click="editItem(item)" >
- +
- {{ $t('create_new') }} - + + {{ $t('create_new') }} + + {{ $t('add_existing') }}
@@ -72,7 +75,7 @@ import { defineComponent, ref, computed, watch, PropType } from '@vue/composition-api'; import api from '@/api'; import useCollection from '@/composables/use-collection'; -import { useCollectionsStore, useRelationsStore, useFieldsStore } from '@/stores/'; +import { useCollectionsStore, useRelationsStore, useFieldsStore, usePermissionsStore, useUserStore } from '@/stores/'; import DrawerItem from '@/views/private/components/drawer-item'; import DrawerCollection from '@/views/private/components/drawer-collection'; import { Filter, Field } from '@/types'; @@ -110,11 +113,21 @@ export default defineComponent({ type: Boolean, default: false, }, + enableCreate: { + type: Boolean, + default: true, + }, + enableSelect: { + type: Boolean, + default: true, + }, }, setup(props, { emit }) { const relationsStore = useRelationsStore(); const collectionsStore = useCollectionsStore(); const fieldsStore = useFieldsStore(); + const permissionsStore = usePermissionsStore(); + const userStore = useUserStore(); const { relation, relatedCollection, relatedPrimaryKeyField } = useRelation(); @@ -131,6 +144,8 @@ export default defineComponent({ const { stageSelection, selectModalActive, selectionFilters } = useSelection(); const { sort, sortItems, sortedItems } = useSort(); + const { createAllowed, updateAllowed } = usePermissions(); + return { relation, loading, @@ -151,6 +166,8 @@ export default defineComponent({ get, getItemFromIndex, templateWithDefaults, + createAllowed, + updateAllowed, }; function getItemFromIndex(index: number) { @@ -426,6 +443,28 @@ export default defineComponent({ const fields = fieldsStore.getFieldsForCollection(relatedCollection.value.collection); return fields.slice(0, 3).map((field: Field) => field.field); } + + function usePermissions() { + const createAllowed = computed(() => { + const admin = userStore.state?.currentUser?.role.admin_access === true; + if (admin) return true; + + return !!permissionsStore.state.permissions.find( + (permission) => permission.action === 'create' && permission.collection === relatedCollection.value.collection + ); + }); + + const updateAllowed = computed(() => { + const admin = userStore.state?.currentUser?.role.admin_access === true; + if (admin) return true; + + return !!permissionsStore.state.permissions.find( + (permission) => permission.action === 'update' && permission.collection === relatedCollection.value.collection + ); + }); + + return { createAllowed, updateAllowed }; + } }, }); @@ -437,10 +476,10 @@ export default defineComponent({ .actions { margin-top: 8px; -} -.existing { - margin-left: 8px; + .v-button + .v-button { + margin-left: 8px; + } } .deselect { diff --git a/app/src/interfaces/one-to-many/options.vue b/app/src/interfaces/one-to-many/options.vue index 66b8931894..45446022cd 100644 --- a/app/src/interfaces/one-to-many/options.vue +++ b/app/src/interfaces/one-to-many/options.vue @@ -15,6 +15,16 @@ " />
+ +
+

{{ $t('creating_items') }}

+ +
+ +
+

{{ $t('selecting_items') }}

+ +
@@ -65,6 +75,30 @@ export default defineComponent({ }, }); + const enableCreate = computed({ + get() { + return props.value?.enableCreate ?? true; + }, + set(val: boolean) { + emit('input', { + ...(props.value || {}), + enableCreate: val, + }); + }, + }); + + const enableSelect = computed({ + get() { + return props.value?.enableSelect ?? true; + }, + set(val: boolean) { + emit('input', { + ...(props.value || {}), + enableSelect: val, + }); + }, + }); + const relatedCollection = computed(() => { if (!props.fieldData || !props.relations || props.relations.length === 0) return null; const { field } = props.fieldData; @@ -79,7 +113,7 @@ export default defineComponent({ return collectionsStore.getCollection(relatedCollection.value); }); - return { template, relatedCollection, relatedCollectionInfo }; + return { template, enableCreate, enableSelect, relatedCollection, relatedCollectionInfo }; }, }); diff --git a/app/src/interfaces/tree-view/options.vue b/app/src/interfaces/tree-view/options.vue index c44c14d9b7..39e7ebd9ec 100644 --- a/app/src/interfaces/tree-view/options.vue +++ b/app/src/interfaces/tree-view/options.vue @@ -7,6 +7,16 @@

{{ $t('interfaces.many-to-one.display_template') }}

+ +
+

{{ $t('creating_items') }}

+ +
+ +
+

{{ $t('selecting_items') }}

+ +
@@ -46,7 +56,31 @@ export default defineComponent({ }, }); - return { template }; + const enableCreate = computed({ + get() { + return props.value?.enableCreate ?? true; + }, + set(val: boolean) { + emit('input', { + ...(props.value || {}), + enableCreate: val, + }); + }, + }); + + const enableSelect = computed({ + get() { + return props.value?.enableSelect ?? true; + }, + set(val: boolean) { + emit('input', { + ...(props.value || {}), + enableSelect: val, + }); + }, + }); + + return { template, enableCreate, enableSelect }; }, }); diff --git a/app/src/interfaces/tree-view/tree-view.vue b/app/src/interfaces/tree-view/tree-view.vue index c5210d9193..b3039e7663 100644 --- a/app/src/interfaces/tree-view/tree-view.vue +++ b/app/src/interfaces/tree-view/tree-view.vue @@ -18,8 +18,8 @@ />
- {{ $t('create_new') }} - + {{ $t('create_new') }} + {{ $t('add_existing') }}
@@ -88,6 +88,14 @@ export default defineComponent({ type: [String, Number], default: undefined, }, + enableCreate: { + type: Boolean, + default: true, + }, + enableSelect: { + type: Boolean, + default: true, + }, }, setup(props, { emit }) { const relationsStore = useRelationsStore(); diff --git a/app/src/lang/translations/en-US.yaml b/app/src/lang/translations/en-US.yaml index 3a1f3fa8cc..08d3a5c2a6 100644 --- a/app/src/lang/translations/en-US.yaml +++ b/app/src/lang/translations/en-US.yaml @@ -320,6 +320,10 @@ save_and_create_new: Save and Create New save_and_stay: Save and Stay save_as_copy: Save as Copy add_existing: Add Existing +creating_items: Creating Items +enable_create_button: Enable Create Button +selecting_items: Selecting Items +enable_select_button: Enable Select Button comments: Comments no_comments: No Comments Yet click_to_expand: Click to Expand