Skip to content

Commit

Permalink
#2943 - replaced mdgConfirm with RemovalValidation
Browse files Browse the repository at this point in the history
  • Loading branch information
rmmayo committed Nov 11, 2024
1 parent e6c4b70 commit b80ecfd
Show file tree
Hide file tree
Showing 3 changed files with 363 additions and 175 deletions.
349 changes: 184 additions & 165 deletions dashboard/src/components/access/RoleManager.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { userErrorState } from '@/stores/UserErrorState.js'
import { useDialogMessages } from '@/components/utils/modal/UseDialogMessages.js'
import { useUpgradeInProgressErrorChecker } from '@/components/utils/errors/UseUpgradeInProgressErrorChecker.js'
import QuizService from '@/components/quiz/QuizService.js';
import RemovalValidation from '@/components/utils/modal/RemovalValidation.vue';
const dialogMessages = useDialogMessages()
// role constants
Expand Down Expand Up @@ -117,7 +118,10 @@ const userRole = ref({
selected: null,
options: props.roles.map((role) => ({ value: role, text: getRoleDisplay(role) })),
});
const removeRoleInfo = ref({
showDialog: false,
userInfo: {}
})
const data = computed(() => {
const groupRows = adminGroupsSupported.value ? assignedAdminGroups.value.map((g) => {
return {
Expand Down Expand Up @@ -306,20 +310,13 @@ function notCurrentUser(userId) {
}
function deleteUserRoleConfirm(row) {
const msg = `Are you absolutely sure you want to remove ${getUserDisplay(row)} as a ${props.roleDescription}?`;
dialogMessages.msgConfirm({
message: msg,
header: 'Please Confirm!',
acceptLabel: 'YES, Delete It',
accept: () => {
deleteUserRole(row);
}
});
removeRoleInfo.value.userInfo = row
removeRoleInfo.value.showDialog = true
}
function deleteUserRole(row) {
function doDeleteUserRole() {
isLoading.value = true;
const row = removeRoleInfo.value.userInfo;
if (props.quizId) {
deleteQuizAdminUserRole(row)
} else {
Expand Down Expand Up @@ -422,172 +419,194 @@ defineExpose({
</script>
<template>
<Card :pt="{ body: { class: 'p-0' }, content: { class: 'p-0' } }">
<template #header>
<SkillsCardHeader v-if="title" :title="title"></SkillsCardHeader>
</template>
<template #content>
<slot name="underHeader"/>
<div>
<div class="p-3">
<div>
<existing-user-input :suggest="true" :validate="true" :user-type="userType" :excluded-suggestions="assignedUserIds"
v-model="selectedUser" data-cy="existingUserInput" />
</div>
<div class="mt-3 mb-3 flex gap-2 flex-column sm:flex-row">
<div v-if="!isOnlyOneRole" class="flex-1">
<Dropdown class="w-full" v-model="userRole.selected" :options="userRole.options" data-cy="userRoleSelector"
placeholder="Please select user's Role" optionLabel="text" optionValue="value" />
</div>
<div>
<Card :pt="{ body: { class: 'p-0' }, content: { class: 'p-0' } }">
<template #header>
<SkillsCardHeader v-if="title" :title="title"></SkillsCardHeader>
</template>
<template #content>
<slot name="underHeader"/>
<div>
<div class="p-3">
<div>
<SkillsButton variant="outline-hc" @click="addUserRole" :disabled="addUsrBtnDisabled" data-cy="addUserBtn"
label="Add User" id="addUserBtn" :track-for-focus="true"
:icon="isSaving ? 'fa fa-circle-notch fa-spin fa-3x-fa-fw' : 'fas fa-arrow-circle-right'">
</SkillsButton>
<existing-user-input :suggest="true" :validate="true" :user-type="userType"
:excluded-suggestions="assignedUserIds"
v-model="selectedUser" data-cy="existingUserInput"/>
</div>
</div>
<div v-if="adminGroupsSupported">
<div class="text-center my-4 font-semibold">
OR
<div class="mt-3 mb-3 flex gap-2 flex-column sm:flex-row">
<div v-if="!isOnlyOneRole" class="flex-1">
<Dropdown class="w-full" v-model="userRole.selected" :options="userRole.options"
data-cy="userRoleSelector"
placeholder="Please select user's Role" optionLabel="text" optionValue="value"/>
</div>
<div>
<SkillsButton variant="outline-hc" @click="addUserRole" :disabled="addUsrBtnDisabled"
data-cy="addUserBtn"
label="Add User" id="addUserBtn" :track-for-focus="true"
:icon="isSaving ? 'fa fa-circle-notch fa-spin fa-3x-fa-fw' : 'fas fa-arrow-circle-right'">
</SkillsButton>
</div>
</div>
<div>
<Dropdown
class="w-full"
aria-label="Select Admin Group to add to a Project"
data-cy="adminGroupSelector"
showClear
filter
placeholder="Please select Admin Group"
optionLabel="name"
@update:modelValue="addProjectOrQuizToAdminGroup"
:emptyMessage=emptyAdminGroupsMessage
:options="availableAdminGroups">
<template #value="slotProps">
<div v-if="slotProps.value" class="p-1" :data-cy="`adminGroupSelected-${slotProps.value.projectId}`">
<span class="ml-1">{{ slotProps.value.name }}</span>
</div>
<span v-else> Search available admin groups...</span>
</template>
<template #option="slotProps">
<div :data-cy="`availableAdminGroupSelection-${slotProps.option.projectId}`">
<span class="h6 ml-2">{{ slotProps.option.name }}</span>
</div>
</template>
</Dropdown>
<div v-if="adminGroupsSupported">
<div class="text-center my-4 font-semibold">
OR
</div>
<div>
<Dropdown
class="w-full"
:aria-label="`Select Admin Group to assign to this ${props.projectId ? 'Project' : 'Quiz'}`"
data-cy="adminGroupSelector"
showClear
filter
placeholder="Please select Admin Group"
optionLabel="name"
@update:modelValue="addProjectOrQuizToAdminGroup"
:emptyMessage=emptyAdminGroupsMessage
:options="availableAdminGroups">
<template #value="slotProps">
<div v-if="slotProps.value" class="p-1"
:data-cy="`adminGroupSelected-${slotProps.value.adminGroupId}`">
<span class="ml-1">{{ slotProps.value.name }}</span>
</div>
<span v-else> Search available admin groups...</span>
</template>
<template #option="slotProps">
<div :data-cy="`availableAdminGroupSelection-${slotProps.option.adminGroupId}`">
<span class="h6 ml-2">{{ slotProps.option.name }}</span>
</div>
</template>
</Dropdown>
</div>
</div>
</div>
<Message v-if="errNotification.enable" severity="error" data-cy="error-msg">
<strong>Error!</strong> Request could not be completed! {{ errNotification.msg }}
</Message>
</div>
<SkillsDataTable
:loading="isLoading"
:value="data"
:rowsPerPageOptions="possiblePageSizes"
data-cy="roleManagerTable"
tableStoredStateId="roleManagerTableSort"
aria-label="User Roles"
striped-rows
paginator
:pt:paginator:paginatorWrapper:aria-label='`${title} Paginator`'
:row-class="showExpansion"
v-model:expandedRows="expandedRows"
v-model:sort-field="sortInfo.sortBy"
v-model:sort-order="sortInfo.sortOrder"
:rows="pageSize">
<Column v-if="adminGroupsSupported" expander style="width: 5rem" :showFilterMenu="false" :class="{'flex': responsive.md.value }">
<template #header>
<span class="sr-only">Rows expand and collapse control - Not sortable</span>
</template>
<template #filter>
<span class="sr-only">Rows expand and collapse control - No filtering</span>
</template>
</Column>
<Column :header="roleDescription" field="userId" sortable :class="{'flex': responsive.md.value }">
<template #header>
<Message v-if="errNotification.enable" severity="error" data-cy="error-msg">
<strong>Error!</strong> Request could not be completed! {{ errNotification.msg }}
</Message>
</div>
<SkillsDataTable
:loading="isLoading"
:value="data"
:rowsPerPageOptions="possiblePageSizes"
data-cy="roleManagerTable"
tableStoredStateId="roleManagerTableSort"
aria-label="User Roles"
striped-rows
paginator
:pt:paginator:paginatorWrapper:aria-label='`${title} Paginator`'
:row-class="showExpansion"
v-model:expandedRows="expandedRows"
v-model:sort-field="sortInfo.sortBy"
v-model:sort-order="sortInfo.sortOrder"
:rows="pageSize">
<Column v-if="adminGroupsSupported" expander style="width: 5rem" :showFilterMenu="false"
:class="{'flex': responsive.md.value }">
<template #header>
<span class="sr-only">Rows expand and collapse control - Not sortable</span>
</template>
<template #filter>
<span class="sr-only">Rows expand and collapse control - No filtering</span>
</template>
</Column>
<Column :header="roleDescription" field="userId" sortable :class="{'flex': responsive.md.value }">
<template #header>
<span class="mr-2"><i class="fas fa-user skills-color-users" :class="colors.getTextClass(0)"
aria-hidden="true"></i> </span>
</template>
<template #body="slotProps">
<div v-if="slotProps.data.adminGroupId && !props.adminGroupId">
<i class="fas fa-layer-group" aria-hidden="true"></i> <span class="uppercase">Admin Group</span>
<Tag class="uppercase ml-2" data-cy="numMembersInGroup">
{{ slotProps.data.numberOfMembers + slotProps.data.numberOfOwners }}
member{{ slotProps.data.numberOfMembers + slotProps.data.numberOfOwners !== 1 ? 's' : '' }}
</Tag>
</div>
<div :data-cy="`userCell_${slotProps.data.userId}`">
{{ getUserDisplay(slotProps.data) }}
</div>
</template>
</Column>
<Column header="Role" v-if="!props.quizId" field="roleName" sortable :class="{'flex': responsive.md.value }">
<template #header>
</template>
<template #body="slotProps">
<div v-if="slotProps.data.adminGroupId && !props.adminGroupId">
<i class="fas fa-layer-group" aria-hidden="true"></i> <span class="uppercase">Admin Group</span>
<Tag class="uppercase ml-2" data-cy="numMembersInGroup">
{{ slotProps.data.numberOfMembers + slotProps.data.numberOfOwners }}
member{{ slotProps.data.numberOfMembers + slotProps.data.numberOfOwners !== 1 ? 's' : '' }}
</Tag>
</div>
<div :data-cy="`userCell_${slotProps.data.userId}`">
{{ getUserDisplay(slotProps.data) }}
</div>
</template>
</Column>
<Column header="Role" v-if="!props.quizId" field="roleName" sortable
:class="{'flex': responsive.md.value }">
<template #header>
<span class="mr-2"><i class="fas fa-id-card text-danger" :class="colors.getTextClass(1)"
aria-hidden="true"></i> </span>
</template>
<template #body="slotProps">
<div v-if="!slotProps.data.isEdited">{{ getRoleDisplay(slotProps.data.roleName) }}</div>
<Dropdown v-else v-model="slotProps.data.roleName"
:options="userRole.options"
optionLabel="text"
optionValue="value"
:aria-label="`select new access role for user ${getUserDisplay(slotProps.data)}`"
:data-cy="`roleDropDown_${slotProps.data.userId}`"
@change="updateUserRole">
</Dropdown>
</template>
</Column>
<Column :class="{'flex': responsive.md.value }">
<template #header>
<span class="sr-only">Controls - Not sortable</span>
</template>
<template #body="slotProps">
<div v-if="!slotProps.data.adminGroupId || props.adminGroupId">
<div class="float-right mr-1 flex gap-2" :data-cy="`controlsCell_${slotProps.data.userId}`">
<!-- <i v-if="!notCurrentUser(slotProps.data.userId)"-->
<!-- data-cy="cannotRemoveWarning"-->
<!-- class="text-warning fas fa-exclamation-circle mr-1"-->
<!-- aria-hidden="true"/>-->
<SkillsButton v-if="!isOnlyOneRole" @click="editItem(slotProps.data)"
:disabled="!notCurrentUser(slotProps.data.userId)"
:aria-label="`edit access role from user ${getUserDisplay(slotProps.data)}`"
data-cy="editUserBtn" icon="fas fa-edit" label="Edit" size="small">
</SkillsButton>
<SkillsButton @click="deleteUserRoleConfirm(slotProps.data)"
:disabled="!notCurrentUser(slotProps.data.userId)"
:id="`removeUserBtn_${slotProps.data.userId}`"
:track-for-focus="true"
:aria-label="`remove access role from user ${getUserDisplay(slotProps.data)}`"
data-cy="removeUserBtn" icon="fas fa-trash" label="Delete" size="small">
</SkillsButton>
</div>
<InlineMessage v-if="!notCurrentUser(slotProps.data.userId)" class="mt-1" severity="info"
aria-live="polite">
Can't remove or edit yourself
</InlineMessage>
</div>
</template>
</Column>
<template #expansion="slotProps">
<ul data-cy="userGroupMembers">
<li v-for="groupMember in slotProps.data.allMembers" class="m-2"
:data-cy="`userGroupMember_${groupMember.userId}`">
{{ getUserDisplay(groupMember) }}
</li>
</ul>
</template>
<template #body="slotProps">
<div v-if="!slotProps.data.isEdited">{{ getRoleDisplay(slotProps.data.roleName) }}</div>
<Dropdown v-else v-model="slotProps.data.roleName"
:options="userRole.options"
optionLabel="text"
optionValue="value"
:aria-label="`select new access role for user ${getUserDisplay(slotProps.data)}`"
:data-cy="`roleDropDown_${slotProps.data.userId}`"
@change="updateUserRole">
</Dropdown>
<template #paginatorstart>
<span>Total Rows:</span> <span class="font-semibold" data-cy=skillsBTableTotalRows>{{
data.length
}}</span>
</template>
</Column>
<Column :class="{'flex': responsive.md.value }">
<template #header>
<span class="sr-only">Controls - Not sortable</span>
<template #empty>
<span class="flex align-items-center justify-content-center">There are no records to show</span>
</template>
<template #body="slotProps">
<div v-if="!slotProps.data.adminGroupId || props.adminGroupId">
<div class="float-right mr-1 flex gap-2" :data-cy="`controlsCell_${slotProps.data.userId}`">
<!-- <i v-if="!notCurrentUser(slotProps.data.userId)"-->
<!-- data-cy="cannotRemoveWarning"-->
<!-- class="text-warning fas fa-exclamation-circle mr-1"-->
<!-- aria-hidden="true"/>-->
<SkillsButton v-if="!isOnlyOneRole" @click="editItem(slotProps.data)"
:disabled="!notCurrentUser(slotProps.data.userId)"
:aria-label="`edit access role from user ${getUserDisplay(slotProps.data)}`"
data-cy="editUserBtn" icon="fas fa-edit" label="Edit" size="small">
</SkillsButton>
<SkillsButton @click="deleteUserRoleConfirm(slotProps.data)"
:disabled="!notCurrentUser(slotProps.data.userId)"
:id="`removeUserBtn_${slotProps.data.userId}`"
:track-for-focus="true"
:aria-label="`remove access role from user ${getUserDisplay(slotProps.data)}`"
data-cy="removeUserBtn" icon="fas fa-trash" label="Delete" size="small">
</SkillsButton>
</SkillsDataTable>
</div>
</template>
</Card>
<RemovalValidation
v-if="removeRoleInfo.showDialog"
v-model="removeRoleInfo.showDialog"
@do-remove="doDeleteUserRole"
:item-name="removeRoleInfo.userInfo.userIdForDisplay"
item-type="from having admin privileges"
:enable-return-focus="true">
</RemovalValidation>
</div>
</div>
<InlineMessage v-if="!notCurrentUser(slotProps.data.userId)" class="mt-1" severity="info" aria-live="polite">
Can't remove or edit yourself
</InlineMessage>
</div>
</template>
</Column>
<template #expansion="slotProps">
<ul>
<li v-for="groupMember in slotProps.data.allMembers" class="m-2">
{{ getUserDisplay(groupMember) }}
</li>
</ul>
</template>
<template #paginatorstart>
<span>Total Rows:</span> <span class="font-semibold" data-cy=skillsBTableTotalRows>{{ data.length }}</span>
</template>
<template #empty>
<span class="flex align-items-center justify-content-center">There are no records to show</span>
</template>
</SkillsDataTable>
</div>
</template>
</Card>
</template>
<style>
Expand Down
Loading

0 comments on commit b80ecfd

Please sign in to comment.