Skip to content
Open
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
96 changes: 54 additions & 42 deletions web-admin/src/features/projects/ProjectTabs.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
} from "@rilldata/web-admin//components/nav/Tab.svelte";
import Tab from "@rilldata/web-admin/components/nav/Tab.svelte";
import { removeBranchFromPath } from "@rilldata/web-admin/features/branches/branch-utils";
import { viewAsUserStore } from "@rilldata/web-admin/features/view-as-user/viewAsUserStore";
import { featureFlags } from "@rilldata/web-common/features/feature-flags";
import { type V1ProjectPermissions } from "../../client";

Expand All @@ -16,48 +17,59 @@

const { chat, reports, alerts } = featureFlags;

$: tabs = [
{
route: `/${organization}/${project}${branchPrefix}`,
label: "Home",
hasPermission: true,
},
{
route: `/${organization}/${project}${branchPrefix}/-/ai`,
label: "AI",
hasPermission: $chat,
},
{
route: `/${organization}/${project}${branchPrefix}/-/dashboards`,
label: "Dashboards",
hasPermission: true,
},
{
route: `/${organization}/${project}${branchPrefix}/-/query`,
label: "Query",
hasPermission: false,
},
{
route: `/${organization}/${project}${branchPrefix}/-/reports`,
label: "Reports",
hasPermission: $reports,
},
{
route: `/${organization}/${project}${branchPrefix}/-/alerts`,
label: "Alerts",
hasPermission: $alerts,
},
{
route: `/${organization}/${project}${branchPrefix}/-/status`,
label: "Status",
hasPermission: projectPermissions.manageProject,
},
{
route: `/${organization}/${project}${branchPrefix}/-/settings`,
label: "Settings",
hasPermission: projectPermissions.manageProject,
},
];
// While "View As" is active, the project view is scoped to dashboards
// only — other tabs (Home, AI, Reports, Alerts, Status, Settings) are
// hidden and their routes redirect in the project layout.
$: tabs = $viewAsUserStore
? [
{
route: `/${organization}/${project}${branchPrefix}/-/dashboards`,
label: "Dashboards",
hasPermission: true,
},
]
: [
{
route: `/${organization}/${project}${branchPrefix}`,
label: "Home",
hasPermission: true,
},
{
route: `/${organization}/${project}${branchPrefix}/-/ai`,
label: "AI",
hasPermission: $chat,
},
{
route: `/${organization}/${project}${branchPrefix}/-/dashboards`,
label: "Dashboards",
hasPermission: true,
},
{
route: `/${organization}/${project}${branchPrefix}/-/query`,
label: "Query",
hasPermission: false,
},
{
route: `/${organization}/${project}${branchPrefix}/-/reports`,
label: "Reports",
hasPermission: $reports,
},
{
route: `/${organization}/${project}${branchPrefix}/-/alerts`,
label: "Alerts",
hasPermission: $alerts,
},
{
route: `/${organization}/${project}${branchPrefix}/-/status`,
label: "Status",
hasPermission: projectPermissions.manageProject,
},
{
route: `/${organization}/${project}${branchPrefix}/-/settings`,
label: "Settings",
hasPermission: projectPermissions.manageProject,
},
];

$: selectedIndex = tabs?.findLastIndex((t) => isSelected(t.route, pathname));

Expand Down
16 changes: 16 additions & 0 deletions web-admin/src/routes/[organization]/[project]/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
branchPathPrefix,
extractBranchFromPath,
handleBranchNavigation,
removeBranchFromPath,
} from "@rilldata/web-admin/features/branches/branch-utils";
import {
V1DeploymentStatus,
Expand Down Expand Up @@ -109,6 +110,21 @@
};
});

// While "View As" is active, scope the project view to dashboards only.
// Any other project page (Home, AI, Reports, Alerts, Status, Settings) is
// redirected — entering View As is a deliberate "see what they see" mode,
// and admin surfaces aren't part of that.
$effect(() => {
if (!$viewAsUserStore) return;
if (!onProjectPage) return;
const dashboardsPath = `/${organization}/${project}${branchPrefix}/-/dashboards`;
const normalizedPath = removeBranchFromPath(page.url.pathname);
const normalizedDashboards = removeBranchFromPath(dashboardsPath);
if (!normalizedPath.startsWith(normalizedDashboards)) {
void goto(dashboardsPath);
}
});

// --- Queries (three auth strategies; cookie and token are mutually exclusive,
// mock is an overlay that runs in parallel when View As is active) ---

Expand Down
Loading