feat: 優化庫存調撥單操作紀錄與 UI 佈局
This commit is contained in:
@@ -171,6 +171,8 @@ const statusMap: Record<string, string> = {
|
||||
// 生產工單狀態
|
||||
planned: '已計畫',
|
||||
in_progress: '生產中',
|
||||
// 調撥單狀態
|
||||
voided: '已作廢',
|
||||
// completed 已定義
|
||||
};
|
||||
|
||||
@@ -223,12 +225,21 @@ export default function ActivityDetailDialog({ open, onOpenChange, activity }: P
|
||||
return a.localeCompare(b);
|
||||
});
|
||||
|
||||
// 檢查鍵是否為快照名稱欄位的輔助函式
|
||||
// 檢查鍵是否為快照名稱欄位或輔助名稱欄位的輔助函式
|
||||
const isSnapshotField = (key: string) => {
|
||||
return [
|
||||
// 隱藏快照欄位
|
||||
const snapshotFields = [
|
||||
'category_name', 'base_unit_name', 'large_unit_name', 'purchase_unit_name',
|
||||
'warehouse_name', 'user_name'
|
||||
].includes(key);
|
||||
'warehouse_name', 'user_name', 'from_warehouse_name', 'to_warehouse_name',
|
||||
'created_by_name', 'updated_by_name', 'completed_by_name', 'posted_by_name'
|
||||
];
|
||||
|
||||
if (snapshotFields.includes(key)) return true;
|
||||
|
||||
// 隱藏所有以 _name 結尾的欄位(因為它們通常是 ID 欄位的文字補充)
|
||||
if (key.endsWith('_name')) return true;
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
const getEventBadgeClass = (event: string) => {
|
||||
@@ -343,7 +354,7 @@ export default function ActivityDetailDialog({ open, onOpenChange, activity }: P
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={onOpenChange}>
|
||||
<DialogContent className="max-w-3xl max-h-[90vh] overflow-y-auto p-0 gap-0">
|
||||
<DialogContent className="max-w-4xl max-h-[90vh] overflow-y-auto p-0 gap-0">
|
||||
<DialogHeader className="p-6 pb-4 border-b pr-12">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<DialogTitle className="text-xl font-bold text-gray-900">
|
||||
@@ -385,12 +396,12 @@ export default function ActivityDetailDialog({ open, onOpenChange, activity }: P
|
||||
<div className="bg-gray-50/50 p-6 min-h-[300px]">
|
||||
{activity.event === 'created' ? (
|
||||
<div className="border rounded-md overflow-hidden bg-white shadow-sm">
|
||||
<Table>
|
||||
<Table className="table-fixed w-full">
|
||||
<TableHeader>
|
||||
<TableRow className="bg-gray-50/50 hover:bg-gray-50/50">
|
||||
<TableHead className="w-[150px]">欄位</TableHead>
|
||||
<TableHead>異動前</TableHead>
|
||||
<TableHead>異動後</TableHead>
|
||||
<TableHead className="w-[140px]">欄位</TableHead>
|
||||
<TableHead className="w-1/2">異動前</TableHead>
|
||||
<TableHead className="w-1/2">異動後</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
@@ -398,9 +409,9 @@ export default function ActivityDetailDialog({ open, onOpenChange, activity }: P
|
||||
.filter(key => attributes[key] !== null && attributes[key] !== '' && !isSnapshotField(key))
|
||||
.map((key) => (
|
||||
<TableRow key={key}>
|
||||
<TableCell className="font-medium text-gray-700 w-[120px] shrink-0">{getFieldLabel(key)}</TableCell>
|
||||
<TableCell className="text-gray-500 break-all min-w-[150px]">-</TableCell>
|
||||
<TableCell className="text-gray-900 font-medium break-all min-w-[200px] whitespace-pre-wrap">
|
||||
<TableCell className="font-medium text-gray-700 w-[140px] truncate">{getFieldLabel(key)}</TableCell>
|
||||
<TableCell className="text-gray-500">-</TableCell>
|
||||
<TableCell className="text-gray-900 font-medium break-all whitespace-pre-wrap">
|
||||
{getFormattedValue(key, attributes[key])}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
@@ -417,12 +428,12 @@ export default function ActivityDetailDialog({ open, onOpenChange, activity }: P
|
||||
</div>
|
||||
) : (
|
||||
<div className="border rounded-md overflow-hidden bg-white shadow-sm">
|
||||
<Table>
|
||||
<Table className="table-fixed w-full">
|
||||
<TableHeader>
|
||||
<TableRow className="bg-gray-50 hover:bg-gray-50">
|
||||
<TableHead className="w-[150px]">欄位</TableHead>
|
||||
<TableHead>異動前</TableHead>
|
||||
<TableHead>異動後</TableHead>
|
||||
<TableHead className="w-[140px]">欄位</TableHead>
|
||||
<TableHead className="w-1/2">異動前</TableHead>
|
||||
<TableHead className="w-1/2">異動後</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
@@ -456,11 +467,11 @@ export default function ActivityDetailDialog({ open, onOpenChange, activity }: P
|
||||
|
||||
return (
|
||||
<TableRow key={key} className={isChanged ? 'bg-amber-50/30 hover:bg-amber-50/50' : 'hover:bg-gray-50/50'}>
|
||||
<TableCell className="font-medium text-gray-700 w-[120px] shrink-0">{getFieldLabel(key)}</TableCell>
|
||||
<TableCell className="text-gray-500 break-all min-w-[150px] whitespace-pre-wrap">
|
||||
<TableCell className="font-medium text-gray-700 w-[140px] truncate">{getFieldLabel(key)}</TableCell>
|
||||
<TableCell className="text-gray-500 break-all whitespace-pre-wrap">
|
||||
{displayBefore}
|
||||
</TableCell>
|
||||
<TableCell className="text-gray-900 font-medium break-all min-w-[200px] whitespace-pre-wrap">
|
||||
<TableCell className="text-gray-900 font-medium break-all whitespace-pre-wrap">
|
||||
{displayAfter}
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
@@ -486,12 +497,12 @@ export default function ActivityDetailDialog({ open, onOpenChange, activity }: P
|
||||
</h3>
|
||||
|
||||
<div className="border rounded-md overflow-hidden bg-white shadow-sm">
|
||||
<Table>
|
||||
<Table className="table-fixed w-full">
|
||||
<TableHeader className="bg-gray-50/50">
|
||||
<TableRow>
|
||||
<TableHead>商品名稱</TableHead>
|
||||
<TableHead className="text-center">異動類型</TableHead>
|
||||
<TableHead>異動詳情 (舊 → 新)</TableHead>
|
||||
<TableHead className="w-1/3">商品名稱</TableHead>
|
||||
<TableHead className="w-[100px] text-center">異動類型</TableHead>
|
||||
<TableHead className="w-1/2">異動詳情 (舊 → 新)</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
|
||||
@@ -113,7 +113,7 @@ export default function ActivityLogIndex({ activities, filters, subject_types, u
|
||||
setPerPage(value);
|
||||
router.get(
|
||||
route('activity-logs.index'),
|
||||
{ ...filters, per_page: value },
|
||||
{ ...filters, per_page: value, page: 1 },
|
||||
{ preserveState: false, replace: true, preserveScroll: true }
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user