188 lines
4.9 KiB
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>
|