Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,11 @@
} from "@rilldata/web-common/components/tabs";
import Tooltip from "@rilldata/web-common/components/tooltip/Tooltip.svelte";
import TooltipContent from "@rilldata/web-common/components/tooltip/TooltipContent.svelte";
import { featureFlags } from "@rilldata/web-common/features/feature-flags";
import { useFeatureFlags } from "@rilldata/web-common/features/feature-flags";

export let createMagicAuthTokens: boolean;

const { hidePublicUrl } = featureFlags;
const { hidePublicUrl } = useFeatureFlags();
let isOpen = false;
let copied = false;

Expand Down
4 changes: 2 additions & 2 deletions web-admin/src/features/embeds/EmbedHeader.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import BreadcrumbItem from "@rilldata/web-common/components/navigation/breadcrumbs/BreadcrumbItem.svelte";
import TwoTieredBreadcrumbItem from "@rilldata/web-common/components/navigation/breadcrumbs/TwoTieredBreadcrumbItem.svelte";
import { useValidDashboards } from "@rilldata/web-common/features/dashboards/selectors";
import { featureFlags } from "@rilldata/web-common/features/feature-flags";
import { useFeatureFlags } from "@rilldata/web-common/features/feature-flags";
import LastRefreshedDate from "@rilldata/web-admin/features/dashboards/listing/LastRefreshedDate.svelte";
import ChatToggle from "@rilldata/web-common/features/chat/layouts/sidebar/ChatToggle.svelte";
import type {
Expand All @@ -16,7 +16,7 @@
export let navigationEnabled: boolean = true;

const runtimeClient = useRuntimeClient();
const { twoTieredNavigation, dashboardChat } = featureFlags;
const { twoTieredNavigation, dashboardChat } = useFeatureFlags();

$: onProjectPage = !activeResource;
$: showDashboardChat = $dashboardChat && !onProjectPage;
Expand Down
46 changes: 46 additions & 0 deletions web-admin/src/features/embeds/EmbedShell.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<script lang="ts">
import EmbedHeader from "@rilldata/web-admin/features/embeds/EmbedHeader.svelte";
import DashboardChat from "@rilldata/web-common/features/chat/DashboardChat.svelte";
import ThemeProvider from "@rilldata/web-common/features/dashboards/ThemeProvider.svelte";
import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors.ts";
import { useFeatureFlags } from "@rilldata/web-common/features/feature-flags";
import { activeDashboardTheme } from "@rilldata/web-common/features/themes/active-dashboard-theme";

export let activeResource: { kind: ResourceKind; name: string };
export let navigationEnabled: boolean;
export let onProjectPage: boolean;

const { dashboardChat } = useFeatureFlags();

$: showDashboardChat = $dashboardChat && !onProjectPage;
// Resource kind can be metrics view in some cases. But internally to render it will have to have an equivalent explore.
$: correctedKindForChat =
activeResource?.kind === ResourceKind.MetricsView
? ResourceKind.Explore
: (activeResource?.kind as
| ResourceKind.Explore
| ResourceKind.Canvas
| undefined);

$: showTopBar = navigationEnabled || showDashboardChat;
</script>

{#if showTopBar}
<ThemeProvider theme={$activeDashboardTheme} applyLayout={false}>
<div
class="flex items-center w-full pr-4 py-1 min-h-[2.5rem] bg-surface-subtle"
class:border-b={!onProjectPage}
>
<EmbedHeader {activeResource} {navigationEnabled} />
</div>
</ThemeProvider>
{/if}

<div class="flex h-full overflow-hidden">
<div class="flex-1 overflow-hidden">
<slot />
</div>
{#if showDashboardChat && correctedKindForChat}
<DashboardChat kind={correctedKindForChat} />
{/if}
</div>
4 changes: 2 additions & 2 deletions web-admin/src/features/projects/ProjectHeader.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import StateManagersProvider from "@rilldata/web-common/features/dashboards/state-managers/StateManagersProvider.svelte";
import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors";
import { useExplore } from "@rilldata/web-common/features/explores/selectors";
import { featureFlags } from "@rilldata/web-common/features/feature-flags";
import { useFeatureFlags } from "@rilldata/web-common/features/feature-flags";
import Header from "@rilldata/web-common/layout/header/Header.svelte";
import HeaderLogo from "@rilldata/web-common/layout/header/HeaderLogo.svelte";
import { useRuntimeClient } from "@rilldata/web-common/runtime-client/v2";
Expand Down Expand Up @@ -62,7 +62,7 @@
dimensionSearch,
dashboardChat,
stickyDashboardState,
} = featureFlags;
} = useFeatureFlags();

$: ({
params: { dashboard, alert, report },
Expand Down
4 changes: 2 additions & 2 deletions web-admin/src/features/projects/ProjectTabs.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +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 { featureFlags } from "@rilldata/web-common/features/feature-flags";
import { useFeatureFlags } from "@rilldata/web-common/features/feature-flags";
import { type V1ProjectPermissions } from "../../client";

export let projectPermissions: V1ProjectPermissions;
Expand All @@ -14,7 +14,7 @@
export let pathname: string;
export let branchPrefix: string = "";

const { chat, reports, alerts } = featureFlags;
const { chat, reports, alerts } = useFeatureFlags();

$: tabs = [
{
Expand Down
8 changes: 6 additions & 2 deletions web-admin/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
import { initCloudMetrics } from "@rilldata/web-admin/features/telemetry/initCloudMetrics";
import BannerCenter from "@rilldata/web-common/components/banner/BannerCenter.svelte";
import NotificationCenter from "@rilldata/web-common/components/notifications/NotificationCenter.svelte";
import { featureFlags } from "@rilldata/web-common/features/feature-flags";
import {
adminServer,
readOnly,
} from "@rilldata/web-common/features/app-flags";
import { initPylonWidget } from "@rilldata/web-common/features/help/initPylonWidget";
import { isEmbedPage } from "@rilldata/web-common/layout/navigation/navigation-utils.ts";
import { eventBus } from "@rilldata/web-common/lib/event-bus/event-bus.ts";
Expand Down Expand Up @@ -74,7 +77,8 @@

// The admin server enables some dashboard features like scheduled reports and alerts
// Set read-only mode so that the user can't edit the dashboard
featureFlags.set(true, "adminServer", "readOnly");
adminServer.set(true);
readOnly.set(true);

let removeJavascriptListeners: () => void;

Expand Down
45 changes: 6 additions & 39 deletions web-admin/src/routes/-/embed/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,12 @@
getDashboardFromEmbedRoute,
isDifferentDashboard,
} from "@rilldata/web-admin/features/embeds/embed-route-utils.ts";
import EmbedShell from "@rilldata/web-admin/features/embeds/EmbedShell.svelte";
import initEmbedPublicAPI from "@rilldata/web-admin/features/embeds/init-embed-public-api.ts";
import EmbedHeader from "@rilldata/web-admin/features/embeds/EmbedHeader.svelte";
import ErrorPage from "@rilldata/web-common/components/ErrorPage.svelte";
import { VegaLiteTooltipHandler } from "@rilldata/web-common/components/vega/vega-tooltip.ts";
import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors.ts";
import { featureFlags } from "@rilldata/web-common/features/feature-flags";
import DashboardChat from "@rilldata/web-common/features/chat/DashboardChat.svelte";
import ThemeProvider from "@rilldata/web-common/features/dashboards/ThemeProvider.svelte";
import { activeDashboardTheme } from "@rilldata/web-common/features/themes/active-dashboard-theme";
import { adminServer } from "@rilldata/web-common/features/app-flags";
import {
createIframeRPCHandler,
emitNotification,
Expand All @@ -32,11 +29,9 @@
accessToken,
} = data;

const { dashboardChat } = featureFlags;

// Embedded dashboards communicate directly with the project runtime and do not communicate with the admin server.
// One by-product of this is that they have no access to control plane features like alerts, bookmarks, and scheduled reports.
featureFlags.set(false, "adminServer");
adminServer.set(false);

// Extract active resource info from current route
// Falls back to Canvas if route doesn't match a dashboard pattern (e.g., project page)
Expand All @@ -50,18 +45,6 @@

$: onProjectPage = !activeResource;

$: showDashboardChat = $dashboardChat && !onProjectPage;
// Resource kind can be metrics view in some cases. But internally to render it will have to have an equivalent explore.
$: correctedKindForChat =
activeResource?.kind === ResourceKind.MetricsView
? ResourceKind.Explore
: (activeResource?.kind as
| ResourceKind.Explore
| ResourceKind.Canvas
| undefined);

$: showTopBar = navigationEnabled || showDashboardChat;

// Suppress browser back/forward
beforeNavigate((nav) => {
if (!navigationEnabled) {
Expand Down Expand Up @@ -135,24 +118,8 @@
jwt={accessToken}
authContext="embed"
>
{#if showTopBar}
<ThemeProvider theme={$activeDashboardTheme} applyLayout={false}>
<div
class="flex items-center w-full pr-4 py-1 min-h-[2.5rem] bg-surface-subtle"
class:border-b={!onProjectPage}
>
<EmbedHeader {activeResource} {navigationEnabled} />
</div>
</ThemeProvider>
{/if}

<div class="flex h-full overflow-hidden">
<div class="flex-1 overflow-hidden">
<slot />
</div>
{#if showDashboardChat && correctedKindForChat}
<DashboardChat kind={correctedKindForChat} />
{/if}
</div>
<EmbedShell {activeResource} {navigationEnabled} {onProjectPage}>
<slot />
</EmbedShell>
</RuntimeProvider>
{/if}
4 changes: 2 additions & 2 deletions web-admin/src/routes/[organization]/[project]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
import DashboardsTable from "@rilldata/web-admin/features/dashboards/listing/DashboardsTable.svelte";
import InlineChat from "@rilldata/web-common/features/chat/layouts/inline/InlineChat.svelte";
import DelayedContent from "@rilldata/web-common/features/entity-management/DelayedContent.svelte";
import { featureFlags } from "@rilldata/web-common/features/feature-flags";
import { useFeatureFlags } from "@rilldata/web-common/features/feature-flags";
import { createRuntimeServiceGetInstance } from "@rilldata/web-common/runtime-client";
import { useRuntimeClient } from "@rilldata/web-common/runtime-client/v2";

const { chat } = featureFlags;
const { chat } = useFeatureFlags();

const runtimeClient = useRuntimeClient();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
} from "@rilldata/web-common/features/add-data/manager/steps/import.ts";
import { onMount } from "svelte";
import { useRuntimeClient } from "@rilldata/web-common/runtime-client/v2";
import { useFeatureFlags } from "@rilldata/web-common/features/feature-flags";
import { addLeadingSlash } from "@rilldata/web-common/features/entity-management/entity-mappers.ts";
import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient.ts";
import {
Expand All @@ -35,6 +36,7 @@
export let onDone: () => void;

const runtimeClient = useRuntimeClient();
const { ai } = useFeatureFlags();
const initialAddDataStep = { ...importAddDataStep };

const StepLabels = [
Expand Down Expand Up @@ -98,6 +100,7 @@
}
}
},
$ai,
);
onDone();
return goto(currentFileRoute);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
} from "@rilldata/web-common/features/metrics-views/ai-generation/generateMetricsView.ts";
import { MetricsEventSpace } from "@rilldata/web-common/metrics/service/MetricsTypes.ts";
import { BehaviourEventMedium } from "@rilldata/web-common/metrics/service/BehaviourEventTypes.ts";
import { featureFlags } from "@rilldata/web-common/features/feature-flags.ts";
import { useFeatureFlags } from "@rilldata/web-common/features/feature-flags";
import { addLeadingSlash } from "@rilldata/web-common/features/entity-management/entity-mappers.ts";
import {
getFileHref,
Expand All @@ -34,7 +34,7 @@
export let importAddDataStep: ImportAddDataStep;
export let onDone: () => void;

const { ai, developerChat } = featureFlags;
const { ai, developerChat } = useFeatureFlags();

const runtimeClient = useRuntimeClient();

Expand All @@ -55,6 +55,7 @@
sourceName,
BehaviourEventMedium.Button,
MetricsEventSpace.Modal,
$ai,
);

async function runImport() {
Expand All @@ -73,6 +74,7 @@
}
}
},
$ai,
);
} catch (e) {
error = e?.response?.data?.message ?? e?.message ?? "Unknown error";
Expand All @@ -89,6 +91,7 @@
"",
"",
sourceName,
$ai,
);
} else {
await createDashboardFromTable();
Expand Down
21 changes: 15 additions & 6 deletions web-common/src/features/add-data/manager/steps/import.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,11 @@ import {
import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors.ts";
import { fileArtifacts } from "@rilldata/web-common/features/entity-management/file-artifacts.ts";
import { queryClient } from "@rilldata/web-common/lib/svelte-query/globalQueryClient.ts";
import { get } from "svelte/store";
import { RuntimeClient } from "@rilldata/web-common/runtime-client/v2";
import {
compileSourceYAML,
inferModelNameFromSQL,
} from "@rilldata/web-common/features/sources/sourceUtils.ts";
import { featureFlags } from "@rilldata/web-common/features/feature-flags.ts";
import { generateBlobForNewResourceFile } from "@rilldata/web-common/features/entity-management/add/new-files.ts";
import { getName } from "@rilldata/web-common/features/entity-management/name-utils.ts";
import type { QueryClient } from "@tanstack/svelte-query";
Expand All @@ -46,6 +44,7 @@ export async function runImportSteps(
step: ImportDataStep,
currentFilePath: string | undefined,
) => void,
isAiEnabled: boolean,
) {
for (const step of addDataStep.config.importSteps) {
fireImportStepEvent(addDataConfig, addDataStep, step);
Expand All @@ -56,13 +55,21 @@ export async function runImportSteps(
break;
case ImportDataStep.CreateMetricsView:
onProgress(step, addDataStep.config.importTo.metricsViewPath);
await runCreateMetricsViewStep(runtimeClient, addDataStep.config);
await runCreateMetricsViewStep(
runtimeClient,
addDataStep.config,
isAiEnabled,
);
break;
case ImportDataStep.CreateDashboard:
onProgress(step, addDataStep.config.importTo.explorePath);
await runCreateExploreStep(runtimeClient, addDataStep.config);
onProgress(step, addDataStep.config.importTo.canvasPath);
await runCreateCanvasStep(runtimeClient, addDataStep.config);
await runCreateCanvasStep(
runtimeClient,
addDataStep.config,
isAiEnabled,
);
break;
}
}
Expand Down Expand Up @@ -286,6 +293,7 @@ async function runCreateModelStep(
async function runCreateMetricsViewStep(
runtimeClient: RuntimeClient,
config: ImportStepConfig,
isAiEnabled: boolean,
) {
// Validate metrics view name and path are generated upstream
const importToConfig = config.importTo;
Expand Down Expand Up @@ -330,7 +338,7 @@ async function runCreateMetricsViewStep(
database,
databaseSchema,
path: importToConfig.metricsViewPath,
useAi: get(featureFlags.ai),
useAi: isAiEnabled,
});
// Wait for the metrics view to successfully reconcile
await waitForResourceReconciliation(
Expand Down Expand Up @@ -385,6 +393,7 @@ async function runCreateExploreStep(
async function runCreateCanvasStep(
runtimeClient: RuntimeClient,
config: ImportStepConfig,
isAiEnabled: boolean,
) {
// Validate canvas name and path are generated upstream
const importToConfig = config.importTo;
Expand All @@ -395,7 +404,7 @@ async function runCreateCanvasStep(
await runtimeServiceGenerateCanvasFile(runtimeClient, {
metricsViewName: importToConfig.metricsViewName,
path: importToConfig.canvasPath,
useAi: get(featureFlags.ai),
useAi: isAiEnabled,
});

// Wait for canvas to reconcile
Expand Down
14 changes: 14 additions & 0 deletions web-common/src/features/app-flags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { writable } from "svelte/store";

// ── App-wide flags ─────────────────────────────────────────────────────
//
// These flags depend on which frontend app is running (web-admin, web-local,
// or an embed iframe), not on which Rill runtime is connected. Each app's
// root layout seeds them at startup; child layouts (e.g. embed) override
// where needed.

export const adminServer = writable(false);
export const readOnly = writable(false);
export const legacyArchiveDeploy = writable(
!!import.meta.env.VITE_PLAYWRIGHT_TEST,
);
Loading
Loading