mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
Editor: view-scoped Extract-to-Dataset for inline and self-defined data
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* Extract-to-Dataset — the modal body (spec §03F).
|
||||
*
|
||||
* Shows a read-only preview of the active snippet draft's inline data and asks
|
||||
* Shows a read-only preview of the focused view's embedded data and asks
|
||||
* for a dataset name. On confirm it saves the data as a new dataset and rewrites
|
||||
* the draft to reference it by name (logic in ExtractStore), then force-closes
|
||||
* (the commit is the user's confirmation, so no discard prompt). Cancel leaves
|
||||
@@ -38,13 +38,13 @@ export function ExtractModal() {
|
||||
};
|
||||
|
||||
if (!source) {
|
||||
return <p className={styles.muted}>This snippet has no inline data to extract.</p>;
|
||||
return <p className={styles.muted}>This snippet has no embedded data to extract.</p>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={styles.extract}>
|
||||
<p className={styles.intro}>
|
||||
Save this snippet’s inline data as a reusable dataset. The spec will be rewritten to
|
||||
Save this snippet’s embedded data as a reusable dataset. The spec will be rewritten to
|
||||
reference it by name.
|
||||
</p>
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ import '../infrastructure/monaco-env'; // side-effect: wire workers before creat
|
||||
import { configureVegaLiteJson } from '../infrastructure/monaco-schema';
|
||||
import { configureJsonFormatter, installFormatOnPaste } from '../infrastructure/monaco-format';
|
||||
import { parseChartSpecText } from '@core/chart-builder';
|
||||
import { openChartBuilderForEdit, openModal } from '../modals/ModalCoordinator';
|
||||
import { openChartBuilderForEdit } from '../modals/ModalCoordinator';
|
||||
import {
|
||||
installSpecConfigActions,
|
||||
runExtractConfig,
|
||||
@@ -41,10 +41,11 @@ import {
|
||||
runWrap,
|
||||
} from '../services/spec-transform-actions';
|
||||
import { configureSpecDatasetHints } from '../services/spec-dataset-hints';
|
||||
import { runExtract } from '../services/extract-action';
|
||||
import { useAppStore } from '../stores/AppStore';
|
||||
import { confirm } from '../stores/ConfirmStore';
|
||||
import { useDatasetStore } from '../stores/DatasetStore';
|
||||
import { hasInlineData } from '../stores/ExtractStore';
|
||||
import { hasExtractableData } from '../stores/ExtractStore';
|
||||
import { publishActiveSnippet } from '../services/snippet-actions';
|
||||
import { notify } from '../stores/NotificationStore';
|
||||
import { usePreviewStore } from '../stores/PreviewStore';
|
||||
@@ -222,10 +223,11 @@ function EditorToolbar({
|
||||
const draft = s.editorView === 'draft' ? s.draftText : active.draftSpec;
|
||||
return draft !== active.spec;
|
||||
});
|
||||
// Offer Extract only when the live draft carries top-level inline data to lift
|
||||
// out (spec §03F → hidden when the spec has no inline data).
|
||||
// Offer Extract only when the live draft carries data to lift out — inline
|
||||
// `values` in any view, or a reference to a self-defined `datasets` entry (spec
|
||||
// §03F → hidden when there is nothing extractable).
|
||||
const canExtract = useSnippetStore(
|
||||
(s) => s.activeSnippetId !== null && hasInlineData(s.draftText),
|
||||
(s) => s.activeSnippetId !== null && hasExtractableData(s.draftText),
|
||||
);
|
||||
|
||||
// Offer "Open in builder" only when the active snippet's published spec is
|
||||
@@ -248,6 +250,14 @@ function EditorToolbar({
|
||||
if (snippet) openChartBuilderForEdit(snippet);
|
||||
};
|
||||
|
||||
// Extract is scoped to the view at the cursor (services/extract-action), so it
|
||||
// goes through the editor handle like the wrap/config actions, not a bare
|
||||
// openModal — the service captures the focused binding before opening the modal.
|
||||
const handleExtract = () => {
|
||||
const editor = editorRef.current;
|
||||
if (editor) runExtract(editor);
|
||||
};
|
||||
|
||||
// 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;
|
||||
@@ -315,8 +325,8 @@ function EditorToolbar({
|
||||
{canExtract && (
|
||||
<Button
|
||||
className={styles.collapsible}
|
||||
onClick={() => openModal('extract')}
|
||||
title="Extract inline data into a reusable dataset"
|
||||
onClick={handleExtract}
|
||||
title="Extract embedded data into a reusable dataset"
|
||||
aria-label="Extract to Dataset"
|
||||
>
|
||||
<Icon name="dataset" className={styles.actionIcon} />
|
||||
|
||||
Reference in New Issue
Block a user