Format procurement and finance screens for quality gate

This commit is contained in:
lizerk 2026-11-10 17:52:53 +03:00
parent 3dab4b5118
commit b72ac5dd0d
3 changed files with 68 additions and 45 deletions

View File

@ -159,9 +159,9 @@ const canConfirmAllReceived = (
);
return Boolean(
isAuthor &&
itemsCount > 0 &&
request.fulfillment_status !== "completed" &&
["waiting", "in_progress"].includes(status),
itemsCount > 0 &&
request.fulfillment_status !== "completed" &&
["waiting", "in_progress"].includes(status),
);
};
@ -308,7 +308,7 @@ function ProcurementRequestActionButtons({
const isInProgress = status === "in_progress";
const canNotifyArrival = Boolean(
request.can_current_user_process_items &&
(status === "waiting" || status === "in_progress"),
(status === "waiting" || status === "in_progress"),
);
const canConfirmRequestReceived = canConfirmAllReceived(request, isAuthor);
const startWorkLabel = request.executor
@ -663,9 +663,9 @@ export default function ProcurementPage() {
return Boolean(
request.can_current_user_submit_for_approval &&
user?.id &&
processingDepartmentId &&
isProcessingDepartmentMember,
user?.id &&
processingDepartmentId &&
isProcessingDepartmentMember,
);
},
[user?.id, userDepartmentIds, userDepartmentsKnown],
@ -1856,7 +1856,11 @@ export default function ProcurementPage() {
>
<Flag
size={15}
className={req.is_deferred ? "text-red-500" : "text-sky-500"}
className={
req.is_deferred
? "text-red-500"
: "text-sky-500"
}
fill={req.is_deferred ? "currentColor" : "none"}
/>
</button>
@ -1947,7 +1951,11 @@ export default function ProcurementPage() {
>
<Flag
size={15}
className={selectedRequest.is_deferred ? "text-red-500" : "text-sky-500"}
className={
selectedRequest.is_deferred
? "text-red-500"
: "text-sky-500"
}
fill={
selectedRequest.is_deferred
? "currentColor"
@ -2077,15 +2085,15 @@ export default function ProcurementPage() {
)}
isAuthor={Boolean(
resolveUserId(selectedRequest.requestor) &&
user?.id &&
resolveUserId(selectedRequest.requestor) ===
user.id,
user?.id &&
resolveUserId(selectedRequest.requestor) ===
user.id,
)}
isExecutor={Boolean(
resolveUserId(selectedRequest.executor) &&
user?.id &&
resolveUserId(selectedRequest.executor) ===
user.id,
user?.id &&
resolveUserId(selectedRequest.executor) ===
user.id,
)}
isFinal={isFinal}
showLabels
@ -2182,9 +2190,9 @@ export default function ProcurementPage() {
).map((comment) => {
const canDeleteCommentThis = Boolean(
comment.author?.id &&
(user?.id === comment.author.id ||
user?.auth?.is_staff ||
user?.auth?.is_superuser),
(user?.id === comment.author.id ||
user?.auth?.is_staff ||
user?.auth?.is_superuser),
);
return (
<div
@ -2260,13 +2268,13 @@ export default function ProcurementPage() {
const urg = urgencyMeta[req.urgency] ?? urgencyMeta.medium;
const isAuthor = Boolean(
resolveUserId(req.requestor) &&
user?.id &&
resolveUserId(req.requestor) === user.id,
user?.id &&
resolveUserId(req.requestor) === user.id,
);
const isExecutor = Boolean(
resolveUserId(req.executor) &&
user?.id &&
resolveUserId(req.executor) === user.id,
user?.id &&
resolveUserId(req.executor) === user.id,
);
const isEditableStatus =
(st === "draft" || st === "waiting") && !req.executor;
@ -2274,7 +2282,7 @@ export default function ProcurementPage() {
const resolvedDetail = detail || req;
const canApproveThis = Boolean(
resolvedDetail.can_current_user_approve ??
req.can_current_user_approve,
req.can_current_user_approve,
);
const canSubmitThis =
canCurrentUserSubmitRequest(resolvedDetail);
@ -2291,11 +2299,11 @@ export default function ProcurementPage() {
);
const hasInlineRequestActions = Boolean(
canSubmitThis ||
canApproveThis ||
(resolvedDetail.can_current_user_start_work ??
req.can_current_user_start_work) ||
(st === "in_progress" && isExecutor) ||
canConfirmAllReceivedThis,
canApproveThis ||
(resolvedDetail.can_current_user_start_work ??
req.can_current_user_start_work) ||
(st === "in_progress" && isExecutor) ||
canConfirmAllReceivedThis,
);
const expanded = expandedIds.has(req.id);
const comments = commentsMap[req.id] || [];
@ -2591,7 +2599,11 @@ export default function ProcurementPage() {
>
<Flag
size={15}
className={req.is_deferred ? "text-red-500" : "text-sky-500"}
className={
req.is_deferred
? "text-red-500"
: "text-sky-500"
}
fill={
req.is_deferred
? "currentColor"
@ -2902,9 +2914,9 @@ export default function ProcurementPage() {
(comment) => {
const canDeleteCommentThis = Boolean(
comment.author?.id &&
(user?.id === comment.author.id ||
user?.auth?.is_staff ||
user?.auth?.is_superuser),
(user?.id === comment.author.id ||
user?.auth?.is_staff ||
user?.auth?.is_superuser),
);
return (
<div
@ -2956,7 +2968,7 @@ export default function ProcurementPage() {
busyKey={busyKey}
canDeleteAnyComment={Boolean(
user?.auth?.is_staff ||
user?.auth?.is_superuser,
user?.auth?.is_superuser,
)}
onUpdateItem={handleUpdateItem}
onReportItemIssue={handleReportItemIssue}
@ -3061,13 +3073,13 @@ export default function ProcurementPage() {
)}
isAuthor={Boolean(
resolveUserId(selectedRequest.requestor) &&
user?.id &&
resolveUserId(selectedRequest.requestor) === user.id,
user?.id &&
resolveUserId(selectedRequest.requestor) === user.id,
)}
isExecutor={Boolean(
resolveUserId(selectedRequest.executor) &&
user?.id &&
resolveUserId(selectedRequest.executor) === user.id,
user?.id &&
resolveUserId(selectedRequest.executor) === user.id,
)}
isFinal={isFinal}
showLabels
@ -3267,9 +3279,9 @@ export default function ProcurementPage() {
).map((comment) => {
const canDeleteCommentThis = Boolean(
comment.author?.id &&
(user?.id === comment.author.id ||
user?.auth?.is_staff ||
user?.auth?.is_superuser),
(user?.id === comment.author.id ||
user?.auth?.is_staff ||
user?.auth?.is_superuser),
);
return (
<div

View File

@ -681,7 +681,9 @@ export function PayrollAdminWorkspace({
const [tableVersion, setTableVersion] = useState(0);
const [notice, setNotice] = useState<string | null>(null);
const [workEntryLockBusy, setWorkEntryLockBusy] = useState(false);
const [workEntryLockError, setWorkEntryLockError] = useState<string | null>(null);
const [workEntryLockError, setWorkEntryLockError] = useState<string | null>(
null,
);
const [periodModalOpen, setPeriodModalOpen] = useState(false);
const [editingPeriod, setEditingPeriod] = useState<PayrollAdminPeriod | null>(
@ -1770,7 +1772,10 @@ export function PayrollAdminWorkspace({
);
} catch (error) {
setWorkEntryLockError(
getPayrollAdminError(error, "Не удалось изменить доступ к выработке."),
getPayrollAdminError(
error,
"Не удалось изменить доступ к выработке.",
),
);
} finally {
setWorkEntryLockBusy(false);
@ -1894,7 +1899,10 @@ export function PayrollAdminWorkspace({
) : null}
{workEntryLockError ? (
<div role="alert" className="app-feedback-danger rounded-xl px-4 py-3 text-sm">
<div
role="alert"
className="app-feedback-danger rounded-xl px-4 py-3 text-sm"
>
{workEntryLockError}
</div>
) : null}

View File

@ -2390,7 +2390,8 @@ export function PayrollPeriodTableView({
columnId: string,
columnLabel: string,
) => ({
commentPreview: commentPreviewByCell.get(commentCellKey(row.employee.id, columnId)) || "",
commentPreview:
commentPreviewByCell.get(commentCellKey(row.employee.id, columnId)) || "",
commentCount:
commentCountByCell.get(commentCellKey(row.employee.id, columnId)) || 0,
onOpenComment: () =>
@ -3779,7 +3780,9 @@ export function PayrollPeriodTableView({
style={{ left: REVIEW_MARK_COLUMN_WIDTH }}
>
<CellCommentButton
preview={commentPreviewByCell.get(commentCellKey(row.employee.id, "employee"))}
preview={commentPreviewByCell.get(
commentCellKey(row.employee.id, "employee"),
)}
count={
commentCountByCell.get(
commentCellKey(row.employee.id, "employee"),