Skip to content

Commit

Permalink
Merge pull request #144 from bcgov/public-toggle-inside-permissions
Browse files Browse the repository at this point in the history
Add public toggle to permissions modal
  • Loading branch information
TimCsaky authored Nov 6, 2023
2 parents 5780f57 + f692250 commit 45a0aa0
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 46 deletions.
2 changes: 0 additions & 2 deletions app/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ dist
files
**/e2e/videos
node_modules
# Ignore only top-level package-lock.json
/package-lock.json

# Ignore Helm subcharts
charts/**/charts
Expand Down
56 changes: 30 additions & 26 deletions frontend/src/components/form/SearchUsers.vue
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ const onReset = () => {
watch(selectedIDP, () => {
if (selectedIDP.value?.searchable) {
userSearchPlaceholder.value = `Enter an existing ${selectedIDP.value?.name} user's name or email address`;
userSearchPlaceholder.value = `Enter the full name or email address of an existing ${selectedIDP.value?.name}`;
} else {
userSearchPlaceholder.value = `Enter an existing user's ${selectedIDP.value?.name} email address`;
}
Expand Down Expand Up @@ -144,35 +144,39 @@ onMounted(() => {
/>
</div>

<Dropdown
v-model="userSearchInput"
:options="userSearch"
:option-label="(option) => getUserDropdownLabel(option)"
editable
:placeholder="userSearchPlaceholder"
class="mt-1 mb-4"
:class="invalidSelectedUser ? 'p-invalid' : ''"
@input="onInput"
@change="onChange"
/>
<Button
label="Add"
class="mt-1 mb-4 ml-3"
icon="pi pi-check"
:disabled="!selectedUser"
@click="onAdd"
/>
<Button
label="Cancel"
class="p-button-outlined mt-1 mb-4 ml-3"
icon="pi pi-times"
@click="onCancel"
/>
<div class="flex">
<div class="flex flex-auto">
<Dropdown
v-model="userSearchInput"
:options="userSearch"
:option-label="(option) => getUserDropdownLabel(option)"
editable
:placeholder="userSearchPlaceholder"
class="mt-1 mb-4"
:class="invalidSelectedUser ? 'p-invalid' : ''"
@input="onInput"
@change="onChange"
/>
</div>
<Button
label="Add"
class="mt-1 mb-4 ml-3"
icon="pi pi-check"
:disabled="!selectedUser"
@click="onAdd"
/>
<Button
label="Cancel"
class="p-button-outlined mt-1 mb-4 ml-3"
icon="pi pi-times"
@click="onCancel"
/>
</div>
</div>
</template>

<style lang="scss" scoped>
.p-dropdown {
width: 60%;
width: 100%;
}
</style>
30 changes: 27 additions & 3 deletions frontend/src/components/object/ObjectPermission.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import { storeToRefs } from 'pinia';
import { onBeforeMount, ref } from 'vue';
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome';
import ObjectPermissionAddUser from '@/components/object/ObjectPermissionAddUser.vue';
import { ObjectPermissionAddUser, ObjectPublicToggle } from '@/components/object';
import { useAlert } from '@/composables/useAlert';
import { Button, Checkbox, Column, DataTable } from '@/lib/primevue';
import { usePermissionStore } from '@/store';
import { useAuthStore, useObjectStore, usePermissionStore } from '@/store';
import { Permissions } from '@/utils/constants';
import type { Ref } from 'vue';
import type { UserPermissions } from '@/types';
import type { COMSObject, UserPermissions } from '@/types';
// Props
type Props = {
Expand All @@ -20,11 +20,14 @@ type Props = {
const props = withDefaults(defineProps<Props>(), {});
// Store
const objectStore = useObjectStore();
const permissionStore = usePermissionStore();
const { getMappedObjectToUserPermissions } = storeToRefs(permissionStore);
const { getUserId } = storeToRefs(useAuthStore());
// State
const showSearchUsers: Ref<boolean> = ref(false);
const object: Ref<COMSObject | undefined> = ref(undefined);
// Actions
const removeManageAlert = useAlert('Warning', 'Cannot remove last user with MANAGE permission.');
Expand Down Expand Up @@ -72,11 +75,32 @@ const updateObjectPermission = (value: boolean, userId: string, permCode: string
onBeforeMount(() => {
permissionStore.mapObjectToUserPermissions(props.objectId);
object.value = objectStore.findObjectById(props.objectId);
});
</script>

<template>
<div>
<div class="flex flex-row gap-6 pb-3">
<div>
<h3 class="pb-1">Public</h3>
<ul>
<li>This option toggles the file to be publicly available and accessible to anyone</li>
<li>To instead set explicit permissions, add users and use the options below</li>
</ul>
</div>
<ObjectPublicToggle
v-if="object && getUserId"
class="ml-4"
:bucket-id="object.bucketId"
:object-id="object.id"
:object-public="object.public"
:user-id="getUserId"
/>
</div>

<h3 class="mt-1 mb-2">User Permissions</h3>

<div v-if="!showSearchUsers">
<Button
class="mt-1 mb-4"
Expand Down
53 changes: 53 additions & 0 deletions frontend/src/components/object/ObjectPublicToggle.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<script setup lang="ts">
import { ref, watch } from 'vue';
import { InputSwitch } from '@/lib/primevue';
import { useObjectStore, usePermissionStore } from '@/store';
import { Permissions } from '@/utils/constants';
import type { Ref } from 'vue';
// Props
type Props = {
bucketId: string;
objectId: string;
objectPublic: boolean;
userId: string;
};
const props = withDefaults(defineProps<Props>(), {});
// Store
const objectStore = useObjectStore();
const permissionStore = usePermissionStore();
// State
const isPublic: Ref<boolean> = ref(props.objectPublic);
// Actions
const togglePublic = async (isPublic: boolean) => {
await objectStore.togglePublic(props.objectId, isPublic);
};
watch(props, () => {
isPublic.value = props.objectPublic;
});
</script>

<template>
<InputSwitch
v-model="isPublic"
:disabled="
!(
usePermissionStore().isUserElevatedRights() &&
permissionStore.isObjectActionAllowed(
props.objectId,
props.userId,
Permissions.MANAGE,
props.bucketId as string
)
)
"
@change="togglePublic(isPublic)"
/>
</template>
29 changes: 14 additions & 15 deletions frontend/src/components/object/ObjectTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@ import { storeToRefs } from 'pinia';
import { onUnmounted, ref, watch } from 'vue';
import { Spinner } from '@/components/layout';
import { DeleteObjectButton, DownloadObjectButton, ObjectFilters, ObjectPermission } from '@/components/object';
import {
DeleteObjectButton,
DownloadObjectButton,
ObjectFilters,
ObjectPermission,
ObjectPublicToggle
} from '@/components/object';
import { SyncButton } from '@/components/common';
import { ShareObjectButton } from '@/components/object/share';
import { Button, Column, DataTable, Dialog, FilterMatchMode, InputText, InputSwitch, useToast } from '@/lib/primevue';
import { Button, Column, DataTable, Dialog, FilterMatchMode, InputText, useToast } from '@/lib/primevue';
import { useAuthStore, useAppStore, useObjectStore, usePermissionStore } from '@/store';
import { Permissions } from '@/utils/constants';
import { ButtonMode } from '@/utils/enums';
Expand Down Expand Up @@ -64,10 +70,6 @@ const showPermissions = async (objectId: string) => {
permissionsObjectName.value = objectStore.findObjectById(objectId)?.name;
};
const togglePublic = async (objectId: string, isPublic: boolean) => {
await objectStore.togglePublic(objectId, isPublic);
};
function onDeletedSuccess() {
toast.success('File deleted');
}
Expand Down Expand Up @@ -204,15 +206,12 @@ const filters = ref({
header="Public"
>
<template #body="{ data }">
<InputSwitch
v-model="data.public"
:disabled="
!(
usePermissionStore().isUserElevatedRights() &&
permissionStore.isObjectActionAllowed(data.id, getUserId, Permissions.MANAGE, props.bucketId as string)
)
"
@change="togglePublic(data.id, data.public)"
<ObjectPublicToggle
v-if="props.bucketId && getUserId"
:bucket-id="props.bucketId"
:object-id="data.id"
:object-public="data.public"
:user-id="getUserId"
/>
</template>
</Column>
Expand Down
1 change: 1 addition & 0 deletions frontend/src/components/object/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export { default as ObjectMetadataTagForm } from './ObjectMetadataTagForm.vue';
export { default as ObjectPermission } from './ObjectPermission.vue';
export { default as ObjectPermissionAddUser } from './ObjectPermissionAddUser.vue';
export { default as ObjectProperties } from './ObjectProperties.vue';
export { default as ObjectPublicToggle } from './ObjectPublicToggle.vue';
export { default as ObjectSidebar } from './ObjectSidebar.vue';
export { default as ObjectTable } from './ObjectTable.vue';
export { default as ObjectTag } from './ObjectTag.vue';
Expand Down
2 changes: 2 additions & 0 deletions frontend/src/store/objectStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ export const useObjectStore = defineStore('object', () => {
try {
appStore.beginIndeterminateLoading();
await objectService.togglePublic(objectId, isPublic);
const obj = findObjectById(objectId);
if (obj) obj.public = isPublic;
} catch (error: any) {
toast.error('Changing public state', error);
} finally {
Expand Down

0 comments on commit 45a0aa0

Please sign in to comment.