mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
Chart Builder: open a snippet in the builder to edit it in place
This commit is contained in:
@@ -13,7 +13,8 @@
|
||||
* inline near the editor (spec §03E), mirroring the preview via PreviewStore.
|
||||
*/
|
||||
|
||||
import { useEffect, useRef, type RefObject } from 'react';
|
||||
import { useEffect, useMemo, useRef, type RefObject } from 'react';
|
||||
import { useShallow } from 'zustand/react/shallow';
|
||||
// `edcore.main` is the full standalone editor — every feature contribution
|
||||
// (folding, suggest widget, word operations like Cmd+Backspace, find, bracket
|
||||
// colorization, multi-cursor, …) — but WITHOUT the `monaco-editor` barrel's
|
||||
@@ -24,7 +25,8 @@ import 'monaco-editor/esm/vs/language/json/monaco.contribution';
|
||||
import '../infrastructure/monaco-env'; // side-effect: wire workers before create
|
||||
import { configureVegaLiteJson } from '../infrastructure/monaco-schema';
|
||||
import { configureJsonFormatter, installFormatOnPaste } from '../infrastructure/monaco-format';
|
||||
import { openModal } from '../modals/ModalCoordinator';
|
||||
import { parseChartSpecText } from '@core/chart-builder';
|
||||
import { openChartBuilderForEdit, openModal } from '../modals/ModalCoordinator';
|
||||
import {
|
||||
installSpecConfigActions,
|
||||
runExtractConfig,
|
||||
@@ -33,6 +35,7 @@ import {
|
||||
} from '../services/spec-config-actions';
|
||||
import { useAppStore } from '../stores/AppStore';
|
||||
import { confirm } from '../stores/ConfirmStore';
|
||||
import { useDatasetStore } from '../stores/DatasetStore';
|
||||
import { hasInlineData } from '../stores/ExtractStore';
|
||||
import { publishActiveSnippet } from '../services/snippet-actions';
|
||||
import { notify } from '../stores/NotificationStore';
|
||||
@@ -193,6 +196,26 @@ function EditorToolbar({
|
||||
(s) => s.activeSnippetId !== null && hasInlineData(s.draftText),
|
||||
);
|
||||
|
||||
// Offer "Open in builder" only when the active snippet's published spec is
|
||||
// losslessly representable in the builder dialect AND its referenced dataset
|
||||
// exists — the gate the builder's openForEdit enforces (spec §06 → Open in
|
||||
// builder). Content-gated like Extract, so it is **hidden** when inapplicable
|
||||
// (the toolbar's convention for content-gated actions — vs Revert/Config, which
|
||||
// disable because they are merely state-gated; arch 10 §5). `datasetNames` is a
|
||||
// shallow-stable string[] so the memo doesn't churn (MEMORY → stable selectors).
|
||||
const activeSpec = useSnippetStore((s) => selectActiveSnippet(s)?.spec ?? null);
|
||||
const datasetNames = useDatasetStore(useShallow((s) => s.datasets.map((d) => d.name)));
|
||||
const canOpenInBuilder = useMemo(() => {
|
||||
if (activeSpec === null) return false;
|
||||
const config = parseChartSpecText(activeSpec);
|
||||
return config !== null && datasetNames.includes(config.datasetName);
|
||||
}, [activeSpec, datasetNames]);
|
||||
|
||||
const handleOpenInBuilder = () => {
|
||||
const snippet = selectActiveSnippet(useSnippetStore.getState());
|
||||
if (snippet) openChartBuilderForEdit(snippet);
|
||||
};
|
||||
|
||||
// Publish + its success toast live in one place (services/snippet-actions) so
|
||||
// the button and the Cmd/Ctrl+S shortcut (EventRouter) behave identically.
|
||||
const handlePublish = publishActiveSnippet;
|
||||
@@ -239,6 +262,17 @@ function EditorToolbar({
|
||||
to two lines and Revert/Publish stay on one row. The label rides in
|
||||
`title` (and the accessible name) when only the icon shows. Publish — the
|
||||
one primary action — keeps its label at every width. */}
|
||||
{canOpenInBuilder && (
|
||||
<Button
|
||||
className={styles.collapsible}
|
||||
onClick={handleOpenInBuilder}
|
||||
title="Open this chart in the visual builder to edit it"
|
||||
aria-label="Open in builder"
|
||||
>
|
||||
<Icon name="chart" className={styles.actionIcon} />
|
||||
<span className={styles.actionLabel}>Open in builder</span>
|
||||
</Button>
|
||||
)}
|
||||
{canExtract && (
|
||||
<Button
|
||||
className={styles.collapsible}
|
||||
|
||||
Reference in New Issue
Block a user