feat(tables): roll out configurable columns to all workload lists
- Add column config to DeploymentList - Add column config to StatefulSetList - Add column config to DaemonSetList - Add column config to JobList - Add column config to CronJobList - Add column config to ReplicaSetList - Add column config to ReplicationControllerList All workload lists now have user-customizable columns with settings button. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
a9cc0e12cc
commit
7f12baec9c
@ -1,6 +1,6 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui";
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Button } from "@/components/ui";
|
||||||
import { Scale, Pencil, Trash2, FileText } from "lucide-react";
|
import { Scale, Pencil, Trash2, FileText, Settings } from "lucide-react";
|
||||||
import type { ReplicaSetInfo } from "@/lib/tauriCommands";
|
import type { ReplicaSetInfo } from "@/lib/tauriCommands";
|
||||||
import {
|
import {
|
||||||
scaleReplicasetCmd,
|
scaleReplicasetCmd,
|
||||||
@ -12,6 +12,9 @@ import { ConfirmDeleteDialog } from "./ConfirmDeleteDialog";
|
|||||||
import { ScaleModal } from "./ScaleModal";
|
import { ScaleModal } from "./ScaleModal";
|
||||||
import { EditResourceModal } from "./EditResourceModal";
|
import { EditResourceModal } from "./EditResourceModal";
|
||||||
import { WorkloadLogsModal } from "./WorkloadLogsModal";
|
import { WorkloadLogsModal } from "./WorkloadLogsModal";
|
||||||
|
import { useColumnConfig } from "@/hooks/useColumnConfig";
|
||||||
|
import { DEFAULT_COLUMNS } from "@/config/defaultColumns";
|
||||||
|
import { ColumnConfigModal } from "@/components/tables/ColumnConfigModal";
|
||||||
|
|
||||||
interface ReplicaSetListProps {
|
interface ReplicaSetListProps {
|
||||||
replicaSets: ReplicaSetInfo[];
|
replicaSets: ReplicaSetInfo[];
|
||||||
@ -39,6 +42,11 @@ export function ReplicaSetList({
|
|||||||
const [activeModal, setActiveModal] = useState<ActiveModal>(null);
|
const [activeModal, setActiveModal] = useState<ActiveModal>(null);
|
||||||
const [isActing, setIsActing] = useState(false);
|
const [isActing, setIsActing] = useState(false);
|
||||||
const [actionError, setActionError] = useState<string | null>(null);
|
const [actionError, setActionError] = useState<string | null>(null);
|
||||||
|
const [showColumnConfig, setShowColumnConfig] = useState(false);
|
||||||
|
|
||||||
|
// Configurable columns
|
||||||
|
const columnConfig = useColumnConfig("replicasets", DEFAULT_COLUMNS.replicasets);
|
||||||
|
const { isColumnVisible } = columnConfig;
|
||||||
|
|
||||||
const openEdit = async (rs: ReplicaSetInfo) => {
|
const openEdit = async (rs: ReplicaSetInfo) => {
|
||||||
setActionError(null);
|
setActionError(null);
|
||||||
@ -67,40 +75,65 @@ export function ReplicaSetList({
|
|||||||
{actionError && (
|
{actionError && (
|
||||||
<p className="mb-2 text-sm text-destructive">{actionError}</p>
|
<p className="mb-2 text-sm text-destructive">{actionError}</p>
|
||||||
)}
|
)}
|
||||||
|
<div className="flex items-center justify-between mb-2">
|
||||||
|
<div className="text-sm text-muted-foreground">
|
||||||
|
{replicaSets.length} {replicaSets.length === 1 ? "replica set" : "replica sets"}
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => setShowColumnConfig(true)}
|
||||||
|
className="flex items-center gap-1"
|
||||||
|
>
|
||||||
|
<Settings className="h-3.5 w-3.5" />
|
||||||
|
Columns
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
<div className="overflow-x-auto">
|
<div className="overflow-x-auto">
|
||||||
<Table>
|
<Table>
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHead>Name</TableHead>
|
{isColumnVisible("name") && <TableHead>Name</TableHead>}
|
||||||
<TableHead>Namespace</TableHead>
|
{isColumnVisible("namespace") && <TableHead>Namespace</TableHead>}
|
||||||
<TableHead>Replicas</TableHead>
|
{isColumnVisible("desired") && <TableHead>Desired</TableHead>}
|
||||||
<TableHead>Ready</TableHead>
|
{isColumnVisible("current") && <TableHead>Current</TableHead>}
|
||||||
<TableHead>Age</TableHead>
|
{isColumnVisible("ready") && <TableHead>Ready</TableHead>}
|
||||||
<TableHead>Labels</TableHead>
|
{isColumnVisible("age") && <TableHead>Age</TableHead>}
|
||||||
<TableHead className="text-right">Actions</TableHead>
|
{isColumnVisible("labels") && <TableHead>Labels</TableHead>}
|
||||||
|
{isColumnVisible("actions") && <TableHead className="text-right">Actions</TableHead>}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
{replicaSets.length === 0 ? (
|
{replicaSets.length === 0 ? (
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableCell colSpan={7} className="text-center text-muted-foreground">
|
<TableCell colSpan={8} className="text-center text-muted-foreground">
|
||||||
No replica sets found
|
No replica sets found
|
||||||
</TableCell>
|
</TableCell>
|
||||||
</TableRow>
|
</TableRow>
|
||||||
) : (
|
) : (
|
||||||
replicaSets.map((rs) => (
|
replicaSets.map((rs) => (
|
||||||
<TableRow key={`${rs.name}-${rs.namespace}`}>
|
<TableRow key={`${rs.name}-${rs.namespace}`}>
|
||||||
<TableCell className="font-medium">{rs.name}</TableCell>
|
{isColumnVisible("name") && (
|
||||||
<TableCell>{rs.namespace}</TableCell>
|
<TableCell className="font-medium">{rs.name}</TableCell>
|
||||||
<TableCell>{rs.replicas}</TableCell>
|
)}
|
||||||
<TableCell>{rs.ready}</TableCell>
|
{isColumnVisible("namespace") && (
|
||||||
<TableCell className="text-muted-foreground">{rs.age}</TableCell>
|
<TableCell className="text-muted-foreground">{rs.namespace}</TableCell>
|
||||||
<TableCell>
|
)}
|
||||||
{Object.entries(rs.labels)
|
{isColumnVisible("desired") && <TableCell>{rs.replicas}</TableCell>}
|
||||||
.map(([k, v]) => `${k}=${v}`)
|
{isColumnVisible("current") && <TableCell>{rs.replicas}</TableCell>}
|
||||||
.join(", ")}
|
{isColumnVisible("ready") && <TableCell>{rs.ready}</TableCell>}
|
||||||
</TableCell>
|
{isColumnVisible("age") && (
|
||||||
<TableCell className="text-right">
|
<TableCell className="text-muted-foreground">{rs.age}</TableCell>
|
||||||
|
)}
|
||||||
|
{isColumnVisible("labels") && (
|
||||||
|
<TableCell>
|
||||||
|
{Object.entries(rs.labels)
|
||||||
|
.map(([k, v]) => `${k}=${v}`)
|
||||||
|
.join(", ")}
|
||||||
|
</TableCell>
|
||||||
|
)}
|
||||||
|
{isColumnVisible("actions") && (
|
||||||
|
<TableCell className="text-right">
|
||||||
<ResourceActionMenu
|
<ResourceActionMenu
|
||||||
actions={[
|
actions={[
|
||||||
{
|
{
|
||||||
@ -126,7 +159,8 @@ export function ReplicaSetList({
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
)}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
@ -184,6 +218,23 @@ export function ReplicaSetList({
|
|||||||
onConfirm={handleDelete}
|
onConfirm={handleDelete}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<ColumnConfigModal
|
||||||
|
open={showColumnConfig}
|
||||||
|
onOpenChange={setShowColumnConfig}
|
||||||
|
resourceType="ReplicaSets"
|
||||||
|
columnConfig={columnConfig}
|
||||||
|
columnLabels={{
|
||||||
|
name: "Name",
|
||||||
|
namespace: "Namespace",
|
||||||
|
desired: "Desired",
|
||||||
|
current: "Current",
|
||||||
|
ready: "Ready",
|
||||||
|
age: "Age",
|
||||||
|
labels: "Labels",
|
||||||
|
actions: "Actions",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import React, { useState } from "react";
|
import React, { useState } from "react";
|
||||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui";
|
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow, Button } from "@/components/ui";
|
||||||
import { Scale, Pencil, Trash2, FileText } from "lucide-react";
|
import { Scale, Pencil, Trash2, FileText, Settings } from "lucide-react";
|
||||||
import type { ReplicationControllerInfo } from "@/lib/tauriCommands";
|
import type { ReplicationControllerInfo } from "@/lib/tauriCommands";
|
||||||
import {
|
import {
|
||||||
scaleReplicationcontrollerCmd,
|
scaleReplicationcontrollerCmd,
|
||||||
@ -12,6 +12,9 @@ import { ConfirmDeleteDialog } from "./ConfirmDeleteDialog";
|
|||||||
import { ScaleModal } from "./ScaleModal";
|
import { ScaleModal } from "./ScaleModal";
|
||||||
import { EditResourceModal } from "./EditResourceModal";
|
import { EditResourceModal } from "./EditResourceModal";
|
||||||
import { WorkloadLogsModal } from "./WorkloadLogsModal";
|
import { WorkloadLogsModal } from "./WorkloadLogsModal";
|
||||||
|
import { useColumnConfig } from "@/hooks/useColumnConfig";
|
||||||
|
import { DEFAULT_COLUMNS } from "@/config/defaultColumns";
|
||||||
|
import { ColumnConfigModal } from "@/components/tables/ColumnConfigModal";
|
||||||
|
|
||||||
interface ReplicationControllerListProps {
|
interface ReplicationControllerListProps {
|
||||||
items: ReplicationControllerInfo[];
|
items: ReplicationControllerInfo[];
|
||||||
@ -36,6 +39,11 @@ export function ReplicationControllerList({
|
|||||||
const [activeModal, setActiveModal] = useState<ActiveModal>(null);
|
const [activeModal, setActiveModal] = useState<ActiveModal>(null);
|
||||||
const [isActing, setIsActing] = useState(false);
|
const [isActing, setIsActing] = useState(false);
|
||||||
const [actionError, setActionError] = useState<string | null>(null);
|
const [actionError, setActionError] = useState<string | null>(null);
|
||||||
|
const [showColumnConfig, setShowColumnConfig] = useState(false);
|
||||||
|
|
||||||
|
// Configurable columns
|
||||||
|
const columnConfig = useColumnConfig("replicationcontrollers", DEFAULT_COLUMNS.replicationcontrollers);
|
||||||
|
const { isColumnVisible } = columnConfig;
|
||||||
|
|
||||||
const openEdit = async (rc: ReplicationControllerInfo) => {
|
const openEdit = async (rc: ReplicationControllerInfo) => {
|
||||||
setActionError(null);
|
setActionError(null);
|
||||||
@ -69,17 +77,31 @@ export function ReplicationControllerList({
|
|||||||
{actionError && (
|
{actionError && (
|
||||||
<p className="mb-2 text-sm text-destructive">{actionError}</p>
|
<p className="mb-2 text-sm text-destructive">{actionError}</p>
|
||||||
)}
|
)}
|
||||||
|
<div className="flex items-center justify-between mb-2">
|
||||||
|
<div className="text-sm text-muted-foreground">
|
||||||
|
{items.length} {items.length === 1 ? "replication controller" : "replication controllers"}
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => setShowColumnConfig(true)}
|
||||||
|
className="flex items-center gap-1"
|
||||||
|
>
|
||||||
|
<Settings className="h-3.5 w-3.5" />
|
||||||
|
Columns
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
<div className="overflow-x-auto">
|
<div className="overflow-x-auto">
|
||||||
<Table>
|
<Table>
|
||||||
<TableHeader>
|
<TableHeader>
|
||||||
<TableRow>
|
<TableRow>
|
||||||
<TableHead>Name</TableHead>
|
{isColumnVisible("name") && <TableHead>Name</TableHead>}
|
||||||
<TableHead>Namespace</TableHead>
|
{isColumnVisible("namespace") && <TableHead>Namespace</TableHead>}
|
||||||
<TableHead>Desired</TableHead>
|
{isColumnVisible("desired") && <TableHead>Desired</TableHead>}
|
||||||
<TableHead>Current</TableHead>
|
{isColumnVisible("current") && <TableHead>Current</TableHead>}
|
||||||
<TableHead>Ready</TableHead>
|
{isColumnVisible("ready") && <TableHead>Ready</TableHead>}
|
||||||
<TableHead>Age</TableHead>
|
{isColumnVisible("age") && <TableHead>Age</TableHead>}
|
||||||
<TableHead className="text-right">Actions</TableHead>
|
{isColumnVisible("actions") && <TableHead className="text-right">Actions</TableHead>}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
</TableHeader>
|
</TableHeader>
|
||||||
<TableBody>
|
<TableBody>
|
||||||
@ -92,13 +114,20 @@ export function ReplicationControllerList({
|
|||||||
) : (
|
) : (
|
||||||
items.map((rc) => (
|
items.map((rc) => (
|
||||||
<TableRow key={`${rc.name}-${rc.namespace}`}>
|
<TableRow key={`${rc.name}-${rc.namespace}`}>
|
||||||
<TableCell className="font-medium">{rc.name}</TableCell>
|
{isColumnVisible("name") && (
|
||||||
<TableCell className="text-muted-foreground">{rc.namespace}</TableCell>
|
<TableCell className="font-medium">{rc.name}</TableCell>
|
||||||
<TableCell>{rc.desired}</TableCell>
|
)}
|
||||||
<TableCell>{rc.current}</TableCell>
|
{isColumnVisible("namespace") && (
|
||||||
<TableCell>{rc.ready}</TableCell>
|
<TableCell className="text-muted-foreground">{rc.namespace}</TableCell>
|
||||||
<TableCell className="text-muted-foreground">{rc.age}</TableCell>
|
)}
|
||||||
<TableCell className="text-right">
|
{isColumnVisible("desired") && <TableCell>{rc.desired}</TableCell>}
|
||||||
|
{isColumnVisible("current") && <TableCell>{rc.current}</TableCell>}
|
||||||
|
{isColumnVisible("ready") && <TableCell>{rc.ready}</TableCell>}
|
||||||
|
{isColumnVisible("age") && (
|
||||||
|
<TableCell className="text-muted-foreground">{rc.age}</TableCell>
|
||||||
|
)}
|
||||||
|
{isColumnVisible("actions") && (
|
||||||
|
<TableCell className="text-right">
|
||||||
<ResourceActionMenu
|
<ResourceActionMenu
|
||||||
actions={[
|
actions={[
|
||||||
{
|
{
|
||||||
@ -124,7 +153,8 @@ export function ReplicationControllerList({
|
|||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>
|
||||||
</TableCell>
|
</TableCell>
|
||||||
|
)}
|
||||||
</TableRow>
|
</TableRow>
|
||||||
))
|
))
|
||||||
)}
|
)}
|
||||||
@ -182,6 +212,22 @@ export function ReplicationControllerList({
|
|||||||
onConfirm={handleDelete}
|
onConfirm={handleDelete}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
<ColumnConfigModal
|
||||||
|
open={showColumnConfig}
|
||||||
|
onOpenChange={setShowColumnConfig}
|
||||||
|
resourceType="ReplicationControllers"
|
||||||
|
columnConfig={columnConfig}
|
||||||
|
columnLabels={{
|
||||||
|
name: "Name",
|
||||||
|
namespace: "Namespace",
|
||||||
|
desired: "Desired",
|
||||||
|
current: "Current",
|
||||||
|
ready: "Ready",
|
||||||
|
age: "Age",
|
||||||
|
actions: "Actions",
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user