mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
Chart builder: discoverable entry points — Build Chart door, dataset picker, no-datasets state
This commit is contained in:
@@ -61,7 +61,7 @@ import type { ColumnType } from '@core/type-inference';
|
||||
import { DatasetNotFoundError, prepareSpecForRender } from '@core/rendering';
|
||||
import { chartConfigFor } from '@core/vega-themes';
|
||||
import { ChartTooLargeError, renderSpec, type RenderHandle } from '../services/chart-renderer';
|
||||
import { closeModal } from '../modals/ModalCoordinator';
|
||||
import { closeModal, openModal } from '../modals/ModalCoordinator';
|
||||
import { useAppStore } from '../stores/AppStore';
|
||||
import { useDatasetStore } from '../stores/DatasetStore';
|
||||
import {
|
||||
@@ -1264,9 +1264,62 @@ function ChartProps() {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The dataset picker at the top of the config pane (spec §06 → Dataset picker):
|
||||
* which data the chart builds from is itself a builder choice, so the builder can
|
||||
* open without a preselected dataset and the data can be switched without leaving.
|
||||
* Switching re-derives smart defaults while the config is untouched, and rebases
|
||||
* (keeps chart-level intent, sheds bindings to missing columns) once it isn't.
|
||||
*/
|
||||
function DatasetPicker({ datasetId }: { datasetId: number | null }) {
|
||||
const datasets = useDatasetStore(useShallow((s) => s.datasets));
|
||||
const switchDataset = useChartBuilderStore((s) => s.switchDataset);
|
||||
return (
|
||||
<div className={styles.datasetRow}>
|
||||
<span className={styles.fieldLabel}>Dataset</span>
|
||||
<SelectControl
|
||||
id="cb-dataset"
|
||||
label="Dataset to build from"
|
||||
heading="Dataset"
|
||||
options={datasets.map((d) => ({ value: String(d.id), label: d.name }))}
|
||||
value={datasetId !== null ? String(datasetId) : undefined}
|
||||
onSelect={(v) => switchDataset(Number(v))}
|
||||
triggerContent={datasetId === null ? 'Choose a dataset…' : undefined}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The no-datasets state (spec §06 → Opening; Carbon no-data empty state): says
|
||||
* what the builder does and offers the one next step — never a dead end. The
|
||||
* action swaps this modal for the Datasets manager opened on its create form.
|
||||
*/
|
||||
function NoDatasets() {
|
||||
return (
|
||||
<div className={styles.emptyState}>
|
||||
<h3 className={styles.emptyTitle}>No datasets yet</h3>
|
||||
<p className={styles.emptyBody}>
|
||||
The Chart Builder turns a saved dataset into a chart — pick columns, watch the chart take
|
||||
shape, and save it as a snippet. Add a dataset to start building.
|
||||
</p>
|
||||
<button
|
||||
type="button"
|
||||
className={`${styles.action} ${styles.primary}`}
|
||||
onClick={() => {
|
||||
openModal('datasets');
|
||||
useDatasetStore.getState().startCreate();
|
||||
}}
|
||||
>
|
||||
Add a dataset
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export function ChartBuilderModal() {
|
||||
const datasetId = useChartBuilderStore((s) => s.datasetId);
|
||||
const datasetName = useChartBuilderStore((s) => s.config.datasetName);
|
||||
const datasetCount = useDatasetStore((s) => s.datasets.length);
|
||||
const mark = useChartBuilderStore((s) => s.config.mark);
|
||||
const sort = useChartBuilderStore((s) => s.config.sort);
|
||||
const stack = useChartBuilderStore((s) => s.config.stack);
|
||||
@@ -1317,7 +1370,16 @@ export function ChartBuilderModal() {
|
||||
}, [warnings]);
|
||||
|
||||
if (datasetId === null) {
|
||||
return <p className={styles.muted}>No dataset loaded. Open this from a dataset in Datasets.</p>;
|
||||
if (datasetCount === 0) return <NoDatasets />;
|
||||
// Datasets exist but none is loaded (init auto-picks, so this is a fallback
|
||||
// for a builder restored into an odd state): offer the choice directly.
|
||||
return (
|
||||
<div className={styles.emptyState}>
|
||||
<h3 className={styles.emptyTitle}>Choose a dataset</h3>
|
||||
<p className={styles.emptyBody}>Pick the dataset to build a chart from.</p>
|
||||
<DatasetPicker datasetId={null} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -1326,9 +1388,7 @@ export function ChartBuilderModal() {
|
||||
<div className="visually-hidden" role="status" aria-live="polite">
|
||||
{fixAnnouncement}
|
||||
</div>
|
||||
<p className={styles.datasetName}>
|
||||
Building from <strong>{datasetName}</strong>
|
||||
</p>
|
||||
<DatasetPicker datasetId={datasetId} />
|
||||
|
||||
<DataSection />
|
||||
|
||||
|
||||
Reference in New Issue
Block a user