<script setup> import { VForm } from 'vuetify/components/VForm' const props = defineProps({ rolePermissions: { type: Object, required: false, default: () => ({ name: '', permissions: [], }), }, isDialogVisible: { type: Boolean, required: true, }, }) const emit = defineEmits([ 'update:isDialogVisible', 'update:rolePermissions', ]) // 👉 Permission List const permissions = ref([ { name: 'User Management', read: false, write: false, create: false, }, { name: 'Content Management', read: false, write: false, create: false, }, { name: 'Disputes Management', read: false, write: false, create: false, }, { name: 'Database Management', read: false, write: false, create: false, }, { name: 'Financial Management', read: false, write: false, create: false, }, { name: 'Reporting', read: false, write: false, create: false, }, { name: 'API Control', read: false, write: false, create: false, }, { name: 'Repository Management', read: false, write: false, create: false, }, { name: 'Payroll', read: false, write: false, create: false, }, ]) const isSelectAll = ref(false) const role = ref('') const refPermissionForm = ref() const checkedCount = computed(() => { let counter = 0 permissions.value.forEach(permission => { Object.entries(permission).forEach(([key, value]) => { if (key !== 'name' && value) counter++ }) }) return counter }) const isIndeterminate = computed(() => checkedCount.value > 0 && checkedCount.value < permissions.value.length * 3) // select all watch(isSelectAll, val => { permissions.value = permissions.value.map(permission => ({ ...permission, read: val, write: val, create: val, })) }) // if Indeterminate is false, then set isSelectAll to false watch(isIndeterminate, () => { if (!isIndeterminate.value) isSelectAll.value = false }) // if all permissions are checked, then set isSelectAll to true watch(permissions, () => { if (checkedCount.value === permissions.value.length * 3) isSelectAll.value = true }, { deep: true }) // if rolePermissions is not empty, then set permissions watch(() => props, () => { if (props.rolePermissions && props.rolePermissions.permissions.length) { role.value = props.rolePermissions.name permissions.value = permissions.value.map(permission => { const rolePermission = props.rolePermissions?.permissions.find(item => item.name === permission.name) if (rolePermission) { return { ...permission, ...rolePermission, } } return permission }) } }) const onSubmit = () => { const rolePermissions = { name: role.value, permissions: permissions.value, } emit('update:rolePermissions', rolePermissions) emit('update:isDialogVisible', false) isSelectAll.value = false refPermissionForm.value?.reset() } const onReset = () => { emit('update:isDialogVisible', false) isSelectAll.value = false refPermissionForm.value?.reset() } </script> <template> <VDialog :width="$vuetify.display.smAndDown ? 'auto' : 900" :model-value="props.isDialogVisible" @update:model-value="onReset" > <VCard class="pa-sm-8 pa-5"> <!-- 👉 dialog close btn --> <DialogCloseBtn variant="text" size="default" @click="onReset" /> <VCardText class="mt-5"> <!-- 👉 Title --> <div class="text-center mb-6"> <h4 class="text-h4 mb-2"> {{ props.rolePermissions.name ? 'Edit' : 'Add' }} Role </h4> <p class="text-body-1"> {{ props.rolePermissions.name ? 'Edit' : 'Add' }} Role </p> </div> <!-- 👉 Form --> <VForm ref="refPermissionForm"> <!-- 👉 Role name --> <VTextField v-model="role" label="Role Name" placeholder="Enter Role Name" /> <h5 class="text-h5 my-6"> Role Permissions </h5> <!-- 👉 Role Permissions --> <VTable class="permission-table text-no-wrap"> <!-- 👉 Admin --> <tr> <td class="text-h6"> Administrator Access </td> <td colspan="3"> <div class="d-flex justify-end"> <VCheckbox v-model="isSelectAll" v-model:indeterminate="isIndeterminate" label="Select All" /> </div> </td> </tr> <!-- 👉 Other permission loop --> <template v-for="permission in permissions" :key="permission.name" > <tr> <td class="text-h6"> {{ permission.name }} </td> <td style="inline-size: 5.75rem;"> <div class="d-flex justify-end"> <VCheckbox v-model="permission.read" label="Read" /> </div> </td> <td style="inline-size: 5.75rem;"> <div class="d-flex justify-end"> <VCheckbox v-model="permission.write" label="Write" /> </div> </td> <td style="inline-size: 5.75rem;"> <div class="d-flex justify-end"> <VCheckbox v-model="permission.create" label="Create" /> </div> </td> </tr> </template> </VTable> <!-- 👉 Actions button --> <div class="d-flex align-center justify-center gap-3 mt-6"> <VBtn @click="onSubmit"> Submit </VBtn> <VBtn color="secondary" variant="outlined" @click="onReset" > Cancel </VBtn> </div> </VForm> </VCardText> </VCard> </VDialog> </template> <style lang="scss"> .permission-table { td { border-block-end: 1px solid rgba(var(--v-border-color), var(--v-border-opacity)); padding-block: 0.5rem; .v-checkbox { min-inline-size: 4.75rem; } &:not(:first-child) { padding-inline: 0.5rem; } .v-label { white-space: nowrap; } } } </style>