@@ -35,7 +36,7 @@
-
Danger Zone
+
{m.settings_danger_zone_title()}
diff --git a/web-admin/src/routes/[organization]/[project]/-/settings/environment-variables/+page.svelte b/web-admin/src/routes/[organization]/[project]/-/settings/environment-variables/+page.svelte
index 87fb47c4923..065c2b36c6a 100644
--- a/web-admin/src/routes/[organization]/[project]/-/settings/environment-variables/+page.svelte
+++ b/web-admin/src/routes/[organization]/[project]/-/settings/environment-variables/+page.svelte
@@ -17,6 +17,7 @@
parseArrayParam,
parseStringParam,
} from "@rilldata/web-common/lib/url-filter-sync";
+ import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
import { Plus } from "lucide-svelte";
import { onMount } from "svelte";
@@ -111,16 +112,16 @@
$: emptyTextWhenNoVariables =
envFilter.length === 0
- ? "No environment variables"
- : `No environment variables match the selected filters`;
+ ? m.env_no_variables()
+ : m.env_no_match_filters();
$: filterGroups = [
{
- label: "Environment",
+ label: m.env_environment_label(),
key: "environment",
options: [
- { value: EnvironmentType.PRODUCTION, label: "Production" },
- { value: EnvironmentType.DEVELOPMENT, label: "Development" },
+ { value: EnvironmentType.PRODUCTION, label: m.env_production_label() },
+ { value: EnvironmentType.DEVELOPMENT, label: m.env_development_label() },
],
selected: envFilter,
defaultValue: [],
@@ -135,19 +136,19 @@
{:else if $getProjectVariables.isError}
- Error loading environment variables: {$getProjectVariables.error}
+ {m.env_error_loading()} {$getProjectVariables.error}
{:else if $getProjectVariables.isSuccess}
@@ -160,7 +161,7 @@
showSort={false}
>
(open = true)}>
- New key
+ {m.env_new_key_button()}
{:else if $magicAuthTokensInfiniteQuery.isError}
- Error loading public URLs
+ {m.public_url_error_loading()}
{:else}
diff --git a/web-admin/src/routes/[organization]/[project]/-/share/[token]/+page.ts b/web-admin/src/routes/[organization]/[project]/-/share/[token]/+page.ts
index 34dac8c08ef..f7f87ff4a54 100644
--- a/web-admin/src/routes/[organization]/[project]/-/share/[token]/+page.ts
+++ b/web-admin/src/routes/[organization]/[project]/-/share/[token]/+page.ts
@@ -1,5 +1,6 @@
import { fetchMagicAuthToken } from "@rilldata/web-admin/features/projects/selectors";
import { ResourceKind } from "@rilldata/web-common/features/entity-management/resource-selectors.js";
+import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
import { error, redirect } from "@sveltejs/kit";
export const load = async ({
@@ -9,13 +10,13 @@ export const load = async ({
// Public URLs specify the resource in the token's metadata
const tokenResp = await fetchMagicAuthToken(token).catch((e) => {
console.error(e);
- throw error(404, "Unable to find token");
+ throw error(404, m.route_error_token_not_found());
});
const { token: tokenMetadata } = tokenResp;
if (!tokenMetadata?.resources) {
console.error("Token does not have any associated resources");
- throw error(404, "Unable to find the token's resource");
+ throw error(404, m.route_error_token_resource_not_found());
}
// Check for explore resource
@@ -30,7 +31,7 @@ export const load = async ({
if (!exploreResource && !canvasResource) {
console.error("Token does not have an associated explore or canvas");
- throw error(404, "Unable to find a dashboard");
+ throw error(404, m.route_error_dashboard_not_found());
}
// Determine which resource type to redirect to
diff --git a/web-admin/src/routes/[organization]/[project]/-/share/[token]/canvas/[dashboard]/+page.svelte b/web-admin/src/routes/[organization]/[project]/-/share/[token]/canvas/[dashboard]/+page.svelte
index 385a5634316..b24bd71b5f2 100644
--- a/web-admin/src/routes/[organization]/[project]/-/share/[token]/canvas/[dashboard]/+page.svelte
+++ b/web-admin/src/routes/[organization]/[project]/-/share/[token]/canvas/[dashboard]/+page.svelte
@@ -9,6 +9,7 @@
import CanvasDashboardEmbed from "@rilldata/web-common/features/canvas/CanvasDashboardEmbed.svelte";
import CanvasProvider from "@rilldata/web-common/features/canvas/CanvasProvider.svelte";
import { eventBus } from "@rilldata/web-common/lib/event-bus/event-bus";
+ import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
import { useRuntimeClient } from "@rilldata/web-common/runtime-client/v2";
const runtimeClient = useRuntimeClient();
@@ -24,7 +25,9 @@
priority: TokenBannerPriority,
message: {
type: "default",
- message: `Limited view. For full access and features, visit the
original dashboard .`,
+ message: m.share_limited_view({
+ link: `
${m.share_original_dashboard()} `,
+ }),
includesHtml: true,
iconType: "alert",
},
diff --git a/web-admin/src/routes/[organization]/[project]/-/share/[token]/explore/[dashboard]/+page.svelte b/web-admin/src/routes/[organization]/[project]/-/share/[token]/explore/[dashboard]/+page.svelte
index f00814cf55a..75ce89625ea 100644
--- a/web-admin/src/routes/[organization]/[project]/-/share/[token]/explore/[dashboard]/+page.svelte
+++ b/web-admin/src/routes/[organization]/[project]/-/share/[token]/explore/[dashboard]/+page.svelte
@@ -10,6 +10,7 @@
import StateManagersProvider from "@rilldata/web-common/features/dashboards/state-managers/StateManagersProvider.svelte";
import DashboardStateManager from "@rilldata/web-common/features/dashboards/state-managers/loaders/DashboardStateManager.svelte";
import { eventBus } from "@rilldata/web-common/lib/event-bus/event-bus";
+ import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
import { createRuntimeServiceGetExplore } from "@rilldata/web-common/runtime-client";
import { useRuntimeClient } from "@rilldata/web-common/runtime-client/v2";
@@ -26,7 +27,9 @@
priority: TokenBannerPriority,
message: {
type: "default",
- message: `Limited view. For full access and features, visit the
original dashboard .`,
+ message: m.share_limited_view({
+ link: `
${m.share_original_dashboard()} `,
+ }),
includesHtml: true,
iconType: "alert",
},
diff --git a/web-admin/src/routes/[organization]/[project]/-/status/+layout.svelte b/web-admin/src/routes/[organization]/[project]/-/status/+layout.svelte
index b968f9f6151..f8806c07908 100644
--- a/web-admin/src/routes/[organization]/[project]/-/status/+layout.svelte
+++ b/web-admin/src/routes/[organization]/[project]/-/status/+layout.svelte
@@ -5,49 +5,50 @@
import ContentContainer from "@rilldata/web-common/components/layout/ContentContainer.svelte";
import LeftNav from "@rilldata/web-admin/components/nav/LeftNav.svelte";
import { featureFlags } from "@rilldata/web-common/features/feature-flags.ts";
+ import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
$: basePage = `/${$page.params.organization}/${$page.params.project}/-/status`;
const { cloudEditing } = featureFlags;
$: navItems = [
{
- label: "Overview",
+ label: m.status_nav_overview(),
route: "",
hasPermission: true,
},
...($cloudEditing
? [
{
- label: "Branches",
+ label: m.status_nav_branches(),
route: "/branches",
hasPermission: true,
},
]
: []),
{
- label: "Resources",
+ label: m.status_nav_resources(),
route: "/resources",
hasPermission: true,
},
{
- label: "Tables",
+ label: m.status_nav_tables(),
route: "/tables",
hasPermission: true,
},
{
- label: "Logs",
+ label: m.status_nav_logs(),
route: "/logs",
hasPermission: true,
},
{
- label: "Analytics",
+ label: m.status_nav_analytics(),
route: "/analytics",
hasPermission: false,
},
];
-
+
{#if !fatal && !onEmbedPage}
- Back to home
+ {m.error_back_to_home()}
{/if}
{/if}
@@ -43,9 +44,9 @@
onclick={() => (showDetail = !showDetail)}
>
{#if !showDetail}
- Show details
+ {m.error_show_details()}
{:else}
- Hide details
+ {m.error_hide_details()}
{/if}
{#if showDetail}
diff --git a/web-common/src/components/alert-dialog/alert-dialog-guarded-confirmation.svelte b/web-common/src/components/alert-dialog/alert-dialog-guarded-confirmation.svelte
index 5b7cd14b69e..197ad18fb95 100644
--- a/web-common/src/components/alert-dialog/alert-dialog-guarded-confirmation.svelte
+++ b/web-common/src/components/alert-dialog/alert-dialog-guarded-confirmation.svelte
@@ -14,13 +14,15 @@
} from "@rilldata/web-common/components/button/index.js";
import Input from "@rilldata/web-common/components/forms/Input.svelte";
import AlertCircleOutline from "@rilldata/web-common/components/icons/AlertCircleOutline.svelte";
+ import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
+ import { escapeHtml } from "@rilldata/web-common/lib/i18n";
export let open = false;
export let title: string;
export let description: string;
export let confirmText: string;
- export let confirmButtonText: string = "Continue";
+ export let confirmButtonText: string = m.common_continue();
export let confirmButtonType: ButtonType = "primary";
export let loading: boolean;
@@ -59,12 +61,14 @@
{description}
- Type {confirmText} in the box below to confirm:
+ {@html m.common_type_to_confirm({
+ text: `${escapeHtml(confirmText)} `,
+ })}
{#if error}
@@ -78,7 +82,7 @@
type={confirmButtonType === "destructive" ? "tertiary" : "secondary"}
onClick={close}
>
- Cancel
+ {m.common_cancel()}
+ import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
import AvatarListItem from "../avatar/AvatarListItem.svelte";
import { Combobox } from "bits-ui";
import { Check } from "lucide-svelte";
@@ -12,7 +13,7 @@
export let options: Option[] = [];
export let searchValue = "";
- export let placeholder = "Search";
+ export let placeholder: string | undefined = undefined;
export let disabled = false;
export let required = false;
export let error: string | undefined = undefined;
@@ -26,6 +27,8 @@
export let loadMore: (() => void | Promise) | undefined = undefined;
export let onSelectedChange: (value: string[]) => void = () => {};
+ $: resolvedPlaceholder = placeholder ?? m.common_search();
+
const LOAD_MORE_THRESHOLD_PX = 24;
let contentEl: HTMLElement | null = null;
@@ -104,8 +107,8 @@
>
{#if filteredItems.length === 0}
- No results found
+
+ {m.common_no_results()}
+
{:else}
{#each filteredItems as item (item.value)}
+ import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
import type { Snippet } from "svelte";
import { clamp } from "@rilldata/web-common/lib/clamp";
@@ -202,7 +203,7 @@
{:else}
{/if}
diff --git a/web-common/src/components/forms/Select.svelte b/web-common/src/components/forms/Select.svelte
index ad386b50456..d3b37a2c992 100644
--- a/web-common/src/components/forms/Select.svelte
+++ b/web-common/src/components/forms/Select.svelte
@@ -5,6 +5,7 @@
import Spinner from "@rilldata/web-common/features/entity-management/Spinner.svelte";
import { EntityStatus } from "@rilldata/web-common/features/entity-management/types.ts";
import { InfoIcon, X } from "lucide-svelte";
+ import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
import DataTypeIcon from "../data-types/DataTypeIcon.svelte";
import Search from "../search/Search.svelte";
import type { ComponentType, SvelteComponent } from "svelte";
@@ -89,7 +90,7 @@
{label}
{#if optional}
- (optional)
+ {m.form_optional()}
{/if}
{#if tooltip}
@@ -226,7 +227,9 @@
{/if}
{:else}
- No results found
+
+ {m.common_no_results()}
+
{/each}
{#if onAddNew}
diff --git a/web-common/src/components/i18n/LanguageSwitcher.spec.ts b/web-common/src/components/i18n/LanguageSwitcher.spec.ts
new file mode 100644
index 00000000000..3e2b6ad62ad
--- /dev/null
+++ b/web-common/src/components/i18n/LanguageSwitcher.spec.ts
@@ -0,0 +1,45 @@
+import { fireEvent, render, screen } from "@testing-library/svelte";
+import { beforeEach, describe, expect, it, vi } from "vitest";
+
+vi.mock("@rilldata/web-common/components/dropdown-menu", async () => {
+ const Passthrough = (await import("./__fixtures__/SlotPassthrough.svelte"))
+ .default;
+ const Clickable = (await import("./__fixtures__/ClickableItem.svelte"))
+ .default;
+ return {
+ Sub: Passthrough,
+ SubTrigger: Passthrough,
+ SubContent: Passthrough,
+ CheckboxItem: Clickable,
+ };
+});
+
+vi.mock("@rilldata/web-common/lib/i18n/gen/runtime", async (importOriginal) => {
+ const actual =
+ await importOriginal<
+ typeof import("@rilldata/web-common/lib/i18n/gen/runtime")
+ >();
+ return {
+ ...actual,
+ getLocale: vi.fn(() => "en"),
+ setLocale: vi.fn(),
+ };
+});
+
+import { setLocale } from "@rilldata/web-common/lib/i18n/gen/runtime";
+import LanguageSwitcher from "./LanguageSwitcher.svelte";
+
+describe("LanguageSwitcher", () => {
+ beforeEach(() => {
+ vi.clearAllMocks();
+ });
+
+ it("calls setLocale when a different locale is selected", async () => {
+ render(LanguageSwitcher);
+
+ const esButton = screen.getByText("Español");
+ await fireEvent.click(esButton);
+
+ expect(setLocale).toHaveBeenCalledWith("es");
+ });
+});
diff --git a/web-common/src/components/i18n/LanguageSwitcher.svelte b/web-common/src/components/i18n/LanguageSwitcher.svelte
new file mode 100644
index 00000000000..0e6293e1273
--- /dev/null
+++ b/web-common/src/components/i18n/LanguageSwitcher.svelte
@@ -0,0 +1,32 @@
+
+
+
+ {m.language_switcher_label()}
+
+ {#each LOCALES as loc}
+ setLocale(loc.code)}
+ >
+ {loc.label()}
+
+ {/each}
+
+
diff --git a/web-common/src/components/i18n/__fixtures__/ClickableItem.svelte b/web-common/src/components/i18n/__fixtures__/ClickableItem.svelte
new file mode 100644
index 00000000000..5ee7dbf2a6d
--- /dev/null
+++ b/web-common/src/components/i18n/__fixtures__/ClickableItem.svelte
@@ -0,0 +1,9 @@
+
+
+
+ {@render children?.()}
+
diff --git a/web-common/src/components/i18n/__fixtures__/SlotPassthrough.svelte b/web-common/src/components/i18n/__fixtures__/SlotPassthrough.svelte
new file mode 100644
index 00000000000..fc9910864cc
--- /dev/null
+++ b/web-common/src/components/i18n/__fixtures__/SlotPassthrough.svelte
@@ -0,0 +1,6 @@
+
+
+{@render children?.()}
diff --git a/web-common/src/components/menu/DashboardMetricsDraggableList.svelte b/web-common/src/components/menu/DashboardMetricsDraggableList.svelte
index 10be1ed7d26..aeb64c1bcdc 100644
--- a/web-common/src/components/menu/DashboardMetricsDraggableList.svelte
+++ b/web-common/src/components/menu/DashboardMetricsDraggableList.svelte
@@ -11,6 +11,7 @@
} from "@rilldata/web-common/runtime-client";
import * as Tooltip from "@rilldata/web-common/components/tooltip-v2";
import Resizer from "@rilldata/web-common/layout/Resizer.svelte";
+ import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
import { Button } from "../button";
import Search from "../search/Search.svelte";
import DashboardMetricsTagRow from "./DashboardMetricsTagRow.svelte";
@@ -48,10 +49,24 @@
$: allItemsMap = new Map(allItems.map((item) => [item.name, item]));
$: numAvailable = allItems?.length ?? 0;
$: numShown = selectedItems?.filter((x) => x).length ?? 0;
- $: numShownString =
- numAvailable === numShown ? "All" : `${numShown} of ${numAvailable}`;
- $: tooltipText = `Choose ${type === "measure" ? "measures" : "dimensions"} to display`;
- $: pluralLabel = type === "measure" ? "measures" : "dimensions";
+ $: buttonLabel =
+ numAvailable === numShown
+ ? type === "measure"
+ ? m.explore_all_measures()
+ : m.explore_all_dimensions()
+ : type === "measure"
+ ? m.explore_measures_count({
+ count: String(numShown),
+ total: String(numAvailable),
+ })
+ : m.explore_dimensions_count({
+ count: String(numShown),
+ total: String(numAvailable),
+ });
+ $: tooltipText =
+ type === "measure"
+ ? m.explore_choose_measures()
+ : m.explore_choose_dimensions();
$: tags = tagIndex.tags;
@@ -135,7 +150,7 @@
{`${numShownString} ${type === "measure" ? "Measures" : "Dimensions"}`} {buttonLabel}
@@ -158,10 +173,14 @@
@@ -193,11 +212,11 @@
- Tags
+ {m.explore_tags()}
{#if filteredTags.length === 0}
- No matching tags
+ {m.explore_no_matching_tags()}
{:else}
{#each filteredTags as tag (tag.name)}
@@ -265,14 +284,16 @@
- Shown {pluralLabel}
+ {type === "measure"
+ ? m.explore_shown_measures()
+ : m.explore_shown_dimensions()}
{#if shownFiltered.length > 1 && !filterActive}
- Hide all
+ {m.explore_hide_all()}
{/if}
@@ -280,19 +301,29 @@
{#snippet empty()}
{searchActive && hasTags && filteredTags.length === 0
- ? `No ${pluralLabel} or tags found`
+ ? type === "measure"
+ ? m.explore_no_measures_or_tags()
+ : m.explore_no_dimensions_or_tags()
: filterActive
- ? `No ${pluralLabel} from this tag are shown`
+ ? type === "measure"
+ ? m.explore_no_measures_from_tag()
+ : m.explore_no_dimensions_from_tag()
: searchActive
- ? `No matching ${pluralLabel} shown`
- : `No ${pluralLabel} shown`}
+ ? type === "measure"
+ ? m.explore_no_matching_measures_shown()
+ : m.explore_no_matching_dimensions_shown()
+ : type === "measure"
+ ? m.explore_no_measures_shown()
+ : m.explore_no_dimensions_shown()}
{/snippet}
{#snippet item({ item })}
{@const itemData = allItemsMap.get(item.id)}
{@const displayName =
itemData?.displayName ??
- `Unknown ${type === "measure" ? "measure" : "dimension"}`}
+ (type === "measure"
+ ? m.explore_unknown_measure()
+ : m.explore_unknown_dimension())}
{#if itemData?.description || selectedItems.length === 1}
@@ -321,7 +352,7 @@
class:pointer-events-none={selectedItems.length ===
1}
class:opacity-50={selectedItems.length === 1}
- aria-label="Hide {displayName}"
+ aria-label={m.explore_hide_item({ name: displayName })}
data-testid="toggle-visibility-button"
type="button"
>
@@ -334,9 +365,9 @@
class="bg-popover text-fg-primary z-popover"
>
{#if selectedItems.length === 1}
- Must show at least one {type === "measure"
- ? "measure"
- : "dimension"}
+ {type === "measure"
+ ? m.explore_must_show_one_measure()
+ : m.explore_must_show_one_dimension()}
{:else}
{itemData?.description}
{/if}
@@ -364,7 +395,7 @@
disabled={selectedItems.length === 1}
class:pointer-events-none={selectedItems.length === 1}
class:opacity-50={selectedItems.length === 1}
- aria-label={`Hide ${displayName}`}
+ aria-label={m.explore_hide_item({ name: displayName })}
type="button"
>
@@ -393,21 +424,23 @@
- Hidden {pluralLabel}
+ {type === "measure"
+ ? m.explore_hidden_measures()
+ : m.explore_hidden_dimensions()}
{#if !filterActive}
- Show all
+ {m.explore_show_all()}
{:else}
showAllInTag(selectedTag!)}
>
- Show all in tag
+ {m.explore_show_all_in_tag()}
{/if}
@@ -415,15 +448,21 @@
{#snippet empty()}
{searchActive
- ? `No matching hidden ${pluralLabel}`
- : `No hidden ${pluralLabel}`}
+ ? type === "measure"
+ ? m.explore_no_matching_hidden_measures()
+ : m.explore_no_matching_hidden_dimensions()
+ : type === "measure"
+ ? m.explore_no_hidden_measures()
+ : m.explore_no_hidden_dimensions()}
{/snippet}
{#snippet item({ item })}
{@const itemData = allItemsMap.get(item.id)}
{@const displayName =
itemData?.displayName ??
- `Unknown ${type === "measure" ? "measure" : "dimension"}`}
+ (type === "measure"
+ ? m.explore_unknown_measure()
+ : m.explore_unknown_dimension())}
@@ -443,7 +482,7 @@
e.stopPropagation();
handleHiddenItemClick({ item });
}}
- aria-label={`Show ${displayName}`}
+ aria-label={m.explore_show_item({ name: displayName })}
data-testid="toggle-visibility-button"
type="button"
>
@@ -470,7 +509,7 @@
e.stopPropagation();
handleHiddenItemClick({ item });
}}
- aria-label={`Show ${displayName}`}
+ aria-label={m.explore_show_item({ name: displayName })}
data-testid="toggle-visibility-button"
type="button"
>
@@ -490,13 +529,17 @@
- Clear the tag filter to reorder {pluralLabel}.
+ {type === "measure"
+ ? m.explore_clear_tag_filter_to_reorder_measures()
+ : m.explore_clear_tag_filter_to_reorder_dimensions()}
{:else if searchActive && !filterActive}
- Clear search to reorder {pluralLabel}.
+ {type === "measure"
+ ? m.explore_clear_search_to_reorder_measures()
+ : m.explore_clear_search_to_reorder_dimensions()}
{/if}
diff --git a/web-common/src/components/menu/DashboardMetricsTagRow.svelte b/web-common/src/components/menu/DashboardMetricsTagRow.svelte
index 5db37761108..9ae68f8163e 100644
--- a/web-common/src/components/menu/DashboardMetricsTagRow.svelte
+++ b/web-common/src/components/menu/DashboardMetricsTagRow.svelte
@@ -3,6 +3,7 @@
import EyeOffIcon from "@rilldata/web-common/components/icons/EyeInvisible.svelte";
import * as Tooltip from "@rilldata/web-common/components/tooltip-v2";
import { detectOverflow } from "@rilldata/web-common/lib/actions/detect-overflow";
+ import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
import type { DimensionTag, TagVisibilityState } from "./tag-utils";
type Props = {
@@ -40,7 +41,9 @@
type="button"
class="flex items-center gap-x-2 flex-1 min-w-0 text-left"
onclick={onSelect}
- aria-label={`${selected ? "Clear filter" : "Filter by"} ${tag.name}`}
+ aria-label={selected
+ ? m.explore_clear_filter_tag({ tag: tag.name })
+ : m.explore_filter_by_tag({ tag: tag.name })}
aria-pressed={selected}
>
@@ -86,7 +89,10 @@
{visibility.visibleCount}/{visibility.totalCount}
@@ -105,7 +111,7 @@
e.stopPropagation();
onShowOnly();
}}
- aria-label={`Only show ${tag.name}`}
+ aria-label={m.explore_only_show_tag({ tag: tag.name })}
>
@@ -123,7 +129,7 @@
side="top"
class="bg-popover text-fg-primary z-popover text-xs px-2 py-1"
>
- Only show this tag
+ {m.explore_only_show_this_tag()}
@@ -136,7 +142,7 @@
e.stopPropagation();
onShowAll();
}}
- aria-label={`Show all in ${tag.name}`}
+ aria-label={m.explore_show_all_in_named_tag({ tag: tag.name })}
>
@@ -145,7 +151,7 @@
side="top"
class="bg-popover text-fg-primary z-popover text-xs px-2 py-1"
>
- Show all in tag
+ {m.explore_show_all_in_tag()}
@@ -158,7 +164,7 @@
e.stopPropagation();
onHideAll();
}}
- aria-label={`Hide all in ${tag.name}`}
+ aria-label={m.explore_hide_all_in_named_tag({ tag: tag.name })}
>
@@ -167,7 +173,7 @@
side="top"
class="bg-popover text-fg-primary z-popover text-xs px-2 py-1"
>
- Hide all in tag
+ {m.explore_hide_all_in_tag()}
diff --git a/web-common/src/components/menu/LeaderboardAdvancedActions.svelte b/web-common/src/components/menu/LeaderboardAdvancedActions.svelte
index 4c2cdf6dcad..7b72b21c123 100644
--- a/web-common/src/components/menu/LeaderboardAdvancedActions.svelte
+++ b/web-common/src/components/menu/LeaderboardAdvancedActions.svelte
@@ -10,6 +10,7 @@
import { getStateManagers } from "@rilldata/web-common/features/dashboards/state-managers/state-managers";
import { metricsExplorerStore } from "@rilldata/web-common/features/dashboards/stores/dashboard-stores";
import { useTimeControlStore } from "@rilldata/web-common/features/dashboards/time-controls/time-control-store";
+ import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
const ctx = getStateManagers();
const {
@@ -44,7 +45,7 @@
side="bottom"
class="flex flex-row items-center justify-between gap-x-2 w-[286px] px-3.5 py-2.5"
>
- Show context for all measures
+ {m.explore_show_context_for_all_measures()}
1
- ? `${selectedMeasureNames.length} measures`
+ ? m.explore_n_measures({ count: String(selectedMeasureNames.length) })
: getMeasureDisplayText(leaderboardSortByMeasureName);
function onToggleOff() {
@@ -136,7 +137,7 @@
- Showing {showingMeasuresText}
+ {m.explore_showing()} {showingMeasuresText}
@@ -183,7 +184,7 @@
{/each}
{:else}
- No matching leaderboard measures shown
+ {m.explore_no_matching_leaderboard_measures()}
{/if}
@@ -202,7 +203,7 @@
@@ -212,7 +213,7 @@
- Choose measures to display
+ {m.explore_choose_measures()}
diff --git a/web-common/src/components/menu/TagFilterBanner.svelte b/web-common/src/components/menu/TagFilterBanner.svelte
index addca27d0e3..6980652b915 100644
--- a/web-common/src/components/menu/TagFilterBanner.svelte
+++ b/web-common/src/components/menu/TagFilterBanner.svelte
@@ -1,5 +1,6 @@
- Filter:
+ {m.explore_filter_label()}:
{tagName}
@@ -23,7 +24,7 @@
type="button"
class="flex-none text-icon-muted hover:text-fg-primary transition-colors"
onclick={onClear}
- aria-label="Clear tag filter"
+ aria-label={m.explore_clear_tag_filter()}
>
@@ -33,7 +34,7 @@
side="top"
class="bg-popover text-fg-primary z-popover text-xs px-2 py-1"
>
- Clear filter
+ {m.explore_clear_filter()}
diff --git a/web-common/src/components/search/Search.svelte b/web-common/src/components/search/Search.svelte
index 6b23000b877..c16e5e6dbbb 100644
--- a/web-common/src/components/search/Search.svelte
+++ b/web-common/src/components/search/Search.svelte
@@ -1,4 +1,5 @@
-
+
diff --git a/web-common/src/features/alerts/data-tab/DataPreview.svelte b/web-common/src/features/alerts/data-tab/DataPreview.svelte
index 594f35be61a..23333aa3183 100644
--- a/web-common/src/features/alerts/data-tab/DataPreview.svelte
+++ b/web-common/src/features/alerts/data-tab/DataPreview.svelte
@@ -2,6 +2,7 @@
import { getAlertPreviewData } from "@rilldata/web-common/features/alerts/alert-preview-data";
import AlertPreviewTable from "@rilldata/web-common/features/alerts/AlertPreviewTable.svelte";
import type { AlertFormValues } from "@rilldata/web-common/features/alerts/form-utils";
+ import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
import Spinner from "@rilldata/web-common/features/entity-management/Spinner.svelte";
import { EntityStatus } from "@rilldata/web-common/features/entity-management/types";
import type { Filters } from "@rilldata/web-common/features/dashboards/stores/Filters.ts";
@@ -40,7 +41,7 @@
{:else if !queryResult.data}
{:else}
diff --git a/web-common/src/features/alerts/data-tab/NoFiltersSelected.svelte b/web-common/src/features/alerts/data-tab/NoFiltersSelected.svelte
index f08e3d05900..4d322c79cf5 100644
--- a/web-common/src/features/alerts/data-tab/NoFiltersSelected.svelte
+++ b/web-common/src/features/alerts/data-tab/NoFiltersSelected.svelte
@@ -1,5 +1,6 @@
@@ -7,13 +8,12 @@
-
No filters selected
+ {m.alert_no_filters_heading()}
{#if isEditForm}
- No filters were applied to the dashboard that this alert was created
- from.
+ {m.alert_no_filters_body()}
{:else}
- To apply filters, close this window and filter your dashboard.
+ {m.alert_no_filters_hint()}
{/if}
diff --git a/web-common/src/features/alerts/delivery-tab/AlertDialogDeliveryTab.svelte b/web-common/src/features/alerts/delivery-tab/AlertDialogDeliveryTab.svelte
index dac0f95b95d..015a325de89 100644
--- a/web-common/src/features/alerts/delivery-tab/AlertDialogDeliveryTab.svelte
+++ b/web-common/src/features/alerts/delivery-tab/AlertDialogDeliveryTab.svelte
@@ -1,11 +1,12 @@
-
+
-
+
($form["refreshWhenDataRefreshes"] = true)}
active={$form["refreshWhenDataRefreshes"]}
>
- Whenever data refreshes
+ {m.alert_form_trigger_data_refresh()}
($form["refreshWhenDataRefreshes"] = false)}
active={!$form["refreshWhenDataRefreshes"]}
>
- Set schedule
+ {m.alert_form_trigger_set_schedule()}
{#if !$form["refreshWhenDataRefreshes"]}
@@ -54,26 +55,26 @@
{#if $hasSlackNotifier.data}
{:else}
-
+
- Slack has not been configured for this project. Read the
- docs
- to learn more.
+ {@html m.alert_form_slack_not_configured({ docsUrl: "https://docs.rilldata.com/guide/alerts#configuring-slack-targets" })}
{/if}
@@ -75,7 +86,7 @@
{...props}
{disabled}
class:pr-3.5={open}
- aria-label="Add widget"
+ aria-label={m.canvas_add_widget()}
class="shadow-lg flex group hover:rounded-3xl w-fit gap-x-1 p-2 hover:pr-3.5 absolute bottom-3 right-3 items-center justify-center z-50 rounded-full bg-primary-600 text-white hover:bg-primary-500"
>
@@ -84,7 +95,7 @@
class:not-sr-only={open}
class="sr-only group-hover:not-sr-only font-semibold w-fit"
>
- Add widget
+ {m.canvas_add_widget()}
{:else}
@@ -92,7 +103,7 @@
{...props}
{disabled}
aria-label={getAriaLabel(rowIndex, columnIndex)}
- title="Insert widget"
+ title={m.canvas_insert_widget()}
class:bg-surface-background={open}
class="pointer-events-auto bg-surface-subtle active:bg-gray-100 disabled:pointer-events-none h-7 px-2 grid place-content-center z-50 hover:bg-surface-background text-fg-secondary disabled:opacity-50"
onmouseenter={onMouseEnter}
@@ -135,7 +146,7 @@
onclick={() => onItemClick("custom_chart")}
>
- Custom Chart
+ {m.canvas_custom_chart()}
{/if}
@@ -158,7 +169,7 @@
onclick={() => onAddTabGroup?.()}
>
- Tab group
+ {m.canvas_tab_group()}
{/if}
diff --git a/web-common/src/features/canvas/CanvasBuilder.svelte b/web-common/src/features/canvas/CanvasBuilder.svelte
index b261aac41de..16e57cf23f6 100644
--- a/web-common/src/features/canvas/CanvasBuilder.svelte
+++ b/web-common/src/features/canvas/CanvasBuilder.svelte
@@ -12,6 +12,7 @@
import { parseDocument } from "yaml";
import ComponentError from "../components/ComponentError.svelte";
import type { FileArtifact } from "../entity-management/file-artifact";
+ import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
import ReconcilingSpinner from "../entity-management/ReconcilingSpinner.svelte";
import AddComponentDropdown from "./AddComponentDropdown.svelte";
import CanvasComponent from "./CanvasComponent.svelte";
@@ -867,7 +868,7 @@
onAddTabGroup={addTabGroupAction}
/>
{:else if canvasData}
-
+
{/if}
@@ -914,10 +915,10 @@
}}
>
- Delete widget?
+ {m.canvas_delete_widget()}
- This widget and its configuration will be permanently removed.
+ {m.canvas_delete_widget_description()}
@@ -931,7 +932,7 @@
pendingComponentDelete = undefined;
}}
>
- Cancel
+ {m.canvas_cancel()}
{/snippet}
@@ -952,7 +953,7 @@
pendingComponentDelete = undefined;
}}
>
- Delete
+ {m.canvas_delete()}
{/snippet}
diff --git a/web-common/src/features/canvas/CanvasDashboardEmbed.svelte b/web-common/src/features/canvas/CanvasDashboardEmbed.svelte
index 02e76be3e3d..0ccb6c09a7a 100644
--- a/web-common/src/features/canvas/CanvasDashboardEmbed.svelte
+++ b/web-common/src/features/canvas/CanvasDashboardEmbed.svelte
@@ -4,6 +4,7 @@
import StaticCanvasRow from "./StaticCanvasRow.svelte";
import CanvasTabGroupView from "./CanvasTabGroupView.svelte";
import { useRuntimeClient } from "@rilldata/web-common/runtime-client/v2";
+ import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
import Spinner from "../entity-management/Spinner.svelte";
import { EntityStatus } from "../entity-management/types";
import { page } from "$app/stores";
@@ -88,7 +89,9 @@
{#if $firstLoad}
{:else}
- No components added
+
+ {m.canvas_no_components_added()}
+
{/if}
{/each}
diff --git a/web-common/src/features/canvas/CanvasEditButton.svelte b/web-common/src/features/canvas/CanvasEditButton.svelte
index 19968a1abee..fd607721d0f 100644
--- a/web-common/src/features/canvas/CanvasEditButton.svelte
+++ b/web-common/src/features/canvas/CanvasEditButton.svelte
@@ -1,4 +1,5 @@
-
Edit
+
{m.canvas_edit()}
diff --git a/web-common/src/features/canvas/CanvasLoadingState.svelte b/web-common/src/features/canvas/CanvasLoadingState.svelte
index 6986c8cf37a..1d08e6522df 100644
--- a/web-common/src/features/canvas/CanvasLoadingState.svelte
+++ b/web-common/src/features/canvas/CanvasLoadingState.svelte
@@ -1,6 +1,7 @@
-
Saving default filters
+
+ {m.canvas_saving_default_filters()}
+
{:else if viewingDefaults}
{#if justClickedSaveAsDefault}
- Saved default filters
+ {m.canvas_saved_default_filters()}
{:else}
-
Viewing default state
+
+ {m.canvas_viewing_default_state()}
+
{/if}
{:else}
-
Save as default
+
{m.canvas_save_as_default()}
{/if}
{/snippet}
diff --git a/web-common/src/features/canvas/components/charts/BaseChart.ts b/web-common/src/features/canvas/components/charts/BaseChart.ts
index 5512f5cd093..9338a9bd8a6 100644
--- a/web-common/src/features/canvas/components/charts/BaseChart.ts
+++ b/web-common/src/features/canvas/components/charts/BaseChart.ts
@@ -5,7 +5,7 @@ import {
getLinkStateForTimeDimensionDetail,
} from "@rilldata/web-common/features/canvas/components/charts/util";
import {
- commonOptions,
+ getCommonOptions,
createComponent,
getFilterOptions,
} from "@rilldata/web-common/features/canvas/components/util";
@@ -46,6 +46,8 @@ import type {
} from "../types";
import Chart from "./CanvasChart.svelte";
+import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
+
// Base interface for all chart configurations
export type BaseChartConfig = ComponentFilterProperties &
ComponentCommonProperties &
@@ -88,11 +90,15 @@ export abstract class BaseChart<
inputParams(): InputParams
{
return {
options: {
- metrics_view: { type: "metrics", label: "Metrics view" },
- tooltip: { type: "tooltip", label: "Tooltip", showInUI: false },
+ metrics_view: { type: "metrics", label: m.canvas_metrics_view_label() },
+ tooltip: {
+ type: "tooltip",
+ label: m.canvas_tooltip_label(),
+ showInUI: false,
+ },
vl_config: { type: "config", showInUI: false },
...this.getChartSpecificOptions(),
- ...commonOptions,
+ ...getCommonOptions(),
},
filter: getFilterOptions(this.supportsComparison()),
};
diff --git a/web-common/src/features/canvas/components/charts/custom-chart/AgenticChartPrompt.svelte b/web-common/src/features/canvas/components/charts/custom-chart/AgenticChartPrompt.svelte
index e0cd7f41042..642e1ccfa3e 100644
--- a/web-common/src/features/canvas/components/charts/custom-chart/AgenticChartPrompt.svelte
+++ b/web-common/src/features/canvas/components/charts/custom-chart/AgenticChartPrompt.svelte
@@ -4,6 +4,7 @@
import { useRuntimeClient } from "@rilldata/web-common/runtime-client/v2";
import { getAgentStreamingStore, sendToDevAgent } from "./chart-ai-agent";
import type { CustomChartComponent } from "./index";
+ import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
export let component: CustomChartComponent;
@@ -24,16 +25,16 @@
{#if manualMode}
- Use the inspector panel to write Metrics SQL and Vega-Lite spec manually.
+ {m.canvas_ai_manual_hint()}
(manualMode = false)}>
- ← Back to prompt
+ {m.canvas_back_to_prompt()}
{:else if isStreaming}
-
AI is generating chart
+
{m.canvas_ai_generating_chart()}
{:else}
@@ -42,14 +43,14 @@
(manualMode = true)}>
- Write SQL & Vega-Lite manually
+ {m.canvas_ai_write_manually()}
- Generate
+ {m.canvas_generate()}
diff --git a/web-common/src/features/canvas/components/charts/custom-chart/index.ts b/web-common/src/features/canvas/components/charts/custom-chart/index.ts
index e2ec53aa611..9577ae1bd43 100644
--- a/web-common/src/features/canvas/components/charts/custom-chart/index.ts
+++ b/web-common/src/features/canvas/components/charts/custom-chart/index.ts
@@ -4,7 +4,7 @@ import {
type ComponentCommonProperties,
type ComponentFilterProperties,
} from "@rilldata/web-common/features/canvas/components/types";
-import { commonOptions } from "@rilldata/web-common/features/canvas/components/util";
+import { getCommonOptions } from "@rilldata/web-common/features/canvas/components/util";
import type { InputParams } from "@rilldata/web-common/features/canvas/inspector/types";
import type {
CanvasEntity,
@@ -22,6 +22,8 @@ import type { V1Resource } from "@rilldata/web-common/runtime-client";
import { get, writable, type Writable } from "svelte/store";
import CanvasCustomChart from "./CanvasCustomChart.svelte";
+import { m } from "@rilldata/web-common/lib/i18n/gen/messages";
+
export interface CustomChart
extends ComponentCommonProperties,
ComponentFilterProperties {
@@ -161,10 +163,16 @@ export class CustomChartComponent extends BaseCanvasComponent