upgrade pms action cell

This commit is contained in:
pramod.mahajan 2025-11-09 22:39:30 +05:30
parent 96faf07311
commit 7b0659e820
2 changed files with 142 additions and 99 deletions

View File

@ -234,6 +234,25 @@ export default function PmsGrid({
}
/>
</th>
)}
{features.expand && (
<th
className="text-center ticky-action-column"
>
<input
type="checkbox"
className="form-check-input mx-3"
checked={
currentRows.length > 0 &&
currentRows.every((r) => selected.has(r[rowKey]))
}
onChange={(e) =>
e.target.checked
? selectAllOnPage(currentRows)
: deselectAllOnPage(currentRows)
}
/>
</th>
)}
{visibleColumns.map((col) => {
const style = {
@ -303,7 +322,7 @@ export default function PmsGrid({
{features.actions && (
<th
className="text-center sticky-action-column vs-th bg-white fw-semibold"
className="text-center sticky-action-column vs-th bg-white fw-semibold th-lastChild"
style={{ position: "sticky", right: 0, zIndex: 10 }}
>
Actions
@ -387,104 +406,128 @@ export default function PmsGrid({
);
// render a single row (function hoisted so it can reference visibleColumns)
function renderRow(row) {
const isSelected = selected.has(row[rowKey]);
function renderRow(row) {
const isSelected = selected.has(row[rowKey]);
const isExpanded = expanded.has(row[rowKey]);
return (
<React.Fragment key={row[rowKey]}>
<tr>
{features.selection && (
<td className="text-center p-2 .sticky-action-column">
<input
type="checkbox"
className="form-check-input"
checked={isSelected}
onChange={() => toggleSelect(row[rowKey])}
/>
</td>
)}
{visibleColumns.map((col) => {
const style = {
minWidth: col.width || 120,
width: col.width || undefined,
};
if (col.pinned) style.position = "sticky";
if (col.pinned === "left")
style.left = `${getLeftOffset(colState, col.key)}px`;
if (col.pinned === "right")
style.right = `${getRightOffset(colState, col.key)}px`;
return (
<td
key={col.key}
style={style}
className={`${col.className ?? ""} ${
col.pinned
? "pinned-left px-3 bg-white pms-grid td pinned"
: "px-3"
}`}
>
{col.render ? col.render(row) : row[col.key] ?? ""}
</td>
);
})}
{features.actions && (
<td
className="text-center sticky-action-column bg-white"
style={{
position: "sticky",
right: 0,
zIndex: 2,
width: "1%",
whiteSpace: "nowrap",
}}
>
<div
className="d-inline-flex justify-content-center align-items-center gap-2"
style={{ minWidth: "fit-content", padding: "0 4px" }}
>
{Array.isArray(features.actions)
? features.actions.map((act, i) => (
<button
key={i}
type="button"
className="btn btn-link p-0 border-0"
title={act.label}
onClick={(e) => {
e.stopPropagation();
act.onClick && act.onClick(row);
}}
>
<i className={`bx ${act.icon}`} />
</button>
))
: typeof features.actions === "function"
? features.actions(row, toggleExpand)
: null}
</div>
</td>
)}
</tr>
{features.expand && expanded.has(row[rowKey]) && renderExpanded && (
<tr className="table-active">
<td
colSpan={
visibleColumns.length +
(features.selection ? 1 : 0) +
(features.actions ? 1 : 0)
}
>
{renderExpanded(row)}
</td>
</tr>
return (
<React.Fragment key={row[rowKey]}>
<tr>
{/* Selection checkbox (always left) */}
{features.selection && (
<td className="text-center align-middle p-2">
<input
type="checkbox"
className="form-check-input"
checked={isSelected}
onChange={() => toggleSelect(row[rowKey])}
/>
</td>
)}
</React.Fragment>
);
}
{/* Expand toggle next to selection */}
{features.expand && (
<td className="text-center align-middle p-2">
<button
type="button"
className="btn btn-link p-0 border-0 text-secondary"
onClick={() => toggleExpand(row[rowKey])}
>
<i
className={`bx ${
isExpanded ? "bxs-chevron-up" : "bxs-chevron-down"
} bx-sm`}
></i>
</button>
</td>
)}
{/* Data columns */}
{visibleColumns.map((col) => {
const style = {
minWidth: col.width || 120,
width: col.width || undefined,
};
if (col.pinned) style.position = "sticky";
if (col.pinned === "left")
style.left = `${getLeftOffset(colState, col.key)}px`;
if (col.pinned === "right")
style.right = `${getRightOffset(colState, col.key)}px`;
return (
<td
key={col.key}
style={style}
className={`${col.className ?? ""} ${
col.pinned
? "pinned-left px-3 bg-white pms-grid td pinned"
: "px-3"
}`}
>
{col.render ? col.render(row) : row[col.key] ?? ""}
</td>
);
})}
{/* Actions column (always right) */}
{features.actions && (
<td
className="text-center sticky-action-column bg-white td-lastChild"
style={{
position: "sticky",
right: 0,
zIndex: 2,
width: "1%",
whiteSpace: "nowrap",
}}
>
<div
className="d-inline-flex justify-content-center align-items-center gap-2"
style={{ minWidth: "fit-content", padding: "0 4px" }}
>
{Array.isArray(features.actions)
? features.actions.map((act, i) => (
<button
key={i}
type="button"
className="btn btn-link p-0 border-0"
title={act.label}
onClick={(e) => {
e.stopPropagation();
act.onClick && act.onClick(row);
}}
>
<i className={`bx ${act.icon}`} />
</button>
))
: typeof features.actions === "function"
? features.actions(row, toggleExpand)
: null}
</div>
</td>
)}
</tr>
{/* 🔹 5. Expanded row content (full width) */}
{isExpanded && renderExpanded && (
<tr className="table-active">
<td
colSpan={
visibleColumns.length +
(features.selection ? 1 : 0) +
(features.expand ? 1 : 0) +
(features.actions ? 1 : 0)
}
>
{renderExpanded(row)}
</td>
</tr>
)}
</React.Fragment>
);
}
}
// small helpers to compute sticky offsets

View File

@ -102,8 +102,8 @@
}
/* Always sticky last column (Actions) */
.pms-grid th:last-child,
.pms-grid td:last-child {
.pms-grid .th-lastChild,
.pms-grid .td-lastChild {
position: sticky;
right: 0;
z-index: 8;