feat(WEB): 리스트 페이지 권한 시스템 통합 및 중복 권한 로직 제거
- PermissionContext 기능 확장 (권한 조회 액션 추가) - usePermission 훅 개선 - 회계 모듈 권한 통합: 매입/매출/입금/지출/채권/거래처/어음/일보/부실채권 - 인사 모듈 권한 통합: 근태/카드/급여 관리 - 전자결재 권한 통합: 기안함/결재함 - 게시판/품목/단가/팝업/구독 리스트 권한 적용 - UniversalListPage 권한 연동 - 각 컴포넌트 중복 권한 체크 코드 제거 (-828줄) - 권한 검증 QA 체크리스트 추가 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,7 +9,6 @@ import {
|
||||
Clock,
|
||||
FileX,
|
||||
Files,
|
||||
Edit,
|
||||
} from 'lucide-react';
|
||||
import { toast } from 'sonner';
|
||||
import {
|
||||
@@ -75,6 +74,7 @@ import {
|
||||
APPROVAL_STATUS_COLORS,
|
||||
} from './types';
|
||||
import { isNextRedirectError } from '@/lib/utils/redirect-error';
|
||||
import { usePermission } from '@/hooks/usePermission';
|
||||
|
||||
// ===== 통계 타입 =====
|
||||
interface InboxSummary {
|
||||
@@ -87,6 +87,7 @@ interface InboxSummary {
|
||||
export function ApprovalBox() {
|
||||
const router = useRouter();
|
||||
const [isPending, startTransition] = useTransition();
|
||||
const { canApprove } = usePermission();
|
||||
|
||||
// ===== 상태 관리 =====
|
||||
const [activeTab, setActiveTab] = useState<ApprovalTabType>('all');
|
||||
@@ -402,13 +403,6 @@ export function ApprovalBox() {
|
||||
}
|
||||
}, [selectedDocument, router]);
|
||||
|
||||
const handleEditClick = useCallback(
|
||||
(item: ApprovalRecord) => {
|
||||
router.push(`/ko/approval/draft/new?id=${item.id}&mode=edit`);
|
||||
},
|
||||
[router]
|
||||
);
|
||||
|
||||
const handleModalCopy = useCallback(() => {
|
||||
toast.info('문서 복제 기능은 준비 중입니다.');
|
||||
setIsModalOpen(false);
|
||||
@@ -508,7 +502,6 @@ export function ApprovalBox() {
|
||||
{ key: 'approver', label: '결재자' },
|
||||
{ key: 'draftDate', label: '기안일시' },
|
||||
{ key: 'status', label: '상태', className: 'text-center' },
|
||||
{ key: 'actions', label: '작업', className: 'w-[80px] text-center' },
|
||||
],
|
||||
|
||||
tabs: tabs,
|
||||
@@ -591,7 +584,7 @@ export function ApprovalBox() {
|
||||
|
||||
headerActions: ({ selectedItems, onClearSelection }) => (
|
||||
<>
|
||||
{selectedItems.size > 0 && (
|
||||
{selectedItems.size > 0 && canApprove && (
|
||||
<div className="ml-auto flex gap-2">
|
||||
<Button
|
||||
variant="default"
|
||||
@@ -676,18 +669,6 @@ export function ApprovalBox() {
|
||||
{APPROVAL_STATUS_LABELS[item.status]}
|
||||
</Badge>
|
||||
</TableCell>
|
||||
<TableCell className="text-center" onClick={(e) => e.stopPropagation()}>
|
||||
{isSelected && (
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
onClick={() => handleEditClick(item)}
|
||||
title="기안함 수정 페이지로 이동"
|
||||
>
|
||||
<Edit className="h-4 w-4" />
|
||||
</Button>
|
||||
)}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
);
|
||||
},
|
||||
@@ -720,7 +701,7 @@ export function ApprovalBox() {
|
||||
</div>
|
||||
}
|
||||
actions={
|
||||
item.status === 'pending' && isSelected ? (
|
||||
item.status === 'pending' && isSelected && canApprove ? (
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
variant="default"
|
||||
@@ -813,8 +794,8 @@ export function ApprovalBox() {
|
||||
mode="inbox"
|
||||
onEdit={handleModalEdit}
|
||||
onCopy={handleModalCopy}
|
||||
onApprove={handleModalApprove}
|
||||
onReject={handleModalReject}
|
||||
onApprove={canApprove ? handleModalApprove : undefined}
|
||||
onReject={canApprove ? handleModalReject : undefined}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
@@ -834,7 +815,6 @@ export function ApprovalBox() {
|
||||
filterOption,
|
||||
sortOption,
|
||||
handleDocumentClick,
|
||||
handleEditClick,
|
||||
approveDialogOpen,
|
||||
pendingSelectedItems,
|
||||
handleApproveConfirm,
|
||||
@@ -848,6 +828,7 @@ export function ApprovalBox() {
|
||||
handleModalCopy,
|
||||
handleModalApprove,
|
||||
handleModalReject,
|
||||
canApprove,
|
||||
]
|
||||
);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user