Skip to content
Merged
Show file tree
Hide file tree
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 @@ -14,27 +14,23 @@ export function useWorkspaceHostUrl(workspaceId: string | null): string | null {
const collections = useCollections();
const { machineId, activeHostUrl } = useLocalHostService();

const { data: workspaceWithHost = [] } = useLiveQuery(
const { data: workspaceRows = [] } = useLiveQuery(
(q) =>
q
.from({ workspaces: collections.v2Workspaces })
.leftJoin({ hosts: collections.v2Hosts }, ({ workspaces, hosts }) =>
eq(workspaces.hostId, hosts.machineId),
)
.where(({ workspaces }) => eq(workspaces.id, workspaceId ?? ""))
.select(({ workspaces, hosts }) => ({
.select(({ workspaces }) => ({
organizationId: workspaces.organizationId,
hostId: workspaces.hostId,
hostMachineId: hosts?.machineId ?? null,
})),
[collections, workspaceId],
);

const match = workspaceId ? (workspaceWithHost[0] ?? null) : null;
const match = workspaceId ? (workspaceRows[0] ?? null) : null;

return useMemo(() => {
if (!match) return null;
if (match.hostMachineId === machineId) return activeHostUrl;
if (match.hostId === machineId) return activeHostUrl;
const routingKey = buildHostRoutingKey(match.organizationId, match.hostId);
return `${env.RELAY_URL}/hosts/${routingKey}`;
}, [match, machineId, activeHostUrl]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,19 +172,16 @@ describe("deriveHostPortQueryTargets", () => {
id: "workspace-b",
name: "Workspace B",
hostId: "local-machine",
hostMachineId: "local-machine",
},
{
id: "workspace-a",
name: "Workspace A",
hostId: "local-machine",
hostMachineId: "local-machine",
},
{
id: "workspace-c",
name: "Workspace C",
hostId: "remote-machine",
hostMachineId: "remote-machine",
},
],
});
Expand Down Expand Up @@ -227,13 +224,11 @@ describe("deriveHostPortQueryTargets", () => {
id: "workspace-remote",
name: "Remote",
hostId: "remote-machine",
hostMachineId: "remote-machine",
},
{
id: "workspace-local",
name: "Local",
hostId: "local-machine",
hostMachineId: "local-machine",
},
],
});
Expand Down Expand Up @@ -284,19 +279,17 @@ describe("groupDashboardSidebarPorts", () => {
],
},
],
machineId: "machine-1",
machineId: "host-1",
workspaces: [
{
id: "workspace-b",
name: "Beta",
hostId: "host-1",
hostMachineId: "machine-1",
},
{
id: "workspace-a",
name: "Alpha",
hostId: "host-1",
hostMachineId: "machine-1",
},
],
});
Expand Down Expand Up @@ -336,7 +329,6 @@ describe("groupDashboardSidebarPorts", () => {
id: "workspace-1",
name: "Workspace",
hostId: "host-2",
hostMachineId: "machine-2",
},
],
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {
getEventBus,
type PortChangedPayload,
} from "@superset/workspace-client";
import { eq } from "@tanstack/db";
import { useLiveQuery } from "@tanstack/react-db";
import { useQueries, useQueryClient } from "@tanstack/react-query";
import { useEffect, useMemo } from "react";
Expand Down Expand Up @@ -52,14 +51,10 @@ export function useDashboardSidebarPortsData(): {
(q) =>
q
.from({ workspaces: collections.v2Workspaces })
.leftJoin({ hosts: collections.v2Hosts }, ({ workspaces, hosts }) =>
eq(workspaces.hostId, hosts.machineId),
)
.select(({ workspaces, hosts }) => ({
.select(({ workspaces }) => ({
id: workspaces.id,
name: workspaces.name,
hostId: workspaces.hostId,
hostMachineId: hosts?.machineId ?? null,
})),
[collections],
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ export interface DashboardSidebarWorkspaceRow {
id: string;
name: string;
hostId: string;
hostMachineId: string | null | undefined;
}

export function getHostPortsQueryKey(host: HostPortsQueryTarget) {
Expand Down Expand Up @@ -139,7 +138,7 @@ export function deriveHostPortQueryTargets({
workspaceIds.sort();
}

return hosts.flatMap((host) => {
const targets = hosts.flatMap((host) => {
const workspaceIds = workspaceIdsByHostId.get(host.machineId);
if (!workspaceIds || workspaceIds.length === 0) return [];

Expand All @@ -162,6 +161,28 @@ export function deriveHostPortQueryTargets({
},
];
});

// If the local v2Hosts row hasn't synced via Electric, the loop above won't
// include the local machine — which would hide its ports. Synthesize a
// local target from machineId + activeHostUrl whenever workspaces with
// hostId === machineId exist.
if (
machineId &&
activeHostUrl &&
!targets.some((target) => target.machineId === machineId)
) {
const localWorkspaceIds = workspaceIdsByHostId.get(machineId);
if (localWorkspaceIds && localWorkspaceIds.length > 0) {
targets.push({
machineId,
hostType: "local-device",
hostUrl: activeHostUrl,
workspaceIds: localWorkspaceIds,
});
}
}

return targets;
}

export function groupDashboardSidebarPorts({
Expand All @@ -180,11 +201,9 @@ export function groupDashboardSidebarPorts({
name: workspace.name,
hostId: workspace.hostId,
hostType:
workspace.hostMachineId == null
? ("cloud" as const)
: workspace.hostMachineId === machineId
? ("local-device" as const)
: ("remote-device" as const),
workspace.hostId === machineId
? ("local-device" as const)
: ("remote-device" as const),
},
]),
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ export function useDashboardSidebarData() {
({ sidebarWorkspaces, workspaces }) =>
eq(sidebarWorkspaces.workspaceId, workspaces.id),
)
.leftJoin({ hosts: collections.v2Hosts }, ({ workspaces, hosts }) =>
.innerJoin({ hosts: collections.v2Hosts }, ({ workspaces, hosts }) =>
eq(workspaces.hostId, hosts.machineId),
)
.orderBy(
Expand All @@ -243,9 +243,8 @@ export function useDashboardSidebarData() {
id: workspaces.id,
projectId: sidebarWorkspaces.sidebarState.projectId,
hostId: workspaces.hostId,
hostMachineId: hosts?.machineId ?? null,
type: workspaces.type,
hostIsOnline: hosts?.isOnline ?? null,
hostIsOnline: hosts.isOnline,
name: workspaces.name,
branch: workspaces.branch,
createdAt: workspaces.createdAt,
Expand All @@ -271,17 +270,16 @@ export function useDashboardSidebarData() {
(q) =>
q
.from({ workspaces: collections.v2Workspaces })
.leftJoin({ hosts: collections.v2Hosts }, ({ workspaces, hosts }) =>
.innerJoin({ hosts: collections.v2Hosts }, ({ workspaces, hosts }) =>
eq(workspaces.hostId, hosts.machineId),
)
.where(({ workspaces }) => eq(workspaces.type, "main"))
.select(({ workspaces, hosts }) => ({
id: workspaces.id,
projectId: workspaces.projectId,
hostId: workspaces.hostId,
hostMachineId: hosts?.machineId ?? null,
type: workspaces.type,
hostIsOnline: hosts?.isOnline ?? null,
hostIsOnline: hosts.isOnline,
name: workspaces.name,
branch: workspaces.branch,
createdAt: workspaces.createdAt,
Expand All @@ -299,8 +297,7 @@ export function useDashboardSidebarData() {
const autoLocalMainWorkspaces = localMainWorkspaces.filter(
(workspace) =>
!localStateWorkspaceIds.has(workspace.id) &&
workspace.hostMachineId != null &&
workspace.hostMachineId === machineId &&
workspace.hostId === machineId &&
sidebarProjectIds.has(workspace.projectId),
);

Expand All @@ -316,11 +313,7 @@ export function useDashboardSidebarData() {
const computedLocalWorkspaceIds = useMemo(
() =>
visibleSidebarWorkspaces
.filter(
(workspace) =>
workspace.hostMachineId != null &&
workspace.hostMachineId === machineId,
)
.filter((workspace) => workspace.hostId === machineId)
.map((workspace) => workspace.id)
.sort(),
[machineId, visibleSidebarWorkspaces],
Expand Down Expand Up @@ -404,11 +397,7 @@ export function useDashboardSidebarData() {
if (!project) continue;

const hostType: DashboardSidebarWorkspace["hostType"] =
workspace.hostMachineId == null
? "cloud"
: workspace.hostMachineId === machineId
? "local-device"
: "remote-device";
workspace.hostId === machineId ? "local-device" : "remote-device";

const sidebarWorkspace: DashboardSidebarWorkspace = {
id: workspace.id,
Expand All @@ -417,9 +406,7 @@ export function useDashboardSidebarData() {
hostType,
type: workspace.type,
hostIsOnline:
hostType === "remote-device"
? (workspace.hostIsOnline ?? null)
: null,
hostType === "remote-device" ? workspace.hostIsOnline : null,
accentColor: null,
name: workspace.name,
branch: workspace.branch,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,21 @@ export function V2WorkspaceOpenInButton({
const collections = useCollections();
const { machineId, activeHostUrl } = useLocalHostService();

const { data: workspacesWithHost = [] } = useLiveQuery(
const { data: workspaces = [] } = useLiveQuery(
(q) =>
q
.from({ workspaces: collections.v2Workspaces })
.leftJoin({ hosts: collections.v2Hosts }, ({ workspaces, hosts }) =>
eq(workspaces.hostId, hosts.machineId),
)
.where(({ workspaces }) => eq(workspaces.id, workspaceId))
.select(({ workspaces, hosts }) => ({
.select(({ workspaces }) => ({
id: workspaces.id,
branch: workspaces.branch,
projectId: workspaces.projectId,
hostMachineId: hosts?.machineId ?? null,
hostId: workspaces.hostId,
})),
[collections, workspaceId],
);
const workspace = workspacesWithHost[0] ?? null;
const isLocalWorkspace =
Boolean(workspace) && workspace.hostMachineId === machineId;
const workspace = workspaces[0] ?? null;
const isLocalWorkspace = Boolean(workspace) && workspace.hostId === machineId;

const workspaceQuery = useQuery({
queryKey: ["v2-open-in-workspace", activeHostUrl, workspaceId],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,19 @@ export interface OpenInExternalEditorOptions {
export function useOpenInExternalEditor(workspaceId: string) {
const collections = useCollections();
const { machineId } = useLocalHostService();
const { data: workspacesWithHost = [] } = useLiveQuery(
const { data: workspaceRows = [] } = useLiveQuery(
(q) =>
q
.from({ workspaces: collections.v2Workspaces })
.leftJoin({ hosts: collections.v2Hosts }, ({ workspaces, hosts }) =>
eq(workspaces.hostId, hosts.machineId),
)
.where(({ workspaces }) => eq(workspaces.id, workspaceId))
.select(({ workspaces, hosts }) => ({
hostMachineId: hosts?.machineId ?? null,
.select(({ workspaces }) => ({
hostId: workspaces.hostId,
projectId: workspaces.projectId ?? null,
})),
[collections, workspaceId],
);
const workspaceHost = workspacesWithHost[0];
const projectId = workspaceHost?.projectId ?? undefined;
const workspaceRow = workspaceRows[0];
const projectId = workspaceRow?.projectId ?? undefined;

// Forward the v2 CMD+O choice as an explicit app override; the server
// can't look this up on its own (v2 projects aren't in the v1 localDb).
Expand All @@ -44,9 +41,7 @@ export function useOpenInExternalEditor(workspaceId: string) {

return useCallback(
(path: string, opts?: OpenInExternalEditorOptions) => {
// Treat unloaded host data as non-local to avoid firing the mutation
// against a potentially remote workspace before locality is confirmed.
if (workspaceHost?.hostMachineId !== machineId) {
if (workspaceRow?.hostId !== machineId) {
toast.error("Can't open remote workspace paths in an external editor");
return;
}
Expand All @@ -64,6 +59,6 @@ export function useOpenInExternalEditor(workspaceId: string) {
toast.error("Failed to open in external editor");
});
},
[workspaceHost, machineId, projectId, worktreePath, v2PreferredApp],
[workspaceRow, machineId, projectId, worktreePath, v2PreferredApp],
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,27 +31,23 @@ function V2WorkspaceLayout() {
const { machineId, activeHostUrl } = useLocalHostService();
const { ensureWorkspaceInSidebar } = useDashboardSidebarState();

const { data: workspacesWithHost = [], isReady } = useLiveQuery(
const { data: workspaces = [], isReady } = useLiveQuery(
(q) =>
q
.from({ v2Workspaces: collections.v2Workspaces })
.leftJoin({ hosts: collections.v2Hosts }, ({ v2Workspaces, hosts }) =>
eq(v2Workspaces.hostId, hosts.machineId),
)
.where(({ v2Workspaces }) => eq(v2Workspaces.id, workspaceId ?? ""))
.select(({ v2Workspaces, hosts }) => ({
.select(({ v2Workspaces }) => ({
id: v2Workspaces.id,
organizationId: v2Workspaces.organizationId,
hostId: v2Workspaces.hostId,
hostMachineId: hosts?.machineId ?? null,
projectId: v2Workspaces.projectId,
branch: v2Workspaces.branch,
})),
[collections, workspaceId],
);
const workspace = workspacesWithHost[0] ?? null;
const workspace = workspaces[0] ?? null;

const isLocal = workspace?.hostMachineId === machineId;
const isLocal = workspace?.hostId === machineId;
const hostUrl = !workspace
? null
: isLocal
Expand Down
Loading
Loading