jcloud/dashboard/src2/views/settings/EditPermissions.vue

188 lines
4.9 KiB
Vue

<template>
<Dialog
:options="{
title: `Editing permissions for ${
type === 'group' ? 'group' : 'member'
} ${name}`,
size: '3xl'
}"
:modelValue="show"
@after-leave="
() => {
$emit('close', true);
}
"
>
<template v-slot:body-content>
<Input
class="mb-2"
placeholder="Search"
v-on:input="e => updateSearchTerm(e)"
/>
<LoadingText v-if="$resources.options.loading" />
<div v-else class="flex flex-col max-h-96 overflow-auto">
<div v-if="options.length === 0" class="mt-4 text-center">
<span class="text-gray-500">
No options available to add permissions, let's create somes sites!
<router-link :to="'/sites/new'" class="text-gray-900">
Click here
</router-link>
</span>
</div>
<div
v-else
v-for="(option, index) in filteredList"
class="border-b pt-2"
>
<span class="mr-2 mt-4 w-full pb-2 text-lg text-gray-600">
{{ option.pagetype }}
</span>
<span class="inline-block align-middle text-base font-bold">
{{ option.title ? option.title : option.name }}
</span>
<Input
class="pt-4"
type="checkbox"
label="Select All"
@change="val => toggleSelectAll(option, index, val)"
/>
<div class="grid grid-cols-4 gap-4 py-4">
<Input
v-for="[label, action] in Object.entries(actions[option.pagetype])"
type="checkbox"
:checked="isSelected(option, action)"
:label="label"
@change="() => updateAction(option, index, action)"
>
</Input>
</div>
</div>
</div>
</template>
<template v-slot:actions>
<Button
variant="solid"
class="w-full"
@click="$resources.updatePermissions.submit()"
:disabled="options.length === 0"
>
Save
</Button>
</template>
</Dialog>
</template>
<script>
import Fuse from 'fuse.js/dist/fuse.basic.esm';
import { notify } from '@/utils/toast';
export default {
name: 'EditPermissions',
props: ['show', 'name', 'type'],
data() {
return {
updated: {},
filteredList: []
};
},
resources: {
options() {
return {
url: 'jcloud.api.account.get_permission_options',
auto: true,
params: {
name: this.name,
ptype: this.type
},
onSuccess(r) {
this.fuse = new Fuse(r.options, {
keys: ['pagetype', 'name', 'title'],
threshold: 0.3
});
this.filteredList = r.options;
}
};
},
updatePermissions() {
return {
url: 'jcloud.api.account.update_permissions',
params: {
user: this.name,
ptype: this.type,
updated: this.updated
},
onSuccess() {
notify({
title: 'Permissions Updated',
color: 'green',
icon: 'check'
});
this.$emit('close', true);
this.$resources.options.fetch();
}
};
}
},
methods: {
isSelected(option, action) {
let alreadyAdded = false;
if (option.perms !== null) {
alreadyAdded = option.perms.includes(action);
}
return (
alreadyAdded ||
(this.updated?.[option.pagetype]?.[option.name] || []).includes(action)
);
},
updateSearchTerm(value) {
if (value) {
this.filteredList = this.fuse.search(value).map(result => result.item);
} else {
this.filteredList = this.options;
}
},
updateAction(option, index, action) {
// create updated object for pagetype if it doesn't exists
if (!this.updated[option.pagetype]) {
// if an entry for docname doesn't exists add it to update object with default permission
this.updated[option.pagetype] = {};
}
// create updated record for docname if it doesn't exists and set all existing perms
if (!this.updated[option.pagetype][option.name]) {
this.updated[option.pagetype][option.name] =
option.perms === null ? [] : option.perms.split(',');
}
if (this.updated[option.pagetype][option.name].includes(action)) {
// toggle off
this.updated[option.pagetype][option.name] = this.updated[
option.pagetype
][option.name].filter(item => item !== action);
} else {
// toggled on
this.updated[option.pagetype][option.name].push(action);
}
},
toggleSelectAll(option, index, selected) {
if (!this.updated[option.pagetype]) {
this.updated[option.pagetype] = {};
}
const allActions = Object.values(this.actions[option.pagetype]);
this.updated[option.pagetype][option.name] = selected
? Object.assign([], allActions)
: [];
this.filteredList[index].perms = selected ? allActions.join(',') : '';
}
},
computed: {
options() {
if (!this.$resources.options.data) return [];
return this.$resources.options.data.options;
},
actions() {
if (!this.$resources.options.data) return {};
return this.$resources.options.data.actions;
}
}
};
</script>