feat(rbac): enforce procurement write restrictions and support supervisor role in SSO

This commit is contained in:
2026-09-26 12:32:01 +03:30
parent 730d0bd496
commit 5a9b543040
31 changed files with 480 additions and 139 deletions
+20 -15
View File
@@ -24,6 +24,7 @@ export interface QuoteCardProps {
onToggleExpand: () => void;
onAccept: () => void;
onEdit: () => void;
canWrite?: boolean;
}
function InfoCell({ label, children, className }: { label: string; children: React.ReactNode; className?: string }) {
@@ -35,7 +36,7 @@ function InfoCell({ label, children, className }: { label: string; children: Rea
);
}
export function QuoteCard({ store, q, expanded, onToggleExpand, onAccept, onEdit }: QuoteCardProps) {
export function QuoteCard({ store, q, expanded, onToggleExpand, onAccept, onEdit, canWrite = true }: QuoteCardProps) {
const sup = supplierById(store.suppliers, q.supplier_id);
const expired = isExpired(q);
const total = quoteTotal(q);
@@ -46,7 +47,7 @@ export function QuoteCard({ store, q, expanded, onToggleExpand, onAccept, onEdit
// ستون / دکمه پذیرش
let acceptedCell: React.ReactNode;
if (q.status === "offered") {
acceptedCell = (
acceptedCell = canWrite ? (
<button
onClick={(e) => {
e.stopPropagation();
@@ -57,6 +58,8 @@ export function QuoteCard({ store, q, expanded, onToggleExpand, onAccept, onEdit
<Check className="h-3.5 w-3.5" />
<span>پذیرش</span>
</button>
) : (
<span className="text-muted text-xs font-medium">در انتظار پذیرش</span>
);
} else if (q.accepted_date) {
acceptedCell = <span className="tabular-nums font-medium">{fmtDateTime(q.accepted_date)}</span>;
@@ -185,19 +188,21 @@ export function QuoteCard({ store, q, expanded, onToggleExpand, onAccept, onEdit
)}
{/* دکمه ویرایش */}
<button
type="button"
className="inline-flex h-7 items-center justify-center gap-1 rounded-md border border-line bg-panel px-2 text-xs font-medium text-ink hover:bg-slate-50 dark:hover:bg-zinc-800 transition-colors sm:h-8 sm:px-2.5"
onClick={(e) => {
e.stopPropagation();
onEdit();
}}
title="ویرایش پیشنهاد"
aria-label="ویرایش"
>
<Pencil className="h-3 w-3 text-muted" />
<span className="hidden sm:inline">ویرایش</span>
</button>
{canWrite && (
<button
type="button"
className="inline-flex h-7 items-center justify-center gap-1 rounded-md border border-line bg-panel px-2 text-xs font-medium text-ink hover:bg-slate-50 dark:hover:bg-zinc-800 transition-colors sm:h-8 sm:px-2.5"
onClick={(e) => {
e.stopPropagation();
onEdit();
}}
title="ویرایش پیشنهاد"
aria-label="ویرایش"
>
<Pencil className="h-3 w-3 text-muted" />
<span className="hidden sm:inline">ویرایش</span>
</button>
)}
{/* دکمه فلش اکسپند در هدر */}
<button