Skip to content

Commit 3d35224

Browse files
authored
chore(search-bar): Break down query state actions (#100955)
This PR breaks down the different `UPDATE_FREE_TEXT` and `REPLACE_TOKENS_TEXT` to versions with specific actions. This will help with work to enable replacement when a raw search key is present.
1 parent a4b25e2 commit 3d35224

File tree

4 files changed

+130
-25
lines changed

4 files changed

+130
-25
lines changed

static/app/components/searchQueryBuilder/hooks/useQueryBuilderState.tsx

Lines changed: 114 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,18 +77,94 @@ type DeleteTokensAction = {
7777
focusOverride?: FocusOverride;
7878
};
7979

80-
type UpdateFreeTextAction = {
80+
type UpdateFreeTextActionOnSelect = {
8181
shouldCommitQuery: boolean;
8282
text: string;
8383
tokens: ParseResultToken[];
84-
type: 'UPDATE_FREE_TEXT';
84+
type: 'UPDATE_FREE_TEXT_ON_SELECT';
8585
focusOverride?: FocusOverride;
8686
};
8787

88-
type ReplaceTokensWithTextAction = {
88+
type UpdateFreeTextActionOnBlur = {
89+
shouldCommitQuery: boolean;
90+
text: string;
91+
tokens: ParseResultToken[];
92+
type: 'UPDATE_FREE_TEXT_ON_BLUR';
93+
focusOverride?: FocusOverride;
94+
};
95+
96+
type UpdateFreeTextActionOnCommit = {
97+
shouldCommitQuery: boolean;
8998
text: string;
9099
tokens: ParseResultToken[];
91-
type: 'REPLACE_TOKENS_WITH_TEXT';
100+
type: 'UPDATE_FREE_TEXT_ON_COMMIT';
101+
focusOverride?: FocusOverride;
102+
};
103+
104+
type UpdateFreeTextActionOnExit = {
105+
shouldCommitQuery: boolean;
106+
text: string;
107+
tokens: ParseResultToken[];
108+
type: 'UPDATE_FREE_TEXT_ON_EXIT';
109+
focusOverride?: FocusOverride;
110+
};
111+
112+
type UpdateFreeTextActionOnFunction = {
113+
shouldCommitQuery: boolean;
114+
text: string;
115+
tokens: ParseResultToken[];
116+
type: 'UPDATE_FREE_TEXT_ON_FUNCTION';
117+
focusOverride?: FocusOverride;
118+
};
119+
120+
type UpdateFreeTextActionOnParenthesis = {
121+
shouldCommitQuery: boolean;
122+
text: string;
123+
tokens: ParseResultToken[];
124+
type: 'UPDATE_FREE_TEXT_ON_PARENTHESIS';
125+
focusOverride?: FocusOverride;
126+
};
127+
128+
type UpdateFreeTextActionOnColon = {
129+
shouldCommitQuery: boolean;
130+
text: string;
131+
tokens: ParseResultToken[];
132+
type: 'UPDATE_FREE_TEXT_ON_COLON';
133+
focusOverride?: FocusOverride;
134+
};
135+
136+
type ReplaceTokensWithTextOnPasteAction = {
137+
text: string;
138+
tokens: ParseResultToken[];
139+
type: 'REPLACE_TOKENS_WITH_TEXT_ON_PASTE';
140+
focusOverride?: FocusOverride;
141+
};
142+
143+
type ReplaceTokensWithTextOnDeleteAction = {
144+
text: string;
145+
tokens: ParseResultToken[];
146+
type: 'REPLACE_TOKENS_WITH_TEXT_ON_DELETE';
147+
focusOverride?: FocusOverride;
148+
};
149+
150+
type ReplaceTokensWithTextOnCutAction = {
151+
text: string;
152+
tokens: ParseResultToken[];
153+
type: 'REPLACE_TOKENS_WITH_TEXT_ON_CUT';
154+
focusOverride?: FocusOverride;
155+
};
156+
157+
type ReplaceTokensWithTextOnKeyDownAction = {
158+
text: string;
159+
tokens: ParseResultToken[];
160+
type: 'REPLACE_TOKENS_WITH_TEXT_ON_KEY_DOWN';
161+
focusOverride?: FocusOverride;
162+
};
163+
164+
type ReplaceTokensWithTextOnSelectAction = {
165+
text: string;
166+
tokens: ParseResultToken[];
167+
type: 'REPLACE_TOKENS_WITH_TEXT_ON_SELECT';
92168
focusOverride?: FocusOverride;
93169
};
94170

@@ -126,15 +202,34 @@ type UpdateAggregateArgsAction = {
126202

127203
type ResetClearAskSeerFeedbackAction = {type: 'RESET_CLEAR_ASK_SEER_FEEDBACK'};
128204

205+
type UpdateFreeTextActions =
206+
| UpdateFreeTextActionOnSelect
207+
| UpdateFreeTextActionOnBlur
208+
| UpdateFreeTextActionOnCommit
209+
| UpdateFreeTextActionOnExit
210+
| UpdateFreeTextActionOnFunction
211+
| UpdateFreeTextActionOnParenthesis
212+
| UpdateFreeTextActionOnColon;
213+
129214
export type QueryBuilderActions =
130215
| ClearAction
131216
| CommitQueryAction
132217
| UpdateQueryAction
133218
| ResetFocusOverrideAction
134219
| DeleteTokenAction
135220
| DeleteTokensAction
136-
| UpdateFreeTextAction
137-
| ReplaceTokensWithTextAction
221+
| UpdateFreeTextActionOnSelect
222+
| UpdateFreeTextActionOnBlur
223+
| UpdateFreeTextActionOnCommit
224+
| UpdateFreeTextActionOnExit
225+
| UpdateFreeTextActionOnFunction
226+
| UpdateFreeTextActionOnParenthesis
227+
| UpdateFreeTextActionOnColon
228+
| ReplaceTokensWithTextOnPasteAction
229+
| ReplaceTokensWithTextOnDeleteAction
230+
| ReplaceTokensWithTextOnCutAction
231+
| ReplaceTokensWithTextOnKeyDownAction
232+
| ReplaceTokensWithTextOnSelectAction
138233
| UpdateFilterKeyAction
139234
| UpdateFilterOpAction
140235
| UpdateTokenValueAction
@@ -361,7 +456,7 @@ function replaceTokensWithPadding(
361456

362457
function updateFreeText(
363458
state: QueryBuilderState,
364-
action: UpdateFreeTextAction
459+
action: UpdateFreeTextActions
365460
): QueryBuilderState {
366461
const newQuery = replaceTokensWithPadding(state.query, action.tokens, action.text);
367462

@@ -636,7 +731,13 @@ export function useQueryBuilderState({
636731
clearAskSeerFeedback: displayAskSeerFeedback ? true : false,
637732
};
638733
}
639-
case 'UPDATE_FREE_TEXT': {
734+
case 'UPDATE_FREE_TEXT_ON_SELECT':
735+
case 'UPDATE_FREE_TEXT_ON_BLUR':
736+
case 'UPDATE_FREE_TEXT_ON_COMMIT':
737+
case 'UPDATE_FREE_TEXT_ON_EXIT':
738+
case 'UPDATE_FREE_TEXT_ON_FUNCTION':
739+
case 'UPDATE_FREE_TEXT_ON_PARENTHESIS':
740+
case 'UPDATE_FREE_TEXT_ON_COLON': {
640741
const newState = updateFreeText(state, action);
641742

642743
return {
@@ -645,7 +746,11 @@ export function useQueryBuilderState({
645746
newState.query !== state.query && displayAskSeerFeedback ? true : false,
646747
};
647748
}
648-
case 'REPLACE_TOKENS_WITH_TEXT':
749+
case 'REPLACE_TOKENS_WITH_TEXT_ON_CUT':
750+
case 'REPLACE_TOKENS_WITH_TEXT_ON_PASTE':
751+
case 'REPLACE_TOKENS_WITH_TEXT_ON_DELETE':
752+
case 'REPLACE_TOKENS_WITH_TEXT_ON_SELECT':
753+
case 'REPLACE_TOKENS_WITH_TEXT_ON_KEY_DOWN':
649754
return replaceTokensWithText(state, {
650755
tokens: action.tokens,
651756
text: action.text,

static/app/components/searchQueryBuilder/selectionKeyHandler.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ export function SelectionKeyHandler({
4646
const text = e.clipboardData.getData('text/plain').replace('\n', '').trim();
4747

4848
dispatch({
49-
type: 'REPLACE_TOKENS_WITH_TEXT',
49+
type: 'REPLACE_TOKENS_WITH_TEXT_ON_PASTE',
5050
tokens: selectedTokens,
5151
text,
5252
});
@@ -62,7 +62,7 @@ export function SelectionKeyHandler({
6262
e.preventDefault();
6363
e.stopPropagation();
6464
dispatch({
65-
type: 'REPLACE_TOKENS_WITH_TEXT',
65+
type: 'REPLACE_TOKENS_WITH_TEXT_ON_DELETE',
6666
tokens: selectedTokens,
6767
text: '',
6868
});
@@ -128,7 +128,7 @@ export function SelectionKeyHandler({
128128
state.selectionManager.clearSelection();
129129
copySelectedTokens();
130130
dispatch({
131-
type: 'REPLACE_TOKENS_WITH_TEXT',
131+
type: 'REPLACE_TOKENS_WITH_TEXT_ON_CUT',
132132
tokens: selectedTokens,
133133
text: '',
134134
});
@@ -145,7 +145,7 @@ export function SelectionKeyHandler({
145145
// If the key pressed will generate a symbol, replace the selection with it
146146
if (/^.$/u.test(e.key)) {
147147
dispatch({
148-
type: 'REPLACE_TOKENS_WITH_TEXT',
148+
type: 'REPLACE_TOKENS_WITH_TEXT_ON_KEY_DOWN',
149149
text: e.key,
150150
tokens: selectedTokens,
151151
});

static/app/components/searchQueryBuilder/tokens/filter/filterKeyCombobox.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ export function FilterKeyCombobox({token, onCommit, item}: KeyComboboxProps) {
106106
}
107107

108108
dispatch({
109-
type: 'REPLACE_TOKENS_WITH_TEXT',
109+
type: 'REPLACE_TOKENS_WITH_TEXT_ON_SELECT',
110110
tokens: [token],
111111
text: getInitialFilterText(keyName, newFieldDef),
112112
focusOverride: {

static/app/components/searchQueryBuilder/tokens/freeText.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,7 @@ function SearchQueryBuilderInputInternal({
383383
.trim();
384384

385385
dispatch({
386-
type: 'REPLACE_TOKENS_WITH_TEXT',
386+
type: 'REPLACE_TOKENS_WITH_TEXT_ON_PASTE',
387387
tokens: [token],
388388
text: clipboardText,
389389
});
@@ -429,7 +429,7 @@ function SearchQueryBuilderInputInternal({
429429

430430
if (option.type === 'raw-search') {
431431
dispatch({
432-
type: 'UPDATE_FREE_TEXT',
432+
type: 'UPDATE_FREE_TEXT_ON_SELECT',
433433
tokens: [token],
434434
text: option.value,
435435
shouldCommitQuery: true,
@@ -440,7 +440,7 @@ function SearchQueryBuilderInputInternal({
440440

441441
if (option.type === 'filter-value' && option.textValue) {
442442
dispatch({
443-
type: 'UPDATE_FREE_TEXT',
443+
type: 'UPDATE_FREE_TEXT_ON_SELECT',
444444
tokens: [token],
445445
text: replaceFocusedWord(inputValue, selectionIndex, option.textValue),
446446
focusOverride: calculateNextFocusForInsertedToken(item),
@@ -452,7 +452,7 @@ function SearchQueryBuilderInputInternal({
452452

453453
if (option.type === 'raw-search-filter-is-value' && option.textValue) {
454454
dispatch({
455-
type: 'UPDATE_FREE_TEXT',
455+
type: 'UPDATE_FREE_TEXT_ON_SELECT',
456456
tokens: [token],
457457
text: option.textValue,
458458
focusOverride: calculateNextFocusForInsertedToken(item),
@@ -465,7 +465,7 @@ function SearchQueryBuilderInputInternal({
465465
const value = option.value;
466466

467467
dispatch({
468-
type: 'UPDATE_FREE_TEXT',
468+
type: 'UPDATE_FREE_TEXT_ON_SELECT',
469469
tokens: [token],
470470
text: replaceFocusedWordWithFilter(
471471
inputValue,
@@ -497,7 +497,7 @@ function SearchQueryBuilderInputInternal({
497497
}}
498498
onCustomValueBlurred={value => {
499499
dispatch({
500-
type: 'UPDATE_FREE_TEXT',
500+
type: 'UPDATE_FREE_TEXT_ON_BLUR',
501501
tokens: [token],
502502
text: value,
503503
focusOverride: calculateNextFocusForCommittedCustomValue({
@@ -517,7 +517,7 @@ function SearchQueryBuilderInputInternal({
517517

518518
// Otherwise, commit the query (which will trigger a search)
519519
dispatch({
520-
type: 'UPDATE_FREE_TEXT',
520+
type: 'UPDATE_FREE_TEXT_ON_COMMIT',
521521
tokens: [token],
522522
text: value,
523523
focusOverride: calculateNextFocusForCommittedCustomValue({
@@ -531,7 +531,7 @@ function SearchQueryBuilderInputInternal({
531531
onExit={() => {
532532
if (inputValue !== token.value.trim()) {
533533
dispatch({
534-
type: 'UPDATE_FREE_TEXT',
534+
type: 'UPDATE_FREE_TEXT_ON_EXIT',
535535
tokens: [token],
536536
text: inputValue,
537537
shouldCommitQuery: false,
@@ -568,7 +568,7 @@ function SearchQueryBuilderInputInternal({
568568
getFieldDefinition(maybeFunction.value)?.kind === FieldKind.FUNCTION
569569
) {
570570
dispatch({
571-
type: 'UPDATE_FREE_TEXT',
571+
type: 'UPDATE_FREE_TEXT_ON_FUNCTION',
572572
tokens: [token],
573573
text: replaceFocusedWordWithFilter(
574574
inputValue,
@@ -591,7 +591,7 @@ function SearchQueryBuilderInputInternal({
591591

592592
// It's not a function so treat it as just a parenthesis
593593
dispatch({
594-
type: 'UPDATE_FREE_TEXT',
594+
type: 'UPDATE_FREE_TEXT_ON_PARENTHESIS',
595595
tokens: [token],
596596
text: e.target.value,
597597
focusOverride: calculateNextFocusForInsertedToken(item),
@@ -611,7 +611,7 @@ function SearchQueryBuilderInputInternal({
611611
const filterKey = getSuggestedFilterKey(filterValue) ?? filterValue;
612612
const key = filterKeys[filterKey];
613613
dispatch({
614-
type: 'UPDATE_FREE_TEXT',
614+
type: 'UPDATE_FREE_TEXT_ON_COLON',
615615
tokens: [token],
616616
text: replaceFocusedWordWithFilter(
617617
inputValue,

0 commit comments

Comments
 (0)