MCPcopy Create free account
hub / github.com/microsoft/data-formulator / SimpleChartRecBox

Function SimpleChartRecBox

src/views/SimpleChartRecBox.tsx:119–1796  ·  view source on GitHub ↗
({ onInputFocus })

Source from the content-addressed store, hash-verified

117};
118
119export const SimpleChartRecBox: FC<{ onInputFocus?: () => void }> = function ({ onInputFocus }) {
120
121 const tables = useSelector((state: DataFormulatorState) => state.tables);
122 const focusedId = useSelector((state: DataFormulatorState) => state.focusedId);
123 const charts = useSelector(dfSelectors.getAllCharts);
124 const conceptShelfItems = useSelector((state: DataFormulatorState) => state.conceptShelfItems);
125 const config = useSelector((state: DataFormulatorState) => state.config);
126 const activeModel = useSelector(dfSelectors.getActiveModel);
127 const draftNodes = useSelector((state: DataFormulatorState) => state.draftNodes);
128 const chartThumbnails = useSelector((state: DataFormulatorState) => state.chartThumbnails) || {};
129
130 const theme = useTheme();
131 const { t } = useTranslation();
132 const dispatch = useDispatch<AppDispatch>();
133
134 const [chatPrompt, setChatPrompt] = useState("");
135 // ── Clarification accumulated answers ────────────────────────────
136 // When the agent asks one or more clarification questions, clicking an
137 // option does NOT submit immediately and does NOT mutate the chat box.
138 // We just track the selections here. The agent is invoked when the LAST
139 // question is answered via clicks, OR when the user explicitly hits
140 // Send / Enter (at which point the selections are formatted into a
141 // "Selected answers: ..." prefix and prepended to the typed message).
142 const [clarifyAnswers, setClarifyAnswers] = useState<Record<number, ClarificationResponse>>({});
143 // Guards against double-submit when the user rapidly clicks the last
144 // option twice (state updates are async, so a second click can re-enter
145 // handleSelectAnswer with a stale closure before pendingClarification
146 // clears). Tracks the draftId we've already auto-submitted for.
147 const clarifySubmittedRef = useRef<string | null>(null);
148 const [isChatFormulating, setIsChatFormulating] = useState(false);
149 const [mentionedTableIds, setMentionedTableIds] = useState<string[]>([]);
150 const [mentionDropdownOpen, setMentionDropdownOpen] = useState(false);
151 const [mentionHighlightIdx, setMentionHighlightIdx] = useState(0);
152 const [selectedAgent, setSelectedAgent] = useState<'explore' | 'report'>('explore');
153 const [attachedImages, setAttachedImages] = useState<string[]>([]);
154 const [uploadDialogOpen, setUploadDialogOpen] = useState(false);
155 const agentAbortRef = useRef<AbortController | null>(null);
156 const userChartFocusLockedRef = useRef(false);
157 const lastAutoFocusedChartIdRef = useRef<string | null>(null);
158 // Whether we've already auto-focused an artifact during the current
159 // agent run. We only jump focus once per run (to the FIRST generated
160 // chart), so the user isn't yanked around as further charts stream in.
161 // Subsequent artifacts rely on the "freshly created" highlight + NEW
162 // tag for discoverability instead.
163 const firstFocusedThisRunRef = useRef(false);
164
165 useEffect(() => {
166 if (!isChatFormulating) {
167 userChartFocusLockedRef.current = false;
168 lastAutoFocusedChartIdRef.current = null;
169 firstFocusedThisRunRef.current = false;
170 return;
171 }
172 if (focusedId?.type === 'chart') {
173 if (focusedId.chartId !== lastAutoFocusedChartIdRef.current) {
174 userChartFocusLockedRef.current = true;
175 }
176 } else {

Callers

nothing calls this directly

Calls 13

getTriggersFunction · 0.90
streamRequestFunction · 0.90
getUrlsFunction · 0.90
getErrorMessageFunction · 0.90
translateBackendFunction · 0.90
createNextDraftFunction · 0.85
processStreamingResultFunction · 0.85
handleCompletionFunction · 0.85
scheduleFlushFunction · 0.85
flushNowFunction · 0.85
confirmMentionFunction · 0.85

Tested by

no test coverage detected