diff --git a/AGENTS.md b/AGENTS.md index f365ec4a..272ac328 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -2,7 +2,7 @@ ## Project Overview -**Stackable Cockpit** is a SvelteKit application that serves as the web UI of the Stackable Data Platform. It is built as a set of modules behind a shared OIDC login: +**Stackable Cockpit** is a SvelteKit application that serves as the UI of the Stackable Data Platform. It is built as a set of modules behind a shared OIDC login: - **Trino** — SQL editor (Monaco + ANTLR grammar) with catalogue browser and query lifecycle management - **Storage** — S3 file browser with preview, upload/download, archives, search and transfers (HDFS is a stub) @@ -177,7 +177,7 @@ English is the default/fallback locale; German is also supported. - All user-visible strings go into `messages/en.json` **and** `messages/de.json` (same keys in both). This includes `aria-label`, `title`, `placeholder` and `alt`. - Use them via `import * as m from '$lib/paraglide/messages.js'` and `m.key_name()`. -- Flat keys with a feature prefix: `dashboard_welcome`, `nav_dashboard`, `header_user_menu`. +- Flat keys with a feature prefix: `dashboard_bookmarks_empty`, `nav_dashboard`, `header_user_menu`. - Data structures containing translated strings must be `$derived` so they follow locale changes. - The Vite plugin compiles messages during `dev`/`build`. For `npm run check`/`lint` outside Vite, compile manually: `npx @inlang/paraglide-js compile --project ./project.inlang --outdir ./src/lib/paraglide`. diff --git a/README.md b/README.md index ca81bb50..b3dff441 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@ [Stackable Data Platform](https://stackable.tech/) | [Platform Docs](https://docs.stackable.tech/) | [Discussions](https://github.com/orgs/stackabletech/discussions) | [Discord](https://discord.gg/7kZ3BNnCAF) -Stackable Cockpit is the unified web UI for the Stackable Data Platform (SDP). -It provides a single place to work with the data services running on your platform. +Stackable Cockpit is the UI for the Stackable Data Platform (SDP). +It provides a single place to work with the services running on your platform. It is part of the Stackable Data Platform, a curated selection of the best open source data apps like Apache Kafka®, OpenSearch, Trino or Apache Spark™, [all](#other-operators) working together seamlessly. Based on Kubernetes, it runs everywhere – on prem or in the cloud. diff --git a/deploy/helm/cockpit/Chart.yaml b/deploy/helm/cockpit/Chart.yaml index 8c0a42db..8e0a72d6 100644 --- a/deploy/helm/cockpit/Chart.yaml +++ b/deploy/helm/cockpit/Chart.yaml @@ -1,7 +1,7 @@ --- apiVersion: v2 name: cockpit -description: Unified data platform UI for Stackable's data infrastructure +description: Stackable Cockpit, the UI for the Stackable Data Platform (SDP) type: application version: 0.0.0-dev appVersion: "0.0.0-dev" diff --git a/docker/Dockerfile b/docker/Dockerfile index 906f2a08..30679892 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -187,9 +187,9 @@ LABEL name="cockpit" LABEL version="${VERSION}" LABEL release="${VERSION}" LABEL summary="Stackable Cockpit" -LABEL description="Web UI of the Stackable Data Platform" +LABEL description="UI of the Stackable Data Platform" LABEL io.k8s.display-name="Stackable Cockpit" -LABEL io.k8s.description="Web UI of the Stackable Data Platform" +LABEL io.k8s.description="UI of the Stackable Data Platform" LABEL io.openshift.tags="stackable,cockpit" LABEL build-date="${BUILD_DATE}" LABEL vcs-ref="${GIT_SHA}" @@ -211,7 +211,7 @@ LABEL org.opencontainers.image.source="https://github.com/stackabletech/cockpit/ LABEL org.opencontainers.image.vendor="Stackable GmbH" LABEL org.opencontainers.image.licenses="OSL-3.0" LABEL org.opencontainers.image.title="Stackable Cockpit" -LABEL org.opencontainers.image.description="Web UI of the Stackable Data Platform" +LABEL org.opencontainers.image.description="UI of the Stackable Data Platform" LABEL org.opencontainers.image.version="${VERSION}" LABEL org.opencontainers.image.revision="${GIT_SHA}" LABEL org.opencontainers.image.created="${BUILD_DATE}" diff --git a/docs/modules/cockpit/pages/index.adoc b/docs/modules/cockpit/pages/index.adoc index 232095f9..2074d17b 100644 --- a/docs/modules/cockpit/pages/index.adoc +++ b/docs/modules/cockpit/pages/index.adoc @@ -1,11 +1,11 @@ = Stackable Cockpit -:description: Stackable Cockpit is a web UI for the Stackable Data Platform (SDP) to work with services such as Trino and S3 storage from a single place, behind one OIDC login. +:description: Stackable Cockpit is a UI for the Stackable Data Platform (SDP) to work with services such as Trino and S3 storage from a single place, behind one OIDC login. :github: https://github.com/stackabletech/cockpit/ [.link-bar] * {github}[GitHub {external-link-icon}^] -Stackable Cockpit is a web UI for the Stackable Data Platform (SDP). +Stackable Cockpit is a UI for the Stackable Data Platform (SDP). Users log in once through OpenID Connect (OIDC) and work with the platform's services from a single place. image::dashboard.png[Cockpit dashboard with bookmarks to Trino, Superset, Airflow and other tools] diff --git a/e2e/error-pages.spec.ts b/e2e/error-pages.spec.ts index 721096bb..88a1cc23 100644 --- a/e2e/error-pages.spec.ts +++ b/e2e/error-pages.spec.ts @@ -9,7 +9,7 @@ test.describe('Error pages', () => { expect(response?.status()).toBe(404); await waitForHydration(page); - await expect(page).toHaveTitle('Page not found | Stackable'); + await expect(page).toHaveTitle('Page not found | Stackable Cockpit'); await expect(page.getByRole('heading', { level: 1 })).toHaveText('Page not found'); const main = page.locator('main'); await expect(main.getByRole('heading', { name: /Page not found/ })).toBeVisible(); diff --git a/e2e/i18n.spec.ts b/e2e/i18n.spec.ts index 81bbc507..8fdda957 100644 --- a/e2e/i18n.spec.ts +++ b/e2e/i18n.spec.ts @@ -2,8 +2,8 @@ import { test, expect } from './support/fixtures.js'; import fs from 'fs'; import { waitForHydration } from './support/helpers'; -/** German dashboard heading (messages/de.json `dashboard_welcome`). */ -const DE_DASHBOARD_HEADING = 'Stackable Unified Data Platform – Übersicht'; +/** German bookmarks heading on the dashboard (messages/de.json `bookmark_section_title`). */ +const DE_BOOKMARKS_HEADING = 'Lesezeichen'; /** Load the saved auth storage state, optionally stripping the locale cookie. */ function loadAuthState(authFile: string, { withoutLocale = false } = {}) { @@ -33,7 +33,7 @@ test.describe('Internationalisation', () => { await expect(html).toHaveAttribute('lang', 'en'); // Dashboard content is in English - await expect(page.getByText('Stackable Unified Data Platform overview')).toBeVisible(); + await expect(page.getByRole('heading', { name: 'Bookmarks', exact: true })).toBeVisible(); await expect(page.getByText('Add bookmark')).toBeVisible(); await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible(); }); @@ -68,7 +68,9 @@ test.describe('Internationalisation', () => { // Page reloads with German content await expect(page.locator('html')).toHaveAttribute('lang', 'de'); - await expect(page.getByText(DE_DASHBOARD_HEADING)).toBeVisible(); + await expect( + page.getByRole('heading', { name: DE_BOOKMARKS_HEADING, exact: true }) + ).toBeVisible(); await expect(page.getByText('Lesezeichen hinzufügen')).toBeVisible(); }); @@ -88,14 +90,18 @@ test.describe('Internationalisation', () => { // Should render in German await expect(page.locator('html')).toHaveAttribute('lang', 'de'); - await expect(page.getByText(DE_DASHBOARD_HEADING)).toBeVisible(); + await expect( + page.getByRole('heading', { name: DE_BOOKMARKS_HEADING, exact: true }) + ).toBeVisible(); // Navigate to same page (simulate navigation) await page.goto('/'); // Should still be German await expect(page.locator('html')).toHaveAttribute('lang', 'de'); - await expect(page.getByText(DE_DASHBOARD_HEADING)).toBeVisible(); + await expect( + page.getByRole('heading', { name: DE_BOOKMARKS_HEADING, exact: true }) + ).toBeVisible(); }); test('Accept-Language header respected for first visit', async ({ @@ -114,7 +120,9 @@ test.describe('Internationalisation', () => { // Should render in German based on Accept-Language await expect(page.locator('html')).toHaveAttribute('lang', 'de'); - await expect(page.getByText(DE_DASHBOARD_HEADING)).toBeVisible(); + await expect( + page.getByRole('heading', { name: DE_BOOKMARKS_HEADING, exact: true }) + ).toBeVisible(); await context.close(); }); diff --git a/e2e/navigation.spec.ts b/e2e/navigation.spec.ts index 6a25b249..712961bf 100644 --- a/e2e/navigation.spec.ts +++ b/e2e/navigation.spec.ts @@ -83,10 +83,10 @@ test.describe('App navigation', () => { const sidebar = page.getByRole('complementary', { name: 'Sidebar' }); // Expanded: the visible "Stackable" text names the brand, so the logo is decorative. - await expect(sidebar.getByRole('img', { name: 'Stackable' })).toHaveCount(0); + await expect(sidebar.getByRole('img', { name: 'Stackable Cockpit' })).toHaveCount(0); await sidebar.getByRole('button', { name: 'Collapse sidebar' }).click(); - await expect(sidebar.getByRole('img', { name: 'Stackable' })).toBeVisible(); + await expect(sidebar.getByRole('img', { name: 'Stackable Cockpit' })).toBeVisible(); }); test('skip link is the first tab stop and moves keyboard focus into the main content', async ({ diff --git a/e2e/smoke.spec.ts b/e2e/smoke.spec.ts index d0d54efb..7c6eacd0 100644 --- a/e2e/smoke.spec.ts +++ b/e2e/smoke.spec.ts @@ -15,7 +15,7 @@ test.describe('Smoke tests', () => { await waitForHydration(page); // Sidebar brand is visible - await expect(page.getByText('Stackable', { exact: true })).toBeVisible(); + await expect(page.getByText('Stackable Cockpit', { exact: true })).toBeVisible(); // Dashboard nav item is present and active const dashboardLink = page.getByRole('link', { name: 'Dashboard' }); @@ -26,7 +26,7 @@ test.describe('Smoke tests', () => { await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible(); // Dashboard content is rendered - await expect(page.getByText('Stackable Unified Data Platform overview')).toBeVisible(); + await expect(page.getByRole('heading', { name: 'Bookmarks', exact: true })).toBeVisible(); // Trino nav item is present and navigable const trinoLink = page.getByRole('link', { name: 'Trino' }); diff --git a/messages/de.json b/messages/de.json index c8b51b1e..ecbd5ff7 100644 --- a/messages/de.json +++ b/messages/de.json @@ -2,8 +2,6 @@ "$schema": "https://inlang.com/schema/inlang-message-format", "action_close": "Schließen", "action_dismiss": "Schließen", - "dashboard_welcome": "Stackable Unified Data Platform – Übersicht", - "dashboard_subtitle": "Die Werkzeuge, die Sie sich als Lesezeichen gespeichert haben. Lesezeichen werden von Hand hinzugefügt – Cockpit erkennt noch nichts automatisch.", "dashboard_bookmarks_empty": "Noch keine Lesezeichen. Fügen Sie Ihr erstes Lesezeichen hinzu, um zu starten.", "nav_platform": "Plattform", "nav_dashboard": "Dashboard", @@ -38,8 +36,8 @@ "theme_toggle": "Design umschalten", "page_title_dashboard": "Dashboard", "page_title_default": "Stackable", - "page_title_suffix": "Stackable", - "meta_description": "Stackable Cockpit: Die Web-UI für die Stackable Data Platform (SDP). Arbeiten Sie an einem zentralen Ort mit den Datendiensten der Plattform.", + "app_name": "Stackable Cockpit", + "meta_description": "Stackable Cockpit: Die UI für die Stackable Data Platform (SDP). Arbeiten Sie an einem zentralen Ort mit den Diensten der Plattform.", "page_title_trino": "Trino", "bookmark_count_links": [ { diff --git a/messages/en.json b/messages/en.json index 8d29f704..18cffc0c 100644 --- a/messages/en.json +++ b/messages/en.json @@ -2,8 +2,6 @@ "$schema": "https://inlang.com/schema/inlang-message-format", "action_close": "Close", "action_dismiss": "Dismiss", - "dashboard_welcome": "Stackable Unified Data Platform overview", - "dashboard_subtitle": "The tools you've bookmarked. Bookmarks are added by hand — Cockpit doesn't discover anything yet.", "dashboard_bookmarks_empty": "No bookmarks yet. Add your first bookmark to get started.", "nav_platform": "Platform", "nav_dashboard": "Dashboard", @@ -38,8 +36,8 @@ "theme_toggle": "Toggle theme", "page_title_dashboard": "Dashboard", "page_title_default": "Stackable", - "page_title_suffix": "Stackable", - "meta_description": "Stackable Cockpit: The web UI for the Stackable Data Platform (SDP). Work with the data services running on your platform in one place.", + "app_name": "Stackable Cockpit", + "meta_description": "Stackable Cockpit: The UI for the Stackable Data Platform (SDP). Work with the services running on your platform in one place.", "page_title_trino": "Trino", "bookmark_count_links": [ { diff --git a/src/lib/components/dashboard/DashboardBookmarks.svelte b/src/lib/components/dashboard/DashboardBookmarks.svelte index e0d880d6..06ecba1a 100644 --- a/src/lib/components/dashboard/DashboardBookmarks.svelte +++ b/src/lib/components/dashboard/DashboardBookmarks.svelte @@ -59,21 +59,18 @@
-

{m.bookmark_section_title()} -

+ {#if count > 0} {m.bookmark_count_links({ count })} {/if}
- {#if bookmarks} -

{m.dashboard_subtitle()}

- {/if}
{#if bookmarks}