MDK Logo

User management modals

Modal dialogs for user CRUD operations

These modal components handle user creation, editing, and confirmation dialogs. While they are designed to be used within RBACControlSettings the three modal components can stand alone:

  1. AddUserModal: create new users with form validation.
  2. ManageUserModal: edit users and view effective permissions.
  3. ChangeConfirmationModal: confirm destructive or important actions.

AddUserModal

Create new users with form validation.

import { AddUserModal } from '@mdk/foundation'

Props

PropTypeDefaultDescription
openbooleanRequired: Whether the modal is visible
rolesarrayRequired: Available roles for selection
onSubmitfunctionRequired: Called with form data on submit
onClosefunctionRequired: Called when modal should close
isSubmittingbooleanfalseShows loading state on submit button

RoleOption structure

PropertyTypeDescription
valuestringRole identifier
labelstringDisplay name

Callbacks

The onSubmit callback receives the validated form data:

const handleSubmit = async (data) => {
  // data: { name: string, email: string, role: string }
  await api.createUser(data)  // persist to backend
  refetchUsers()               // refresh list
}

The modal resets its form after successful submission.

Example

function UserActions() {
  const [isOpen, setIsOpen] = useState(false)

  const handleSubmit = async (data) => {
    await api.createUser(data)
    setIsOpen(false)
  }

  return (
    <>
      <Button onClick={() => setIsOpen(true)}>Add User</Button>
      <AddUserModal
        open={isOpen}
        onClose={() => setIsOpen(false)}
        roles={[
          { value: 'admin', label: 'Admin' },
          { value: 'operator', label: 'Operator' },
        ]}
        onSubmit={handleSubmit}
      />
    </>
  )
}

Form fields

  • Name: required, trimmed
  • Email: required, must be valid email
  • Role: required, select from available roles

Validation uses Zod schema with react-hook-form. The modal displays Add User and Cancel buttons.

ManageUserModal

Edit existing user details and view their effective permissions.

import { ManageUserModal } from '@mdk/foundation'

Props

PropTypeDefaultDescription
openbooleanRequired: Whether the modal is visible
userSettingsUserRequired: User being edited
rolesarrayRequired: Available roles
rolePermissionsobjectRequired: Permissions by role
permissionLabelsobjectRequired: Permission display names
onSubmitfunctionRequired: Called with updated data on submit
onClosefunctionRequired: Called when modal should close
isSubmittingbooleanfalseShows loading state on submit button

Data structures

The rolePermissions object maps role IDs to their permissions:

const rolePermissions = {
  admin: { users: 'rw', settings: 'rw', reports: 'r' },
  operator: { users: 'r', settings: 'none', reports: 'r' }
}

The permissionLabels object provides display names:

const permissionLabels = {
  users: 'User Management',
  settings: 'System Settings',
  reports: 'Reports'
}

Callbacks

The onSubmit callback receives the updated user data:

const handleSubmit = async (data) => {
  // data: { id: string, name: string, email: string, role: string }
  await api.updateUser(data)  // persist to backend
  refetchUsers()               // refresh list
}

Example

function UserRow({ user }) {
  const [isEditing, setIsEditing] = useState(false)

  const handleSubmit = async (data) => {
    await api.updateUser(data)
    setIsEditing(false)
  }

  return (
    <>
      <Button onClick={() => setIsEditing(true)}>Manage</Button>
      <ManageUserModal
        open={isEditing}
        onClose={() => setIsEditing(false)}
        user={user}
        roles={roles}
        rolePermissions={rolePermissions}
        permissionLabels={permissionLabels}
        onSubmit={handleSubmit}
      />
    </>
  )
}

Sections

The modal is divided into three sections:

  1. User Information: edit name and email.
  2. Assigned Role: select role from dropdown.
  3. Effective Permissions: read-only table showing what the selected role can do.

Permission icons

Permissions display icons based on level:

  • rw: Read/Write (full access)
  • r: Read (view only)
  • none: No access

The modal displays Save Changes and Cancel buttons.

ChangeConfirmationModal

A reusable confirmation dialog for destructive or important actions.

import { ChangeConfirmationModal } from '@mdk/foundation'

Props

PropTypeDefaultDescription
openbooleanRequired: Whether the modal is visible
titlestringRequired: Modal title
childrenReactNodeModal body content
onConfirmfunctionRequired: Called when end user confirms
onClosefunctionRequired: Called when end user cancels or closes
confirmTextstring'Confirm'Text for confirm button
destructivebooleanfalseUse danger styling (red button)

Example

function DeleteButton({ user }) {
  const [showConfirm, setShowConfirm] = useState(false)

  const handleDelete = async () => {
    await api.deleteUser(user.id)
    setShowConfirm(false)
  }

  return (
    <>
      <Button onClick={() => setShowConfirm(true)}>Delete</Button>
      <ChangeConfirmationModal
        open={showConfirm}
        title={`Delete ${user.email}?`}
        onClose={() => setShowConfirm(false)}
        onConfirm={handleDelete}
        confirmText="Delete"
        destructive
      >
        Are you sure you want to delete this user? This action is permanent
        and cannot be undone.
      </ChangeConfirmationModal>
    </>
  )
}

Variants

Standard confirmation

<ChangeConfirmationModal
  title="Save Changes?"
  confirmText="Save"
  destructive={false}
>
  Your changes will be applied immediately.
</ChangeConfirmationModal>

Destructive confirmation

<ChangeConfirmationModal
  title="Delete Item?"
  confirmText="Delete"
  destructive
>
  This action cannot be undone.
</ChangeConfirmationModal>

The modal displays a Cancel button alongside the configurable confirm button.

Dependencies

All user management modals depend on @mdk/core components:

  • Dialog, DialogContent, DialogFooter
  • Button
  • Form, FormInput, FormSelect

They also use:

  • react-hook-form for form state
  • zod for validation
  • @hookform/resolvers for Zod integration

On this page