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
7 changes: 5 additions & 2 deletions REFERENCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,20 +298,22 @@ CsvTable.rows: readonly (readonly CsvCell[])[]
DataApp (component, @altertable/data-app-react): <Data, Input>(props: DataAppProps<Data, Input>) — Executes the primary view and owns its controls, inspection, exports, and stories.
DataApp.children: ReactNode
DataApp.description?: ReactNode — Override the declared subtitle; null hides it.
DataApp.showToolbar?: boolean — Show page actions. Defaults to true; does not hide filters or data states.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I realize we have DataApp.showToolbar showing up twice. Are we exporting <DataApp> from multiple export paths?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, these are two existing variants: @altertable/data-app-react exports the declared-view DataApp, which handles data loading and controls; @altertable/data-app-react/ui exports the static DataApp for setup/static screens. Both use DataAppFrame, where showToolbar is defined, so the generated reference lists it for both. The two exports predate this PR.

DataApp.toolbarActions?: ReactNode
DataApp.footerActions?: ReactNode
DataApp.footer?: ReactNode — Optional source, coverage, or methodology note below the app content. Compose prose and inline components; typography and spacing are provided.
DataApp.showSearch?: boolean — Show declared search controls. Defaults to true; hiding preserves their values.
DataApp.showFilters?: boolean — Show declared filter controls, including display options. Defaults to true; hiding preserves their values.
DataApp.view: DeclaredView<Data, Input, unknown> & { scope(snapshot: DisplayedSnapshot<Data, Input>): string; }
DataApp.showSearchSuggestions?: boolean — Show supplied datasets’ record suggestions on the first declared search. Defaults to true.
DataApp.story: (snapshot: DisplayedSnapshot<Data, Input>) => readonly (Omit<StoryFinding, 'evidence'> & { evidence: RegisteredBinding; })[]
DataApp.datasets: readonly [ExportDataset<Data, Input>, ...ExportDataset<Data, Input>[]]
DataApp.story?: ((snapshot: DisplayedSnapshot<Data, Input>) => readonly (Omit<StoryFinding, 'evidence'> & { evidence: RegisteredBinding; })[]) — Omit to leave presentation out of the toolbar.
DataApp.datasets?: readonly [ExportDataset<Data, Input>, ...ExportDataset<Data, Input>[]] — Omit to leave CSV export out of the toolbar.
DataApp.details?: readonly DetailContent<any, any>[] — Detail destinations available to dataset actions and metric record inspection.
DataApp (component, @altertable/data-app-react/ui): (props: DataAppProps) — Setup and static screens; fetched data uses the declared-view DataApp.
DataApp.children: ReactNode
DataApp.dataContext: DataContext
DataApp.description?: ReactNode — Override the declared subtitle; null hides it.
DataApp.showToolbar?: boolean — Show page actions. Defaults to true; does not hide filters or data states.
DataApp.toolbarActions?: ReactNode
DataApp.footerActions?: ReactNode
DataApp.footer?: ReactNode — Optional source, coverage, or methodology note below the app content. Compose prose and inline components; typography and spacing are provided.
Expand Down Expand Up @@ -342,6 +344,7 @@ DataAppProps (type, @altertable/data-app-react/ui)
DataAppProps.children: ReactNode
DataAppProps.dataContext: DataContext
DataAppProps.description?: ReactNode — Override the declared subtitle; null hides it.
DataAppProps.showToolbar?: boolean — Show page actions. Defaults to true; does not hide filters or data states.
DataAppProps.toolbarActions?: ReactNode
DataAppProps.footerActions?: ReactNode
DataAppProps.footer?: ReactNode — Optional source, coverage, or methodology note below the app content. Compose prose and inline components; typography and spacing are provided.
Expand Down
42 changes: 42 additions & 0 deletions bun.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions dev/fixtures/bundle-host.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ if (isPlayground)
document.title = `${isContentSizing ? 'Content sizing' : 'Playground'} · Altertable`;
const appPreview = [
'/starter-data-app',
'/starter-metric-data-app',
'/starter-finding-data-app',
'/playground',
'/content-sizing',
].includes(location.pathname);
Expand Down
31 changes: 31 additions & 0 deletions dev/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ import styles from '@/dev/fixtures/styles.html';
import { dataApp as starterApp } from '@/packages/data-app-examples/templates/starter-local-data-app/app';
import starterPage from '@/packages/data-app-examples/templates/starter-local-data-app/src/index.html';
import { operations as starterOperations } from '@/packages/data-app-examples/templates/starter-local-data-app/src/operations';
import findingStarterPage from '@/packages/data-app-examples/templates/starter-local-finding-data-app/src/index.html';
import { operations as findingStarterOperations } from '@/packages/data-app-examples/templates/starter-local-finding-data-app/src/operations';
import metricStarterPage from '@/packages/data-app-examples/templates/starter-local-metric-data-app/src/index.html';
import { operations as metricStarterOperations } from '@/packages/data-app-examples/templates/starter-local-metric-data-app/src/operations';

