mirror of
https://github.com/christianvidalwolf-prog/Craze-Data-check.git
synced 2026-08-03 13:55:23 +02:00
feat: resizable columns in ProductDescriptions and ArticleDetails
This commit is contained in:
@@ -22,6 +22,14 @@ export function ArticleDetails({ data, onEdit, rowStatuses }: ArticleDetailsProp
|
|||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [columnFilters, setColumnFilters] = useState<Record<number, string[]>>({});
|
const [columnFilters, setColumnFilters] = useState<Record<number, string[]>>({});
|
||||||
const [openFilterCol, setOpenFilterCol] = useState<number | null>(null);
|
const [openFilterCol, setOpenFilterCol] = useState<number | null>(null);
|
||||||
|
const [columnWidths, setColumnWidths] = useState<Record<number, number>>({
|
||||||
|
[COLUMNS.ARTICLE_NO]: 100,
|
||||||
|
[COLUMNS.ARTICLE_NAME]: 200,
|
||||||
|
[COLUMNS.CLASSIFICATION]: 80,
|
||||||
|
[COLUMNS.ITEM_AVAILABLE]: 80,
|
||||||
|
[COLUMNS.DETAILS_DE]: 150,
|
||||||
|
[COLUMNS.DETAILS_EN]: 150,
|
||||||
|
});
|
||||||
|
|
||||||
const lines = useMemo(() => Array.from(new Set(data.map(r => r[COLUMNS.LINE]).filter(Boolean))), [data]);
|
const lines = useMemo(() => Array.from(new Set(data.map(r => r[COLUMNS.LINE]).filter(Boolean))), [data]);
|
||||||
|
|
||||||
@@ -89,6 +97,25 @@ export function ArticleDetails({ data, onEdit, rowStatuses }: ArticleDetailsProp
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleResize = (colIndex: number, e: React.MouseEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const startX = e.pageX;
|
||||||
|
const startWidth = columnWidths[colIndex] || 100;
|
||||||
|
|
||||||
|
const onMouseMove = (moveEvent: MouseEvent) => {
|
||||||
|
const newWidth = Math.max(60, startWidth + (moveEvent.pageX - startX));
|
||||||
|
setColumnWidths(prev => ({ ...prev, [colIndex]: newWidth }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const onMouseUp = () => {
|
||||||
|
window.removeEventListener('mousemove', onMouseMove);
|
||||||
|
window.removeEventListener('mouseup', onMouseUp);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('mousemove', onMouseMove);
|
||||||
|
window.addEventListener('mouseup', onMouseUp);
|
||||||
|
};
|
||||||
|
|
||||||
const getUniqueValues = (col: number) => {
|
const getUniqueValues = (col: number) => {
|
||||||
const values = data.map(r => String(r[col] || ''));
|
const values = data.map(r => String(r[col] || ''));
|
||||||
return Array.from(new Set(values)).sort();
|
return Array.from(new Set(values)).sort();
|
||||||
@@ -185,7 +212,7 @@ export function ArticleDetails({ data, onEdit, rowStatuses }: ArticleDetailsProp
|
|||||||
|
|
||||||
<div className="flex-1 bg-slate-800 rounded-xl border border-slate-700 shadow-xl overflow-hidden flex flex-col">
|
<div className="flex-1 bg-slate-800 rounded-xl border border-slate-700 shadow-xl overflow-hidden flex flex-col">
|
||||||
<div className="overflow-x-auto flex-1">
|
<div className="overflow-x-auto flex-1">
|
||||||
<table className="w-full text-left text-xs">
|
<table className="w-full text-left text-xs" style={{ tableLayout: 'fixed' }}>
|
||||||
<thead className="bg-slate-900/80 text-slate-400 sticky top-0 z-10">
|
<thead className="bg-slate-900/80 text-slate-400 sticky top-0 z-10">
|
||||||
<tr>
|
<tr>
|
||||||
{[
|
{[
|
||||||
@@ -198,13 +225,14 @@ export function ArticleDetails({ data, onEdit, rowStatuses }: ArticleDetailsProp
|
|||||||
].map(({ col, label }) => (
|
].map(({ col, label }) => (
|
||||||
<th
|
<th
|
||||||
key={col}
|
key={col}
|
||||||
className="px-3 py-3 font-medium transition-colors select-none group relative"
|
className="px-3 py-3 font-medium transition-colors select-none group relative border-r border-slate-700/30"
|
||||||
|
style={{ width: columnWidths[col] || 'auto', minWidth: columnWidths[col] || 'auto' }}
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between gap-1">
|
<div className="flex items-center justify-between gap-1 overflow-hidden">
|
||||||
<div className="flex items-center gap-1 cursor-pointer hover:text-white" onClick={() => handleSort(col)}>
|
<div className="flex items-center gap-1 cursor-pointer hover:text-white truncate" onClick={() => handleSort(col)}>
|
||||||
{label}
|
{label}
|
||||||
{sortCol === col && (
|
{sortCol === col && (
|
||||||
sortDesc ? <ChevronDown className="w-3 h-3" /> : <ChevronUp className="w-3 h-3" />
|
sortDesc ? <ChevronDown className="w-3 h-3 shrink-0" /> : <ChevronUp className="w-3 h-3 shrink-0" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
@@ -213,7 +241,7 @@ export function ArticleDetails({ data, onEdit, rowStatuses }: ArticleDetailsProp
|
|||||||
setOpenFilterCol(openFilterCol === col ? null : col);
|
setOpenFilterCol(openFilterCol === col ? null : col);
|
||||||
}}
|
}}
|
||||||
className={cn(
|
className={cn(
|
||||||
"p-1 rounded hover:bg-slate-700 transition-colors",
|
"p-1 rounded hover:bg-slate-700 transition-colors shrink-0",
|
||||||
(columnFilters[col]?.length || 0) > 0 ? "text-indigo-400 bg-indigo-400/10" : "text-slate-500 opacity-0 group-hover:opacity-100"
|
(columnFilters[col]?.length || 0) > 0 ? "text-indigo-400 bg-indigo-400/10" : "text-slate-500 opacity-0 group-hover:opacity-100"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@@ -221,6 +249,12 @@ export function ArticleDetails({ data, onEdit, rowStatuses }: ArticleDetailsProp
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Resizer handle */}
|
||||||
|
<div
|
||||||
|
onMouseDown={(e) => handleResize(col, e)}
|
||||||
|
className="absolute right-0 top-0 bottom-0 w-1 cursor-col-resize hover:bg-indigo-500/50 group-hover:bg-slate-700/50 transition-colors z-20"
|
||||||
|
/>
|
||||||
|
|
||||||
{openFilterCol === col && (
|
{openFilterCol === col && (
|
||||||
<ColumnFilterPopover
|
<ColumnFilterPopover
|
||||||
uniqueValues={getUniqueValues(col)}
|
uniqueValues={getUniqueValues(col)}
|
||||||
@@ -240,7 +274,7 @@ export function ArticleDetails({ data, onEdit, rowStatuses }: ArticleDetailsProp
|
|||||||
)}
|
)}
|
||||||
</th>
|
</th>
|
||||||
))}
|
))}
|
||||||
<th className="px-3 py-3 font-medium text-right">Edit</th>
|
<th className="px-3 py-3 font-medium text-right" style={{ width: 80 }}>Edit</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="divide-y divide-slate-700/30">
|
<tbody className="divide-y divide-slate-700/30">
|
||||||
@@ -254,11 +288,11 @@ export function ArticleDetails({ data, onEdit, rowStatuses }: ArticleDetailsProp
|
|||||||
isPending ? "bg-yellow-400/20 border-l-4 border-l-yellow-400" : ""
|
isPending ? "bg-yellow-400/20 border-l-4 border-l-yellow-400" : ""
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<td className="px-3 py-2 font-mono text-indigo-400">{row[COLUMNS.ARTICLE_NO]}</td>
|
<td className="px-3 py-2 font-mono text-indigo-400 truncate" style={{ width: columnWidths[COLUMNS.ARTICLE_NO] }}>{row[COLUMNS.ARTICLE_NO]}</td>
|
||||||
<td className="px-3 py-2 font-medium text-slate-200 max-w-[150px] truncate" title={row[COLUMNS.ARTICLE_NAME]}>
|
<td className="px-3 py-2 font-medium text-slate-200 truncate" style={{ width: columnWidths[COLUMNS.ARTICLE_NAME] }} title={row[COLUMNS.ARTICLE_NAME]}>
|
||||||
{row[COLUMNS.ARTICLE_NAME]}
|
{row[COLUMNS.ARTICLE_NAME]}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-3 py-2">
|
<td className="px-3 py-2 truncate" style={{ width: columnWidths[COLUMNS.CLASSIFICATION] }}>
|
||||||
<span className={cn(
|
<span className={cn(
|
||||||
"px-1.5 py-0.5 rounded-[4px] text-[10px] font-bold border",
|
"px-1.5 py-0.5 rounded-[4px] text-[10px] font-bold border",
|
||||||
String(row[COLUMNS.CLASSIFICATION]).includes('OOC') ? "bg-amber-500/10 text-amber-500 border-amber-500/20" : "bg-slate-700/50 text-slate-400 border-slate-600/50"
|
String(row[COLUMNS.CLASSIFICATION]).includes('OOC') ? "bg-amber-500/10 text-amber-500 border-amber-500/20" : "bg-slate-700/50 text-slate-400 border-slate-600/50"
|
||||||
@@ -266,7 +300,7 @@ export function ArticleDetails({ data, onEdit, rowStatuses }: ArticleDetailsProp
|
|||||||
{row[COLUMNS.CLASSIFICATION] || '—'}
|
{row[COLUMNS.CLASSIFICATION] || '—'}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-3 py-2">
|
<td className="px-3 py-2 truncate" style={{ width: columnWidths[COLUMNS.ITEM_AVAILABLE] }}>
|
||||||
<span className={cn(
|
<span className={cn(
|
||||||
"font-mono font-bold",
|
"font-mono font-bold",
|
||||||
Number(row[COLUMNS.ITEM_AVAILABLE] || 0) <= 0 ? "text-red-400" : "text-emerald-400"
|
Number(row[COLUMNS.ITEM_AVAILABLE] || 0) <= 0 ? "text-red-400" : "text-emerald-400"
|
||||||
@@ -274,14 +308,14 @@ export function ArticleDetails({ data, onEdit, rowStatuses }: ArticleDetailsProp
|
|||||||
{row[COLUMNS.ITEM_AVAILABLE] || 0}
|
{row[COLUMNS.ITEM_AVAILABLE] || 0}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-3 py-2">
|
<td className="px-3 py-2 truncate" style={{ width: columnWidths[COLUMNS.DETAILS_DE] }}>
|
||||||
{row[COLUMNS.DETAILS_DE] ? (
|
{row[COLUMNS.DETAILS_DE] ? (
|
||||||
<div className="max-w-[120px] truncate text-slate-400" title={row[COLUMNS.DETAILS_DE]}>{row[COLUMNS.DETAILS_DE]}</div>
|
<div className="truncate text-slate-400" title={row[COLUMNS.DETAILS_DE]}>{row[COLUMNS.DETAILS_DE]}</div>
|
||||||
) : getBadge(null)}
|
) : getBadge(null)}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-3 py-2">
|
<td className="px-3 py-2 truncate" style={{ width: columnWidths[COLUMNS.DETAILS_EN] }}>
|
||||||
{row[COLUMNS.DETAILS_EN] ? (
|
{row[COLUMNS.DETAILS_EN] ? (
|
||||||
<div className="max-w-[120px] truncate text-slate-400" title={row[COLUMNS.DETAILS_EN]}>{row[COLUMNS.DETAILS_EN]}</div>
|
<div className="truncate text-slate-400" title={row[COLUMNS.DETAILS_EN]}>{row[COLUMNS.DETAILS_EN]}</div>
|
||||||
) : getBadge(null)}
|
) : getBadge(null)}
|
||||||
</td>
|
</td>
|
||||||
<td className="px-3 py-2 text-right">
|
<td className="px-3 py-2 text-right">
|
||||||
|
|||||||
@@ -26,6 +26,17 @@ export function ProductDescriptions({ data, onEdit, rowStatuses }: ProductDescri
|
|||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [columnFilters, setColumnFilters] = useState<Record<number, string[]>>({});
|
const [columnFilters, setColumnFilters] = useState<Record<number, string[]>>({});
|
||||||
const [openFilterCol, setOpenFilterCol] = useState<number | null>(null);
|
const [openFilterCol, setOpenFilterCol] = useState<number | null>(null);
|
||||||
|
const [columnWidths, setColumnWidths] = useState<Record<number, number>>({
|
||||||
|
[COLUMNS.ARTICLE_NO]: 100,
|
||||||
|
[COLUMNS.ARTICLE_NAME]: 250,
|
||||||
|
[COLUMNS.LINE]: 80,
|
||||||
|
[COLUMNS.LICENSE]: 120,
|
||||||
|
[COLUMNS.CLASSIFICATION]: 100,
|
||||||
|
[COLUMNS.LONG_DE]: 80,
|
||||||
|
[COLUMNS.LONG_EN]: 80,
|
||||||
|
[COLUMNS.SHORT_DE]: 80,
|
||||||
|
[COLUMNS.SHORT_EN]: 80,
|
||||||
|
});
|
||||||
|
|
||||||
const lines = useMemo(() => Array.from(new Set(data.map(r => r[COLUMNS.LINE]).filter(Boolean))), [data]);
|
const lines = useMemo(() => Array.from(new Set(data.map(r => r[COLUMNS.LINE]).filter(Boolean))), [data]);
|
||||||
const licenses = useMemo(() => Array.from(new Set(data.map(r => r[COLUMNS.LICENSE]).filter(Boolean))), [data]);
|
const licenses = useMemo(() => Array.from(new Set(data.map(r => r[COLUMNS.LICENSE]).filter(Boolean))), [data]);
|
||||||
@@ -116,6 +127,25 @@ export function ProductDescriptions({ data, onEdit, rowStatuses }: ProductDescri
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleResize = (colIndex: number, e: React.MouseEvent) => {
|
||||||
|
e.preventDefault();
|
||||||
|
const startX = e.pageX;
|
||||||
|
const startWidth = columnWidths[colIndex] || 100;
|
||||||
|
|
||||||
|
const onMouseMove = (moveEvent: MouseEvent) => {
|
||||||
|
const newWidth = Math.max(60, startWidth + (moveEvent.pageX - startX));
|
||||||
|
setColumnWidths(prev => ({ ...prev, [colIndex]: newWidth }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const onMouseUp = () => {
|
||||||
|
window.removeEventListener('mousemove', onMouseMove);
|
||||||
|
window.removeEventListener('mouseup', onMouseUp);
|
||||||
|
};
|
||||||
|
|
||||||
|
window.addEventListener('mousemove', onMouseMove);
|
||||||
|
window.addEventListener('mouseup', onMouseUp);
|
||||||
|
};
|
||||||
|
|
||||||
const getUniqueValues = (col: number) => {
|
const getUniqueValues = (col: number) => {
|
||||||
// For description columns, return only 'Present' and 'Missing'
|
// For description columns, return only 'Present' and 'Missing'
|
||||||
if (DESCRIPTION_COLUMNS.includes(col)) {
|
if (DESCRIPTION_COLUMNS.includes(col)) {
|
||||||
@@ -252,7 +282,7 @@ export function ProductDescriptions({ data, onEdit, rowStatuses }: ProductDescri
|
|||||||
|
|
||||||
<div className="flex-1 bg-slate-800 rounded-xl border border-slate-700 shadow-xl overflow-hidden flex flex-col">
|
<div className="flex-1 bg-slate-800 rounded-xl border border-slate-700 shadow-xl overflow-hidden flex flex-col">
|
||||||
<div className="overflow-x-auto flex-1">
|
<div className="overflow-x-auto flex-1">
|
||||||
<table className="w-full text-left text-sm">
|
<table className="w-full text-left text-sm" style={{ tableLayout: 'fixed' }}>
|
||||||
<thead className="bg-slate-900/50 text-slate-400 sticky top-0 z-10">
|
<thead className="bg-slate-900/50 text-slate-400 sticky top-0 z-10">
|
||||||
<tr>
|
<tr>
|
||||||
{[
|
{[
|
||||||
@@ -268,13 +298,14 @@ export function ProductDescriptions({ data, onEdit, rowStatuses }: ProductDescri
|
|||||||
].map(({ col, label }) => (
|
].map(({ col, label }) => (
|
||||||
<th
|
<th
|
||||||
key={col}
|
key={col}
|
||||||
className="px-4 py-3 font-medium transition-colors select-none group relative"
|
className="px-4 py-3 font-medium transition-colors select-none group relative border-r border-slate-700/30"
|
||||||
|
style={{ width: columnWidths[col] || 'auto', minWidth: columnWidths[col] || 'auto' }}
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between gap-1">
|
<div className="flex items-center justify-between gap-1 overflow-hidden">
|
||||||
<div className="flex items-center gap-1 cursor-pointer hover:text-white" onClick={() => handleSort(col)}>
|
<div className="flex items-center gap-1 cursor-pointer hover:text-white truncate" onClick={() => handleSort(col)}>
|
||||||
{label}
|
{label}
|
||||||
{sortCol === col && (
|
{sortCol === col && (
|
||||||
sortDesc ? <ChevronDown className="w-4 h-4" /> : <ChevronUp className="w-4 h-4" />
|
sortDesc ? <ChevronDown className="w-4 h-4 shrink-0" /> : <ChevronUp className="w-4 h-4 shrink-0" />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
@@ -283,7 +314,7 @@ export function ProductDescriptions({ data, onEdit, rowStatuses }: ProductDescri
|
|||||||
setOpenFilterCol(openFilterCol === col ? null : col);
|
setOpenFilterCol(openFilterCol === col ? null : col);
|
||||||
}}
|
}}
|
||||||
className={cn(
|
className={cn(
|
||||||
"p-1 rounded hover:bg-slate-700 transition-colors",
|
"p-1 rounded hover:bg-slate-700 transition-colors shrink-0",
|
||||||
(columnFilters[col]?.length || 0) > 0 ? "text-blue-400 bg-blue-400/10" : "text-slate-500 opacity-0 group-hover:opacity-100"
|
(columnFilters[col]?.length || 0) > 0 ? "text-blue-400 bg-blue-400/10" : "text-slate-500 opacity-0 group-hover:opacity-100"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
@@ -291,6 +322,12 @@ export function ProductDescriptions({ data, onEdit, rowStatuses }: ProductDescri
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Resizer handle */}
|
||||||
|
<div
|
||||||
|
onMouseDown={(e) => handleResize(col, e)}
|
||||||
|
className="absolute right-0 top-0 bottom-0 w-1 cursor-col-resize hover:bg-blue-500/50 group-hover:bg-slate-700/50 transition-colors z-20"
|
||||||
|
/>
|
||||||
|
|
||||||
{openFilterCol === col && (
|
{openFilterCol === col && (
|
||||||
<ColumnFilterPopover
|
<ColumnFilterPopover
|
||||||
uniqueValues={getUniqueValues(col)}
|
uniqueValues={getUniqueValues(col)}
|
||||||
@@ -310,7 +347,7 @@ export function ProductDescriptions({ data, onEdit, rowStatuses }: ProductDescri
|
|||||||
)}
|
)}
|
||||||
</th>
|
</th>
|
||||||
))}
|
))}
|
||||||
<th className="px-4 py-3 font-medium text-right">Actions</th>
|
<th className="px-4 py-3 font-medium text-right" style={{ width: 100 }}>Actions</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="divide-y divide-slate-700/50">
|
<tbody className="divide-y divide-slate-700/50">
|
||||||
@@ -325,11 +362,11 @@ export function ProductDescriptions({ data, onEdit, rowStatuses }: ProductDescri
|
|||||||
isPending ? "bg-yellow-400/20 border-l-4 border-l-yellow-400" : ""
|
isPending ? "bg-yellow-400/20 border-l-4 border-l-yellow-400" : ""
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<td className="px-4 py-3 font-mono text-slate-300 text-xs">{row[COLUMNS.ARTICLE_NO]}</td>
|
<td className="px-4 py-3 font-mono text-slate-300 text-xs truncate" style={{ width: columnWidths[COLUMNS.ARTICLE_NO] }}>{row[COLUMNS.ARTICLE_NO]}</td>
|
||||||
<td className="px-4 py-3 font-medium text-white max-w-[200px] truncate" title={row[COLUMNS.ARTICLE_NAME]}>{row[COLUMNS.ARTICLE_NAME]}</td>
|
<td className="px-4 py-3 font-medium text-white truncate" style={{ width: columnWidths[COLUMNS.ARTICLE_NAME] }} title={row[COLUMNS.ARTICLE_NAME]}>{row[COLUMNS.ARTICLE_NAME]}</td>
|
||||||
<td className="px-4 py-3 text-slate-300 text-xs">{row[COLUMNS.LINE]}</td>
|
<td className="px-4 py-3 text-slate-300 text-xs truncate" style={{ width: columnWidths[COLUMNS.LINE] }}>{row[COLUMNS.LINE]}</td>
|
||||||
<td className="px-4 py-3 text-slate-300 text-xs truncate max-w-[120px]" title={row[COLUMNS.LICENSE]}>{row[COLUMNS.LICENSE] || '—'}</td>
|
<td className="px-4 py-3 text-slate-300 text-xs truncate" style={{ width: columnWidths[COLUMNS.LICENSE] }} title={row[COLUMNS.LICENSE]}>{row[COLUMNS.LICENSE] || '—'}</td>
|
||||||
<td className="px-4 py-3">
|
<td className="px-4 py-3 truncate" style={{ width: columnWidths[COLUMNS.CLASSIFICATION] }}>
|
||||||
<span className={cn(
|
<span className={cn(
|
||||||
"px-2 py-0.5 rounded text-[10px] font-bold border",
|
"px-2 py-0.5 rounded text-[10px] font-bold border",
|
||||||
String(row[COLUMNS.CLASSIFICATION]).includes('OOC')
|
String(row[COLUMNS.CLASSIFICATION]).includes('OOC')
|
||||||
@@ -339,10 +376,10 @@ export function ProductDescriptions({ data, onEdit, rowStatuses }: ProductDescri
|
|||||||
{row[COLUMNS.CLASSIFICATION] || '—'}
|
{row[COLUMNS.CLASSIFICATION] || '—'}
|
||||||
</span>
|
</span>
|
||||||
</td>
|
</td>
|
||||||
<td className="px-4 py-3"><Badge content={row[COLUMNS.LONG_DE]} row={row} /></td>
|
<td className="px-4 py-3" style={{ width: columnWidths[COLUMNS.LONG_DE] }}><Badge content={row[COLUMNS.LONG_DE]} row={row} /></td>
|
||||||
<td className="px-4 py-3"><Badge content={row[COLUMNS.LONG_EN]} row={row} /></td>
|
<td className="px-4 py-3" style={{ width: columnWidths[COLUMNS.LONG_EN] }}><Badge content={row[COLUMNS.LONG_EN]} row={row} /></td>
|
||||||
<td className="px-4 py-3"><Badge content={row[COLUMNS.SHORT_DE]} row={row} /></td>
|
<td className="px-4 py-3" style={{ width: columnWidths[COLUMNS.SHORT_DE] }}><Badge content={row[COLUMNS.SHORT_DE]} row={row} /></td>
|
||||||
<td className="px-4 py-3"><Badge content={row[COLUMNS.SHORT_EN]} row={row} /></td>
|
<td className="px-4 py-3" style={{ width: columnWidths[COLUMNS.SHORT_EN] }}><Badge content={row[COLUMNS.SHORT_EN]} row={row} /></td>
|
||||||
<td className="px-4 py-3 text-right">
|
<td className="px-4 py-3 text-right">
|
||||||
<button
|
<button
|
||||||
onClick={() => onEdit(index)}
|
onClick={() => onEdit(index)}
|
||||||
|
|||||||
Reference in New Issue
Block a user