Files
emaui/apps/backoffice/src/app/features/question/pages/QuestionPage/actions.tsx
mihretue ae3af7777e fix(exam,result,question): kebab-icon action menus, status change as a picker
Two follow-ups on the dropdown-actions pass:
- All four action menus (exams, results, questions, candidates panel) now
  trigger off a plain three-dot icon button instead of a text 'Actions'
  button with a chevron.
- Exam status change no longer lists all six statuses flat in the dropdown
  (bad UX, looked like six always-visible options). 'Status' is now one
  menu item that opens a small picker modal (current status + a Select +
  Update) rather than the full edit form.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-18 11:46:16 +00:00

92 lines
3.3 KiB
TypeScript

import { ActionIcon, Menu } from '@mantine/core';
import {
IconDotsVertical,
IconEdit,
IconGavel,
IconSend,
IconTrash,
} from '@tabler/icons-react';
import type { TFunction } from 'i18next';
import type { AdvancedColumn } from '@ema-platform/ui';
import { LICENSE_PERMISSIONS, RequirePermission } from '@ema-platform/auth';
import type { Question } from '../../types/question';
export function questionActionsColumn(
t: TFunction,
handlers: {
isSubmittingReview: boolean;
onSubmitForApproval: (question: Question) => void;
onReview: (question: Question, outcome: 'APPROVED' | 'REJECTED' | 'RETIRED') => void;
onEdit: (question: Question) => void;
onDelete: (question: Question) => void;
},
): AdvancedColumn<Question> {
return {
header: '',
label: t('question.columns.actions', 'Actions'),
cell: ({ row }) => {
const q = row.original;
return (
<Menu shadow="md" width={180} position="bottom-end">
<Menu.Target>
<ActionIcon
variant="subtle"
color="gray"
size="sm"
loading={handlers.isSubmittingReview}
>
<IconDotsVertical size={16} />
</ActionIcon>
</Menu.Target>
<Menu.Dropdown>
{(q.status === 'DRAFT' || q.status === 'REJECTED') && (
<RequirePermission anyOf={[LICENSE_PERMISSIONS.AUTHOR_QUESTION]} hideOnly>
<Menu.Item
leftSection={<IconSend size={14} />}
onClick={() => handlers.onSubmitForApproval(q)}
>
{t('question.qc.submit')}
</Menu.Item>
</RequirePermission>
)}
{q.status === 'PENDING_APPROVAL' && (
<RequirePermission anyOf={[LICENSE_PERMISSIONS.APPROVE_QUESTION]} hideOnly>
<Menu.Item color="teal" onClick={() => handlers.onReview(q, 'APPROVED')}>
{t('question.qc.approve')}
</Menu.Item>
<Menu.Item color="red" onClick={() => handlers.onReview(q, 'REJECTED')}>
{t('question.qc.reject')}
</Menu.Item>
</RequirePermission>
)}
{q.status === 'APPROVED' && (
<RequirePermission anyOf={[LICENSE_PERMISSIONS.APPROVE_QUESTION]} hideOnly>
<Menu.Item
color="dark"
leftSection={<IconGavel size={14} />}
onClick={() => handlers.onReview(q, 'RETIRED')}
>
{t('question.qc.retire')}
</Menu.Item>
</RequirePermission>
)}
<RequirePermission anyOf={[LICENSE_PERMISSIONS.AUTHOR_QUESTION]} hideOnly>
<Menu.Divider />
<Menu.Item leftSection={<IconEdit size={14} />} onClick={() => handlers.onEdit(q)}>
{t('question.action.edit', 'Edit')}
</Menu.Item>
<Menu.Item
color="red"
leftSection={<IconTrash size={14} />}
onClick={() => handlers.onDelete(q)}
>
{t('question.action.delete', 'Delete')}
</Menu.Item>
</RequirePermission>
</Menu.Dropdown>
</Menu>
);
},
};
}