Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,18 @@ function getServiceInfo(d: DeploymentRow) {
return null;
}

// Sentinel value for deployments whose service has no remote server set,
// meaning it runs on the local Dokploy server.
const LOCAL_SERVER_VALUE = "__local__";

function getServerInfo(d: DeploymentRow) {
const server = d.server ?? d.application?.server ?? d.compose?.server ?? null;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Include build servers in the server filter

When an application deployment uses a separate build server, this helper returns only d.server/application.server/compose.server, while the same table’s Server column also renders d.buildServer/application.buildServer. In that case the dropdown either omits the build server entirely, or selecting that server excludes deployments that visibly list it under “Build:”, so filtering by the server shown in the table gives incomplete results.

Useful? React with 👍 / 👎.

if (server) {
return { serverId: server.serverId, name: server.name };
}
return null;
}

export function ShowDeploymentsTable() {
const [sorting, setSorting] = useState<SortingState>([
{ id: "createdAt", desc: true },
Expand All @@ -102,6 +114,7 @@ export function ShowDeploymentsTable() {
const [globalFilter, setGlobalFilter] = useState("");
const [statusFilter, setStatusFilter] = useState<string>("all");
const [typeFilter, setTypeFilter] = useState<string>("all");
const [serverFilter, setServerFilter] = useState<string>("all");
const [pagination, setPagination] = useState<PaginationState>({
pageIndex: 0,
pageSize: 50,
Expand All @@ -112,6 +125,24 @@ export function ShowDeploymentsTable() {
refetchInterval: 5000,
});

const serverOptions = useMemo(() => {
const map = new Map<string, string>();
let hasLocal = false;
for (const d of deploymentsList ?? []) {
const info = getServerInfo(d);
if (info) {
map.set(info.serverId, info.name);
} else {
hasLocal = true;
}
}
const options = Array.from(map, ([serverId, name]) => ({
serverId,
name,
})).sort((a, b) => a.name.localeCompare(b.name));
return { options, hasLocal };
}, [deploymentsList]);

const filteredData = useMemo(() => {
if (!deploymentsList) return [];
let list = deploymentsList;
Expand All @@ -123,6 +154,13 @@ export function ShowDeploymentsTable() {
} else if (typeFilter === "compose") {
list = list.filter((d) => d.composeId != null);
}
if (serverFilter !== "all") {
list = list.filter((d) => {
const info = getServerInfo(d);
if (serverFilter === LOCAL_SERVER_VALUE) return info === null;
return info?.serverId === serverFilter;
});
}
if (globalFilter.trim()) {
const q = globalFilter.toLowerCase();
list = list.filter((d) => {
Expand All @@ -146,7 +184,7 @@ export function ShowDeploymentsTable() {
});
}
return list;
}, [deploymentsList, statusFilter, typeFilter, globalFilter]);
}, [deploymentsList, statusFilter, typeFilter, serverFilter, globalFilter]);

const columns = useMemo(
() => [
Expand Down Expand Up @@ -482,6 +520,22 @@ export function ShowDeploymentsTable() {
<SelectItem value="compose">Compose</SelectItem>
</SelectContent>
</Select>
<Select value={serverFilter} onValueChange={setServerFilter}>
<SelectTrigger className="w-[160px]">
<SelectValue placeholder="Server" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all">All servers</SelectItem>
{serverOptions.hasLocal && (
<SelectItem value={LOCAL_SERVER_VALUE}>Dokploy</SelectItem>
)}
{serverOptions.options.map((server) => (
<SelectItem key={server.serverId} value={server.serverId}>
{server.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="px-0">
{isLoading ? (
Expand Down
Loading