async function bundle(entry: string) {
const result = await Bun.build({
Expand Down Expand Up @@ -93,6 +97,12 @@ const hostedApps = {
},
};
const hostedApp = hostedApps[isDevelopment ? 'development' : 'test'];
const loadMetricStarterBundle = await createBundleLoader(
'../packages/data-app-examples/templates/starter-metric-data-app/index.tsx'
);
const loadFindingStarterBundle = await createBundleLoader(
'../packages/data-app-examples/templates/starter-finding-data-app/index.tsx'
);
const loadHostedAppBundle = await createBundleLoader(hostedApp.entry);
const loadPlaygroundBundle = isDevelopment
? loadHostedAppBundle
Expand All @@ -101,6 +111,7 @@ const serveReloadEvents =
isDevelopment &&
createReloadHandler([
'../dev',
'../packages/data-app-examples/templates',
'./fixtures/bundle-app.tsx',
'./fixtures/bridge-frame.ts',
]);
Expand All @@ -120,6 +131,20 @@ serveLocalApp({
title: starterApp.title,
port: port + 2,
});
if (isDevelopment)
serveLocalApp({
page: metricStarterPage,
operations: metricStarterOperations,
title: 'Local metric starter',
port: port + 3,
});
if (isDevelopment)
serveLocalApp({
page: findingStarterPage,
operations: findingStarterOperations,
title: 'Local finding starter',
port: port + 4,
});
const loadFrameBundle = await createBundleLoader('./fixtures/bridge-frame.ts');
Bun.serve({
hostname: '127.0.0.1',
Expand Down Expand Up @@ -153,6 +178,8 @@ Bun.serve({
'/playground': bundleHost,
'/content-sizing': bundleHost,
[hostedApp.path]: bundleHost,
'/starter-finding-data-app': bundleHost,
'/starter-metric-data-app': bundleHost,
},
async fetch(request, server) {
const path = new URL(request.url).pathname;
Expand Down Expand Up @@ -204,6 +231,10 @@ Bun.serve({
}
if (path === '/__test/content-sizing')
return new Response(await loadHostedAppBundle());
if (path === '/__test/starter-metric-data-app')
return new Response(await loadMetricStarterBundle());
if (path === '/__test/starter-finding-data-app')
return new Response(await loadFindingStarterBundle());
if (path === '/__test/playground')
return new Response(await loadPlaygroundBundle());
if (path === `/__test${hostedApp.path}`)
Expand Down
14 changes: 14 additions & 0 deletions dev/starter-mock.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/** Mock image with DuckDB 2 and semantic_layer (altertable-mock PR #31). */
export const starterMockImage =
'ghcr.io/altertable-ai/altertable-mock@sha256:fc23b3fc07865b4d469f0451e36ee1f514e321848abdc38cc4a267e8ccfa33d0';

/** Fictional evidence shared by the metric and Finding examples. Never run on a user's lakehouse. */
export const starterSeedStatements = [
'CREATE SCHEMA starter_demo',
'CREATE TABLE starter_demo.sample_counts (group_name VARCHAR, segment_name VARCHAR, sample_count BIGINT)',
"INSERT INTO starter_demo.sample_counts VALUES ('Alpha', 'Online', 1500000), ('Alpha', 'Retail', 700000), ('Beta', 'Partner', 600000)",
`CREATE SEMANTIC VIEW starter_sample_counts
TABLES (samples AS starter_demo.sample_counts)
DIMENSIONS (samples.group_name AS group_name, samples.segment_name AS segment_name)
METRICS (samples.sample_count AS SUM(samples.sample_count))`,
];
9 changes: 6 additions & 3 deletions docs/app-authoring.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,13 @@ for the requested change. For a new app, use the starter supplied by the authori
| ----------------------- | ------------------------------------------------------------------- |
| Hosted / remote / cloud | `starter-data-app/index.tsx` |
| Local | `starter-local-data-app` |
| Hosted metric | `starter-metric-data-app/index.tsx` |
| Hosted Finding | `starter-finding-data-app/index.tsx` |
| Local metric | `starter-local-metric-data-app` |
| Local Finding | `starter-local-finding-data-app` |

These are the currently shipped runtime starters. Select a use-case starter when
one is supplied by the authoring workflow; otherwise adapt the shared starter's
sample content to the app brief. The hosted starter demonstrates query → operation
Choose the runtime and use case supplied by the app brief. Each starter is editable
source; replace fixture queries and sample content before publishing. The hosted starter demonstrates query → operation
→ context → view → dataset → widget composition, including a story example.
Hosted apps stay in one file with public package imports
and a literal `defineDataApp()` declaration. Local apps use the same composition
Expand Down
18 changes: 16 additions & 2 deletions docs/local-data-apps.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

Use the local scaffold supplied by your authoring workflow. Its README covers
setup and its AGENTS.md identifies app-owned files.
Replace the connectivity screen with the content specified by the app brief or
authoring skill, using the [shared SDK patterns](app-authoring.md). Local execution
Replace the connectivity screen or fixture examples with the content specified by
the app brief, using the [shared SDK patterns](app-authoring.md). Local execution
does not require a particular content structure or presentation story.

| Task | Documentation |
Expand All @@ -13,3 +13,17 @@ does not require a particular content structure or presentation story.
| Customize the browser client | [HTTP client](client.md#http-operations) |

You can also [convert the local app to a hosted data app](hosted-apps.md#convert-a-local-data-app).

## Preview the use-case starters

From the SDK repository, run `bun run dev:gallery` with Docker available. It starts
and seeds the Altertable mock with fictional sample data.

| Starter | Hosted preview | Local preview |
| ------- | ------------------------------------------------- | ------------------------ |
| Metric | <http://127.0.0.1:27418/starter-metric-data-app> | <http://127.0.0.1:27421> |
| Finding | <http://127.0.0.1:27418/starter-finding-data-app> | <http://127.0.0.1:27422> |

Copied starters use the normal query connection. Replace their example queries
with verified sources in the target lakehouse; the mock and seed belong only to
local development. Never create demo objects in a user's lakehouse.
12 changes: 7 additions & 5 deletions docs/stories-and-export.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
# Stories and CSV export

The current bound `<DataApp>` from `@altertable/data-app-react` requires a `story`
callback and a nonempty `datasets` list. Both use the displayed snapshot, including
during refresh or failure. A story callback returning `[]` leaves a disabled
presentation action; it does not hide the toolbar. Setup and static screens can use `<DataApp>`
from `/ui`, which may omit both.
The bound `<DataApp>` from `@altertable/data-app-react` accepts an optional `story`
callback and optional nonempty `datasets` list. Omit either prop to omit its toolbar
control. Supplied features use the displayed snapshot, including during refresh or
failure. A story callback returning `[]` leaves a disabled presentation action.
Set `showToolbar={false}` to omit page actions together; data loading, error states,
and declared filters remain available. Setup and static screens can use `<DataApp>`
from `/ui`.

These are component contracts. The app brief determines the
intended presentation and export coverage. A presentation story is distinct from
Expand Down
6 changes: 3 additions & 3 deletions knip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -85,10 +85,10 @@ export default {
},
'packages/data-app-examples': {
...packages['packages/data-app-examples'],
entry: ['src/index.ts', 'templates/starter-data-app/index.tsx'],
project: ['src/**/*.ts', 'templates/starter-data-app/*.tsx'],
entry: ['src/index.ts', 'templates/starter-*/index.tsx'],
project: ['src/**/*.ts', 'templates/starter-*/*.tsx'],
},
'packages/data-app-examples/templates/starter-local-data-app': {
'packages/data-app-examples/templates/starter-local-*': {
entry: ['src/server.ts', 'src/main.tsx'],
project: ['src/**/*.{ts,tsx}'],
},
Expand Down
6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"private": true,
"workspaces": [
"packages/*",
"packages/data-app-examples/templates/starter-local-data-app"
"packages/data-app-examples/templates/starter-local-*"
],
"type": "module",
"scripts": {
Expand All @@ -14,14 +14,14 @@
"dev:file": "bun run scripts/dev-file.ts",
"dev:dir": "bun run scripts/dev-dir.ts",
"typecheck": "tsc --noEmit && bun run --filter '@altertable/*' typecheck",
"lint": "oxlint --type-aware packages/*/src packages/data-app-examples/templates/starter-data-app tests scripts dev vitest.config.ts knip.ts",
"lint": "oxlint --type-aware packages/*/src packages/data-app-examples/templates/starter-data-app packages/data-app-examples/templates/starter-metric-data-app packages/data-app-examples/templates/starter-finding-data-app tests scripts dev vitest.config.ts knip.ts",
"format": "oxfmt .",
"format:check": "oxfmt --check .",
"test": "vitest run",
"check": "bun run build && bun run check:boundaries && bun run typecheck && bun run lint && bun run knip && bun run check:styles && bun run lint:md && bun run check:links && bun run format:check && bun run test && bun run check:reference && bun run check:package && bun run check:starter",
"check:package": "bun run scripts/check-package.ts",
"check:workflows": "bash scripts/check-workflows.sh",
"lint:fix": "oxlint --type-aware --fix packages/*/src packages/data-app-examples/templates/starter-data-app tests scripts dev vitest.config.ts knip.ts",
"lint:fix": "oxlint --type-aware --fix packages/*/src packages/data-app-examples/templates/starter-data-app packages/data-app-examples/templates/starter-metric-data-app packages/data-app-examples/templates/starter-finding-data-app tests scripts dev vitest.config.ts knip.ts",
"check:starter": "bun run scripts/check-starter.ts",
"lint:md": "markdownlint-cli2",
"check:links": "remark . --ext md --rc-path .remarkrc.json --frail --no-stdout",
Expand Down
12 changes: 8 additions & 4 deletions packages/data-app-examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,14 @@ on this package.

## Starters

| ID | Use |
| ------------------------ | ------------------------------------------------------------------------- |
| `starter-data-app` | [Hosted single-file app](templates/starter-data-app/index.tsx) |
| `starter-local-data-app` | [Local Bun and React project](templates/starter-local-data-app/README.md) |
| ID | Use |
| -------------------------------- | ------------------------------------------------------------------------- |
| `starter-data-app` | [Hosted single-file app](templates/starter-data-app/index.tsx) |
| `starter-local-data-app` | [Local Bun and React project](templates/starter-local-data-app/README.md) |
| `starter-metric-data-app` | [Hosted metric app](templates/starter-metric-data-app/index.tsx) |
| `starter-finding-data-app` | [Hosted finding app](templates/starter-finding-data-app/index.tsx) |
| `starter-local-metric-data-app` | [Local metric app](templates/starter-local-metric-data-app/README.md) |
| `starter-local-finding-data-app` | [Local finding app](templates/starter-local-finding-data-app/README.md) |

Pin to the same exact version as `@altertable/data-app`. Authoring guides and
API reference ship in that base package.
Expand Down
24 changes: 24 additions & 0 deletions packages/data-app-examples/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,30 @@ export const dataAppExamples = [
description: 'A Bun and React project with server-side lakehouse access.',
mode: 'local',
},
{
id: 'starter-metric-data-app',
title: 'Hosted metric illustration',
description: 'A focused metric app for hosted execution.',
mode: 'hosted',
},
{
id: 'starter-finding-data-app',
title: 'Hosted Finding document',
description: 'A focused finding app for hosted execution.',
mode: 'hosted',
},
{
id: 'starter-local-metric-data-app',
title: 'Local metric illustration',
description: 'A focused metric app for local execution.',
mode: 'local',
},
{
id: 'starter-local-finding-data-app',
title: 'Local Finding document',
description: 'A focused finding app for local execution.',
mode: 'local',
},
] as const;

/** Stable identifier for a canonical starter. */
Expand Down
Loading