feat: update inventory columns to match legacy portal and grant admins all companies
Inventory summary table now shows Plant, Cust Part#, Vorteq Part#, Vorteq Desc, Warehouse, Qty LB, Rows with a blue View button for drill-down. Admins see all active companies in the company selector. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
cf9af94f7d
commit
87c1cdf8da
3 changed files with 45 additions and 24 deletions
|
|
@ -12,7 +12,7 @@ import {
|
||||||
} from '@/components/ui/table';
|
} from '@/components/ui/table';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Input } from '@/components/ui/input';
|
import { Input } from '@/components/ui/input';
|
||||||
import { Search, Download } from 'lucide-react';
|
import { Search, Download, Eye } from 'lucide-react';
|
||||||
import { InventorySummaryRow } from '@/services/inventory';
|
import { InventorySummaryRow } from '@/services/inventory';
|
||||||
|
|
||||||
type InventorySummaryTableProps = {
|
type InventorySummaryTableProps = {
|
||||||
|
|
@ -30,31 +30,34 @@ export function InventorySummaryTable({
|
||||||
(row) =>
|
(row) =>
|
||||||
row.part_num.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
row.part_num.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
row.description?.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
row.description?.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
row.plant?.toLowerCase().includes(searchTerm.toLowerCase())
|
row.plant?.toLowerCase().includes(searchTerm.toLowerCase()) ||
|
||||||
|
row.cust_part_num?.toLowerCase().includes(searchTerm.toLowerCase())
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleExportCSV = () => {
|
const handleExportCSV = () => {
|
||||||
// Create CSV content
|
|
||||||
const headers = [
|
const headers = [
|
||||||
'Part Number',
|
|
||||||
'Description',
|
|
||||||
'Plant',
|
'Plant',
|
||||||
|
'Cust Part#',
|
||||||
|
'Vorteq Part#',
|
||||||
|
'Vorteq Desc',
|
||||||
'Warehouse',
|
'Warehouse',
|
||||||
'On Hand Qty',
|
'Qty LB',
|
||||||
|
'Rows',
|
||||||
];
|
];
|
||||||
const rows = filteredData.map((row) => [
|
const rows = filteredData.map((row) => [
|
||||||
|
row.plant,
|
||||||
|
row.cust_part_num || '',
|
||||||
row.part_num,
|
row.part_num,
|
||||||
row.description || '',
|
row.description || '',
|
||||||
row.plant,
|
|
||||||
row.warehouse,
|
row.warehouse,
|
||||||
row.on_hand_qty,
|
row.on_hand_qty,
|
||||||
|
row.rows,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const csvContent = [headers, ...rows]
|
const csvContent = [headers, ...rows]
|
||||||
.map((row) => row.join(','))
|
.map((row) => row.map((cell) => `"${cell}"`).join(','))
|
||||||
.join('\n');
|
.join('\n');
|
||||||
|
|
||||||
// Download CSV
|
|
||||||
const blob = new Blob([csvContent], { type: 'text/csv' });
|
const blob = new Blob([csvContent], { type: 'text/csv' });
|
||||||
const url = window.URL.createObjectURL(blob);
|
const url = window.URL.createObjectURL(blob);
|
||||||
const a = document.createElement('a');
|
const a = document.createElement('a');
|
||||||
|
|
@ -95,32 +98,39 @@ export function InventorySummaryTable({
|
||||||
<Table>
|
<Table>
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHead>Part Number</TableHead>
|
|
||||||
<TableHead>Description</TableHead>
|
|
||||||
<TableHead>Plant</TableHead>
|
<TableHead>Plant</TableHead>
|
||||||
|
<TableHead>Cust Part#</TableHead>
|
||||||
|
<TableHead>Vorteq Part#</TableHead>
|
||||||
|
<TableHead>Vorteq Desc</TableHead>
|
||||||
<TableHead>Warehouse</TableHead>
|
<TableHead>Warehouse</TableHead>
|
||||||
<TableHead className="text-right">On Hand Qty</TableHead>
|
<TableHead className="text-right">Qty LB</TableHead>
|
||||||
|
<TableHead className="text-right">Rows</TableHead>
|
||||||
|
<TableHead className="w-[70px]"></TableHead>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{filteredData.map((row, idx) => (
|
{filteredData.map((row, idx) => (
|
||||||
<TableRow key={idx}>
|
<TableRow key={idx}>
|
||||||
<TableCell>
|
|
||||||
<Link
|
|
||||||
href={`/inventory/${category}/detail?part=${encodeURIComponent(row.part_num)}&plant=${encodeURIComponent(row.plant_key || row.plant)}&warehouse=${encodeURIComponent(row.warehouse)}`}
|
|
||||||
className="font-medium hover:underline"
|
|
||||||
>
|
|
||||||
{row.part_num}
|
|
||||||
</Link>
|
|
||||||
</TableCell>
|
|
||||||
<TableCell className="max-w-xs truncate">
|
|
||||||
{row.description || 'N/A'}
|
|
||||||
</TableCell>
|
|
||||||
<TableCell>{row.plant}</TableCell>
|
<TableCell>{row.plant}</TableCell>
|
||||||
|
<TableCell>{row.cust_part_num || '-'}</TableCell>
|
||||||
|
<TableCell className="font-medium">{row.part_num}</TableCell>
|
||||||
|
<TableCell className="max-w-xs truncate">
|
||||||
|
{row.description || '-'}
|
||||||
|
</TableCell>
|
||||||
<TableCell>{row.warehouse}</TableCell>
|
<TableCell>{row.warehouse}</TableCell>
|
||||||
<TableCell className="text-right">
|
<TableCell className="text-right">
|
||||||
{Number(row.on_hand_qty).toLocaleString()}
|
{Number(row.on_hand_qty).toLocaleString()}
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
<TableCell className="text-right">{row.rows}</TableCell>
|
||||||
|
<TableCell>
|
||||||
|
<Link
|
||||||
|
href={`/inventory/${category}/detail?part=${encodeURIComponent(row.part_num)}&plant=${encodeURIComponent(row.plant_key || row.plant)}&warehouse=${encodeURIComponent(row.warehouse)}`}
|
||||||
|
>
|
||||||
|
<Button variant="ghost" size="icon" className="h-8 w-8 text-blue-600 hover:text-blue-800">
|
||||||
|
<Eye className="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))}
|
))}
|
||||||
</TableBody>
|
</TableBody>
|
||||||
|
|
|
||||||
|
|
@ -247,7 +247,8 @@ export async function getActiveCompany() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all companies accessible by the current user
|
* Get all companies accessible by the current user.
|
||||||
|
* Admins and Super Admins can access all active companies.
|
||||||
*/
|
*/
|
||||||
export async function getUserCompanies() {
|
export async function getUserCompanies() {
|
||||||
const session = await getQuestSession();
|
const session = await getQuestSession();
|
||||||
|
|
@ -256,6 +257,14 @@ export async function getUserCompanies() {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Admins see all active companies
|
||||||
|
if (session.userType === 'Admin' || session.userType === 'Super Admin') {
|
||||||
|
return await db.quest_company.findMany({
|
||||||
|
where: { is_active: true },
|
||||||
|
orderBy: { display_name: 'asc' },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const questUser = await db.quest_user.findUnique({
|
const questUser = await db.quest_user.findUnique({
|
||||||
where: { id: session.questUserId },
|
where: { id: session.questUserId },
|
||||||
include: {
|
include: {
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,7 @@ export type InventorySummaryRow = {
|
||||||
plant_key: string;
|
plant_key: string;
|
||||||
warehouse: string;
|
warehouse: string;
|
||||||
on_hand_qty: number;
|
on_hand_qty: number;
|
||||||
|
rows: number;
|
||||||
paint_code?: string;
|
paint_code?: string;
|
||||||
cust_part_num?: string;
|
cust_part_num?: string;
|
||||||
};
|
};
|
||||||
|
|
@ -50,6 +51,7 @@ function mapSummaryRow(raw: Record<string, unknown>): InventorySummaryRow {
|
||||||
plant_key: String(raw.PlantKey ?? ''),
|
plant_key: String(raw.PlantKey ?? ''),
|
||||||
warehouse: String(raw.Warehouse ?? ''),
|
warehouse: String(raw.Warehouse ?? ''),
|
||||||
on_hand_qty: Number(raw.OnHandQty ?? 0),
|
on_hand_qty: Number(raw.OnHandQty ?? 0),
|
||||||
|
rows: Number(raw.Rows ?? 0),
|
||||||
paint_code: raw.PaintCode ? String(raw.PaintCode) : undefined,
|
paint_code: raw.PaintCode ? String(raw.PaintCode) : undefined,
|
||||||
cust_part_num: raw.CustPartNum ? String(raw.CustPartNum) : undefined,
|
cust_part_num: raw.CustPartNum ? String(raw.CustPartNum) : undefined,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue