feat(procurement): 統一採購單按鈕樣式與術語更名為「作廢」,並加強權限控管
This commit is contained in:
@@ -46,6 +46,8 @@ export default function PermissionSelector({ groupedPermissions, selectedPermiss
|
||||
'view_cost': '檢視成本',
|
||||
'view_logs': '檢視日誌',
|
||||
'activate': '啟用/停用',
|
||||
'approve': '核准/退回',
|
||||
'cancel': '取消',
|
||||
};
|
||||
|
||||
const actionText = map[action] || action;
|
||||
@@ -203,6 +205,11 @@ export default function PermissionSelector({ groupedPermissions, selectedPermiss
|
||||
const totalCount = group.permissions.length;
|
||||
const isAllSelected = selectedCount === totalCount;
|
||||
|
||||
// 將權限分為「基本操作」與「狀態/進階操作」
|
||||
const statusActions = ['approve', 'cancel', 'complete', 'activate'];
|
||||
const normalPermissions = group.permissions.filter(p => !statusActions.includes(p.name.split('.').pop() || ''));
|
||||
const specialPermissions = group.permissions.filter(p => statusActions.includes(p.name.split('.').pop() || ''));
|
||||
|
||||
return (
|
||||
<AccordionItem
|
||||
key={group.key}
|
||||
@@ -210,18 +217,11 @@ export default function PermissionSelector({ groupedPermissions, selectedPermiss
|
||||
className="bg-white border rounded-lg px-2 data-[state=open]:bg-gray-50/50 last:border-b"
|
||||
>
|
||||
<div className="flex items-center w-full">
|
||||
{/* Group Selection Checkbox - Moved outside trigger to avoid bubbling issues, positioned left */}
|
||||
<div className="flex items-center pl-2 pr-1">
|
||||
<Checkbox
|
||||
id={`group-select-${group.key}`}
|
||||
checked={isAllSelected}
|
||||
onCheckedChange={() => {
|
||||
// Stop propagation to prevent accordion from toggling
|
||||
// This is implicitly handled by the checkbox being a sibling,
|
||||
// but if it were a child of AccordionTrigger, stopPropagation would be needed.
|
||||
// For clarity, we can add it here if needed, but the current structure makes it unnecessary.
|
||||
toggleGroup(group.permissions);
|
||||
}}
|
||||
onCheckedChange={() => toggleGroup(group.permissions)}
|
||||
className="data-[state=checked]:bg-primary-main"
|
||||
/>
|
||||
</div>
|
||||
@@ -241,30 +241,47 @@ export default function PermissionSelector({ groupedPermissions, selectedPermiss
|
||||
</AccordionTrigger>
|
||||
</div>
|
||||
<AccordionContent className="px-2 pb-4">
|
||||
<div className="pl-10 space-y-3 pt-1">
|
||||
{/* Permissions Grid */}
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-y-3 gap-x-4">
|
||||
{group.permissions.map((permission) => (
|
||||
<div key={permission.id} className="flex items-start space-x-3">
|
||||
<Checkbox
|
||||
id={permission.name}
|
||||
checked={selectedPermissions.includes(permission.name)}
|
||||
onCheckedChange={() => togglePermission(permission.name)}
|
||||
/>
|
||||
<div className="grid gap-1.5 leading-none">
|
||||
<label
|
||||
htmlFor={permission.name}
|
||||
className="text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 cursor-pointer text-gray-700 hover:text-primary-main transition-colors"
|
||||
>
|
||||
{translateAction(permission.name)}
|
||||
</label>
|
||||
<p className="text-[10px] text-gray-400 font-mono">
|
||||
{permission.name}
|
||||
</p>
|
||||
</div>
|
||||
<div className="pl-10 space-y-6 pt-1">
|
||||
{/* 基本操作 */}
|
||||
{normalPermissions.length > 0 && (
|
||||
<div className="space-y-3">
|
||||
<div className="text-xs font-semibold text-gray-400 uppercase tracking-wider">
|
||||
基本功能權限
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-y-3 gap-x-4">
|
||||
{normalPermissions.map((permission) => (
|
||||
<PermissionItem
|
||||
key={permission.id}
|
||||
permission={permission}
|
||||
selectedPermissions={selectedPermissions}
|
||||
onToggle={togglePermission}
|
||||
translate={translateAction}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 狀態操作/進階權限 */}
|
||||
{specialPermissions.length > 0 && (
|
||||
<div className="space-y-3 pt-2 border-t border-gray-100 italic">
|
||||
<div className="text-xs font-semibold text-amber-600/70 uppercase tracking-wider flex items-center gap-1">
|
||||
<span className="w-1 h-3 bg-amber-500 rounded-full" />
|
||||
單據狀態與進階操作權限
|
||||
</div>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-y-3 gap-x-4">
|
||||
{specialPermissions.map((permission) => (
|
||||
<PermissionItem
|
||||
key={permission.id}
|
||||
permission={permission}
|
||||
selectedPermissions={selectedPermissions}
|
||||
onToggle={togglePermission}
|
||||
translate={translateAction}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
@@ -275,3 +292,26 @@ export default function PermissionSelector({ groupedPermissions, selectedPermiss
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function PermissionItem({ permission, selectedPermissions, onToggle, translate }: any) {
|
||||
return (
|
||||
<div className="flex items-start space-x-3">
|
||||
<Checkbox
|
||||
id={permission.name}
|
||||
checked={selectedPermissions.includes(permission.name)}
|
||||
onCheckedChange={() => onToggle(permission.name)}
|
||||
/>
|
||||
<div className="grid gap-1.5 leading-none">
|
||||
<label
|
||||
htmlFor={permission.name}
|
||||
className="text-sm leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 cursor-pointer text-gray-700 hover:text-primary-main transition-colors"
|
||||
>
|
||||
{translate(permission.name)}
|
||||
</label>
|
||||
<p className="text-[10px] text-gray-400 font-mono">
|
||||
{permission.name}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user