RBAC Improvements
Caching improvements Maker-Checker Implementation
This commit is contained in:
@@ -150,7 +150,7 @@ export const evaluateProjectScheduleRisk = (
|
||||
export const ProjectsPage: React.FC = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const { success, error: toastError } = useToast();
|
||||
const { canAdd, canExport } = useRbac();
|
||||
const { canAdd, canApprove, canExport, canApproveRecord, isMaker } = useRbac();
|
||||
|
||||
// Filter & Search States
|
||||
const [searchTerm, setSearchTerm] = useState('');
|
||||
@@ -954,22 +954,41 @@ export const ProjectsPage: React.FC = () => {
|
||||
{/* Governance Status */}
|
||||
<td className="py-4 px-4" onClick={(e) => e.stopPropagation()}>
|
||||
<div className="space-y-1">
|
||||
<select
|
||||
value={p.status}
|
||||
onChange={(e) =>
|
||||
statusMutation.mutate({
|
||||
projectId: p.id,
|
||||
status: Number(e.target.value) as ApprovalStatus,
|
||||
})
|
||||
}
|
||||
className="text-xs font-semibold bg-[#090d16] border border-slate-700/80 rounded-xl px-2.5 py-1 text-slate-200 focus:outline-none focus:ring-1 focus:ring-blue-500 cursor-pointer"
|
||||
>
|
||||
{APPROVAL_STATUS_OPTIONS.map((opt) => (
|
||||
<option key={opt.value} value={opt.value}>
|
||||
{opt.label}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
{(() => {
|
||||
const canApproveThis = canApproveRecord('projects_milestones', p.createdBy);
|
||||
const isSelf = isMaker(p.createdBy);
|
||||
const canModifyStatus = canAdd('projects_milestones') || canApprove('projects_milestones');
|
||||
|
||||
return (
|
||||
<select
|
||||
value={p.status}
|
||||
disabled={!canModifyStatus}
|
||||
onChange={(e) =>
|
||||
statusMutation.mutate({
|
||||
projectId: p.id,
|
||||
status: Number(e.target.value) as ApprovalStatus,
|
||||
})
|
||||
}
|
||||
className="text-xs font-semibold bg-[#090d16] border border-slate-700/80 rounded-xl px-2.5 py-1 text-slate-200 focus:outline-none focus:ring-1 focus:ring-blue-500 cursor-pointer disabled:opacity-60 disabled:cursor-not-allowed"
|
||||
>
|
||||
{APPROVAL_STATUS_OPTIONS.map((opt) => {
|
||||
const isApprovedOpt = opt.value === ApprovalStatus.Approved;
|
||||
const isOptDisabled = isApprovedOpt && !canApproveThis;
|
||||
let reasonText = '';
|
||||
if (isApprovedOpt && !canApprove('projects_milestones')) {
|
||||
reasonText = ' (Requires Update Permission)';
|
||||
} else if (isApprovedOpt && isSelf) {
|
||||
reasonText = ' (Maker-Checker: Cannot approve own record)';
|
||||
}
|
||||
return (
|
||||
<option key={opt.value} value={opt.value} disabled={isOptDisabled}>
|
||||
{opt.label}{reasonText}
|
||||
</option>
|
||||
);
|
||||
})}
|
||||
</select>
|
||||
);
|
||||
})()}
|
||||
</div>
|
||||
</td>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user