diff --git a/frontend/src/assets/main.scss b/frontend/src/assets/main.scss index af54a33f..5cda649f 100644 --- a/frontend/src/assets/main.scss +++ b/frontend/src/assets/main.scss @@ -254,6 +254,12 @@ div:focus-visible { font-size: .8rem; padding: 0.25rem 0.75rem; font-weight: 400; + line-height: 1; + + .p-tag-value { + margin-top: -2px; + } + } .p-tag-danger { @@ -271,6 +277,21 @@ div:focus-visible { } } +.p-tag-info { + background-color: rgb(224, 242, 254); + outline-style: solid; + outline-color: $bcbox-primary; + outline-width: thin; + + .p-tag-value { + color: $bcbox-primary; + } + + .p-tag-icon { + color: $bcbox-primary + } +} + /* datatable */ .p-datatable, .p-treetable { diff --git a/frontend/src/components/bucket/BucketIdpToggle.vue b/frontend/src/components/bucket/BucketIdpToggle.vue new file mode 100644 index 00000000..16479c87 --- /dev/null +++ b/frontend/src/components/bucket/BucketIdpToggle.vue @@ -0,0 +1,154 @@ + + + diff --git a/frontend/src/components/bucket/BucketList.vue b/frontend/src/components/bucket/BucketList.vue index efe7ccca..16c8d986 100644 --- a/frontend/src/components/bucket/BucketList.vue +++ b/frontend/src/components/bucket/BucketList.vue @@ -43,7 +43,19 @@ const closeBucketConfig = () => { }; onMounted(async () => { - await bucketStore.fetchBuckets({ userId: getUserId.value, objectPerms: true }); + const buckets = await bucketStore.fetchBuckets({ + userId: getUserId.value, + objectPerms: true + }); + // get IDP permissions for labelling in table + if (buckets && buckets.length > 0 && usePermissionStore().isUserElevatedRights()) { + await usePermissionStore().fetchBucketIdpPermissions({ + // limit to 1000 folders + bucketId: buckets.slice(0, 1000).map((b) => b.bucketId), + idp: 'idir', + objectPerms: true + }); + } }); @@ -103,7 +115,7 @@ onMounted(async () => { {{ bucketConfigTitle }} - + { + > + + + + diff --git a/frontend/src/components/bucket/index.ts b/frontend/src/components/bucket/index.ts index 04257c05..e4ac95d6 100644 --- a/frontend/src/components/bucket/index.ts +++ b/frontend/src/components/bucket/index.ts @@ -3,6 +3,8 @@ export { default as BucketConfigForm } from './BucketConfigForm.vue'; export { default as BucketList } from './BucketList.vue'; export { default as BucketPermission } from './BucketPermission.vue'; export { default as BucketPermissionAddUser } from './BucketPermissionAddUser.vue'; +export { default as BucketPublicToggle } from './BucketPublicToggle.vue'; +export { default as BucketIdpToggle } from './BucketIdpToggle.vue'; export { default as BucketSidebar } from './BucketSidebar.vue'; export { default as BucketTable } from './BucketTable.vue'; export { default as BucketTableBucketName } from './BucketTableBucketName.vue'; diff --git a/frontend/src/components/common/ShareButton.vue b/frontend/src/components/common/ShareButton.vue index 52f4d761..c407feb7 100644 --- a/frontend/src/components/common/ShareButton.vue +++ b/frontend/src/components/common/ShareButton.vue @@ -98,14 +98,9 @@ const showDialog = (x: boolean) => { diff --git a/frontend/src/components/layout/Navbar.vue b/frontend/src/components/layout/Navbar.vue index b4e220be..46af5e5c 100644 --- a/frontend/src/components/layout/Navbar.vue +++ b/frontend/src/components/layout/Navbar.vue @@ -39,7 +39,7 @@ const { getIsAuthenticated, getProfile } = storeToRefs(useAuthStore()); :to="{ name: RouteNames.LIST_OBJECTS_DELETED }" aria-label="Recycle Bin" > - Recycle Bin + Recycle Bin
  • diff --git a/frontend/src/components/object/ObjectFileDetails.vue b/frontend/src/components/object/ObjectFileDetails.vue index 50aa728f..da64eb20 100644 --- a/frontend/src/components/object/ObjectFileDetails.vue +++ b/frontend/src/components/object/ObjectFileDetails.vue @@ -50,7 +50,7 @@ const permissionStore = usePermissionStore(); const tagStore = useTagStore(); const versionStore = useVersionStore(); -const { getUserId } = storeToRefs(useAuthStore()); +const { getProfile, getUserId } = storeToRefs(useAuthStore()); const { getObject } = storeToRefs(objectStore); const { getIsDeleted, @@ -65,6 +65,8 @@ const object: Ref = ref(undefined); const bucketId: Ref = ref(''); const permissionsVisible: Ref = ref(false); +const isInternal = computed(() => permissionStore.getInternal(object.value)); + // version stuff const bucketVersioningEnabled = computed(() => getIsVersioningEnabled.value(props.objectId)); const currentVersionId: Ref = ref(props.versionId); @@ -118,21 +120,27 @@ async function onVersionCreated() { onMounted(async () => { const head = await objectStore.headObject(props.objectId); - - // TODO: sync object? - await objectStore.fetchObjects({ objectId: props.objectId, userId: getUserId.value, bucketPerms: true }); + // fetch object and object permissions + await objectStore.fetchObjects({ + objectId: props.objectId, + userId: getUserId.value, + idp: (getProfile.value as any)?.identity_provider, + bucketPerms: true + }); object.value = getObject.value(props.objectId); bucketId.value = object.value ? object.value.bucketId : ''; - - await permissionStore.fetchBucketPermissions({ - userId: getUserId.value, + // fetch bucket and bucket permissions + await bucketStore.fetchBuckets({ bucketId: bucketId.value, + userId: getUserId.value, + idp: (getProfile.value as any)?.identity_provider, objectPerms: true }); if ( head?.status !== 204 && !isDeleted.value && (!object.value || + // check for permissions in store !permissionStore.isObjectActionAllowed(object.value.id, getUserId.value, Permissions.READ, object.value.bucketId)) ) { router.replace({ name: RouteNames.FORBIDDEN }); @@ -158,11 +166,15 @@ onMounted(async () => { + diff --git a/frontend/src/components/object/ObjectIdpToggle.vue b/frontend/src/components/object/ObjectIdpToggle.vue new file mode 100644 index 00000000..c56ea40e --- /dev/null +++ b/frontend/src/components/object/ObjectIdpToggle.vue @@ -0,0 +1,125 @@ + + + diff --git a/frontend/src/components/object/ObjectList.vue b/frontend/src/components/object/ObjectList.vue index d9894f7b..52437434 100644 --- a/frontend/src/components/object/ObjectList.vue +++ b/frontend/src/components/object/ObjectList.vue @@ -25,11 +25,13 @@ import type { Ref } from 'vue'; type Props = { bucketId: string; isBucketPublic?: boolean; + isBucketInternal?: boolean; }; const props = withDefaults(defineProps(), { bucketId: undefined, - isBucketPublic: undefined + isBucketPublic: undefined, + isBucketInternal: undefined }); //const navStore = useNavStore(); @@ -90,7 +92,7 @@ const autoSync = async () => { const lastSyncDate = new Date(bucket?.lastSyncRequestedDate as string); const sinceLastSyncDate = differenceInSeconds(now, lastSyncDate); - // if havent synced for 24 hrs trigger autoSync + // if havent synced for 24 hrs trigger autoSync of JUST this folder level (not recursive) if (sinceLastSyncDate > autoMinimum) { await bucketStore.syncBucket(props.bucketId, false); syncStatus.value = 'Sync in progress'; @@ -118,7 +120,9 @@ const autoSync = async () => { onBeforeMount(async () => { // sync bucket if necessary - const hasRead = permissionStore.getBucketPermissions.filter((p) => p.permCode === Permissions.READ); + const hasRead = permissionStore.getBucketPermissions.filter( + (p) => p.permCode === Permissions.READ && p.bucketId === props.bucketId + ); if (hasRead.length > 0) await autoSync(); }); @@ -180,7 +184,7 @@ onBeforeMount(async () => { " > { :key="objectTableKey" :bucket-id="props.bucketId" :is-bucket-public="props.isBucketPublic" + :is-bucket-internal-only="isBucketInternal" :object-info-id="objectInfoId" @show-object-info="showObjectInfo" /> diff --git a/frontend/src/components/object/ObjectPermission.vue b/frontend/src/components/object/ObjectPermission.vue index 54eeec4c..7e62ab2b 100644 --- a/frontend/src/components/object/ObjectPermission.vue +++ b/frontend/src/components/object/ObjectPermission.vue @@ -3,7 +3,7 @@ import { storeToRefs } from 'pinia'; import { computed, onBeforeMount, ref } from 'vue'; import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'; -import { ObjectPermissionAddUser, ObjectPublicToggle } from '@/components/object'; +import { ObjectPermissionAddUser, ObjectPublicToggle, ObjectIdpToggle } from '@/components/object'; import { BulkPermission } from '@/components/common'; import { Button, Checkbox, Column, DataTable, TabPanel, TabView } from '@/lib/primevue'; @@ -40,7 +40,7 @@ const aggregatePermissionData = computed(() => { Object.values( data.reduce((acc, item) => { const baseUser = acc[item.userId] ?? { - idpName: item.idpName, + idp: item.idp, elevatedRights: item.elevatedRights, fullName: item.fullName, resource: 'object', @@ -98,9 +98,10 @@ onBeforeMount(() => {