Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(issues): add feature flags to issue stream search suggestions #83968

Merged
merged 15 commits into from
Feb 6, 2025

Conversation

aliu39
Copy link
Member

@aliu39 aliu39 commented Jan 23, 2025

Closes https://github.com/getsentry/team-replay/issues/532

Adds FF suggestions as their own section in issues stream search bar.
image

To do this, we make additional requests to /tags and /tags/<key>/values with the
?useFlagsBackend switch. For details on the backend, see changes in #83639.

Notes:

  • the actual search/filtering is a WIP. However, the tag endpoints this PR uses are working.
  • if a flag has the same name as another searchable field or tag, we don't suggest it in the flag section. We're expecting this to be an uncommon edge case, we can revisit if it becomes a problem.

@github-actions github-actions bot added the Scope: Frontend Automatically applied to PRs that change frontend components label Jan 23, 2025
Copy link

codecov bot commented Jan 23, 2025

❌ 1 Tests Failed:

Tests completed Failed Passed Skipped
8629 1 8628 3
View the top 1 failed tests by shortest run time
WidgetBuilder discover dataset split events selects the error discover split type as the dataset when the events request completes
Stack Traces | 0.991s run time
Error: expect(element).toBeChecked()

Received element is not checked:
  <input aria-label="Errors (TypeError, InvalidSearchQuery, etc)" class="css-141lam5-Radio-checkedCss e72tocb0" type="radio" />
    at Object.<anonymous> (.../dashboards/widgetBuilder/widgetBuilder.spec.tsx:1605:13)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at processTimers (node:internal/timers:526:9)

To view more test analytics, go to the Test Analytics Dashboard
📢 Thoughts on this report? Let us know!

@cmanallen
Copy link
Member

@aliu39 Gate with this feature flag: https://github.com/getsentry/sentry-options-automator/pull/3051/files

@aliu39 aliu39 marked this pull request as ready for review January 28, 2025 23:46
@aliu39 aliu39 requested a review from a team as a code owner January 28, 2025 23:46
@aliu39 aliu39 requested a review from malwilley January 28, 2025 23:50
Copy link
Member

@malwilley malwilley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do see one big problem with this, is that the feature flags being fetched from the backend have colons in them, which isn't compatible with our search syntax that uses colons to separate the filter key from the filter value 🤔

(allTagsCollection[tag.key]!.totalValues ?? 0) + (tag.totalValues ?? 0);
} else {
// When a feature flag collides with a custom tag, we only suggest the tag.
// Searching for such a flag will filter by both tag and flag.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For tags that conflict with other search keys, we suggest tags[tag_name] instead. If the search backend supports that syntax, I'd do the same here (flags[flag_name]?)

Copy link
Member Author

@aliu39 aliu39 Jan 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've mentioned this to @cmanallen and @jas-kas and think we prefer to not use flags[. CC'ing here so we can align. The tags[ syntax seems (mostly?) deprecated - we don't use it in replays/feedback at least. On the backend, we check both columns (tags and flags) in an OR condition, so the actual filtering/search functionality is never broken.

The trade-off for not using flags[ syntax is we'd sacrifice flag suggestions when there's a conflict. The key would show up in the tag section, but not flags. It also wouldn't have the description
Screenshot 2025-01-30 at 2 14 36 PM
and would only suggest the tag values instead of true/false.

The reason there's this trade-off is because of the data structure for filterKeys (mapping[key -> metadata]). The way the search bar is currently built, if the key/name is the same, we can't case it into 2 different suggestions.

Is this trade-off ok for now?

Copy link
Member

@malwilley malwilley Jan 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason there's this trade-off is because of the data structure for filterKeys (mapping[key -> metadata]). The way the search bar is currently built, if the key/name is the same, we can't case it into 2 different suggestions.

Even if we allowed more advanced mapping for filterKeys, we need to have that information in the underlying search query string. Without it, we can't know if it's a flag or a tag when you refresh the page. e.g. you load the URL /issues?query=flag_and_tag:value and you click into the filter, which suggestions do you show? And what if the user only wants to target the flag and not the tag?

I'm okay with punting this for now and dealing with it later, but I would suggest more thought into how we can differentiate tags and flags in the search syntax. Especially since once we run into conflicts it will be very difficult to modify the syntax in the future

Copy link
Member Author

@aliu39 aliu39 Jan 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

e.g. you load the URL /issues?query=flag_and_tag:value and you click into the filter, which suggestions do you show?

I think this PR deals with this by only suggesting values from the tag. Since conflicting flags are simply dropped from filterKeys. Not ideal, as it prevents the flag from being discovered, and confuses users who're looking for the flag.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm sure you've probably already ruled this out, but this would fit into our current search syntax a lot better if it looked like:

feature_flag.on:["organizations:flag_1", "organizations_flag_2"]

feature_flag.off:["organizations:flag_3"]

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh we actually haven't considered that! Maybe the backend parser can use this as an alias for FF queries? cc @cmanallen

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@malwilley Feature flags are not just on/off values. They have the same properties as tags and we want to query them as though they were tags. They are only disambiguated on the back-end to prevent us from interfering with existing tag systems in ways that would be annoying to customers.

static/app/views/issueList/searchBar.tsx Outdated Show resolved Hide resolved
static/app/views/issueList/searchBar.tsx Outdated Show resolved Hide resolved
static/app/views/issueList/searchBar.tsx Outdated Show resolved Hide resolved
Copy link
Member

@cmanallen cmanallen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Merge-able? Protected by the autocomplete feature-flag?

Copy link

codecov bot commented Feb 3, 2025

Bundle Report

Changes will increase total bundle size by 11.47kB (0.03%) ⬆️. This is within the configured threshold ✅

Detailed changes
Bundle name Size Change
app-webpack-bundle-array-push 33.15MB 11.47kB (0.03%) ⬆️

Affected Assets, Files, and Routes:

view changes for bundle: app-webpack-bundle-array-push

Assets Changed:

Asset Name Size Change Total Size Change (%)
chunks/app_actionCreators_discoverHomepageQueries_tsx-app_bootstrap_initializeApp_tsx-app_components-2ddc8c.*.js -391 bytes 1.37MB -0.03%
chunks/app_components_assigneeBadge_tsx-app_components_badge_featureBadge_tsx-app_components_charts_-eed9e1.*.js 1.64kB 1.13MB 0.15%
chunks/app_actionCreators_guides_tsx-app_actionCreators_preferences_tsx-app_components_avatar_actorA-95b65d.*.js 30 bytes 290.6kB 0.01%
chunks/app_views_issueDetails_groupDetails_tsx.*.js 4.31kB 123.91kB 3.61%
entrypoints/app.js 4 bytes 98.71kB 0.0%
chunks/app_components_feedback_widget_us*kWidget_tsx-app_views_projectDetail_index_tsx.e2cf0ba9f259c5aab1c7.js (New) 94.59kB 94.59kB 100.0% 🚀
chunks/app_components_charts_eventsRequest_tsx-app_components_metrics_queryFieldGroup_tsx-app_views_-0eb303.*.js (New) 71.95kB 71.95kB 100.0% 🚀
chunks/app_components_charts_eventsRequest_tsx-app_components_charts_lineChart_tsx-app_utils_discove-a3f1dd.*.js (New) 59.34kB 59.34kB 100.0% 🚀
chunks/app_components_breadcrumbs_tsx-app_components_feedback_widget_us*kWidget_tsx-app_utils-df50cf.a3fd37b1cc872c3ec82e.js (New) 57.12kB 57.12kB 100.0% 🚀
chunks/app_views_stories_index_tsx.*.js -53 bytes 40.8kB -0.13%
chunks/app_components_charts_eventsRequest_tsx-app_components_feedback_widget_us*kWidget_tsx--64a49b.de22ebd007a0b7839f31.js (New) 37.72kB 37.72kB 100.0% 🚀
chunks/app_components_feedback_widget_us*kWidget_tsx-app_views_performance_transactionSummary-51d702.ea1ed89ea95a7f25e433.js (New) 37.17kB 37.17kB 100.0% 🚀
chunks/app_views_insights_uptime_views_overview_tsx.*.js 3.4kB 36.49kB 10.29% ⚠️
chunks/app_components_feedback_widget_us*kWidget_tsx-app_views_insights_common_components_cha-d2aaf9.c761c497bdb69a401dcf.js (New) 31.93kB 31.93kB 100.0% 🚀
chunks/app_components_feedback_widget_us*kWidget_tsx-app_components_performance_transactionSe-feae7d.c017bb44cd24302df963.js (New) 24.18kB 24.18kB 100.0% 🚀
chunks/app_components_checkInTimeline_checkInTimeline_tsx-app_components_checkInTimeline_gridLines_t-34069f.*.js (New) 18.74kB 18.74kB 100.0% 🚀
chunks/app_components_feedback_widget_us*kWidget_tsx-app_utils_discover_discoverQuery_tsx-app-c5fefe.6b4e433eb8c5d4dc154d.js (New) 17.01kB 17.01kB 100.0% 🚀
chunks/app_views_alerts_rules_metric_details_metricChart_tsx.*.js (New) 17.0kB 17.0kB 100.0% 🚀
chunks/app_components_feedback_widget_us*kWidget_tsx-app_components_gridEditable_sortLink_tsx-d372f4.984957a13accd16bfe2c.js (New) 16.21kB 16.21kB 100.0% 🚀
chunks/app_components_feedback_widget_us*kWidget_tsx-app_components_performance_transactionSe-f61270.456490ee92159d42e6a8.js (New) 13.36kB 13.36kB 100.0% 🚀
chunks/app_components_charts_lineChart_tsx-app_components_feedback_widget_us*kWidget_tsx-app_-26fc43.f48d8eafe0813fce1f08.js (New) 12.25kB 12.25kB 100.0% 🚀
chunks/app_actionCreators_prompts_tsx-app_components_feedback_widget_us*k_tsx-app_components_-5240c4.f1418a69b3f50321b046.js (New) 12.12kB 12.12kB 100.0% 🚀
chunks/vendors-node_modules_lodash_groupBy_js-node_modules_react-virtualized_dist_es_CellMeasurer_Ce-4677050.*.js 1 bytes 8.55kB 0.01%
chunks/vendors-node_modules_lodash_groupBy_js-node_modules_react-virtualized_dist_es_CellMeasurer_Ce-4677052.*.js (New) 8.55kB 8.55kB 100.0% 🚀
chunks/vendors-node_modules_lodash_groupBy_js-node_modules_react-virtualized_dist_es_CellMeasurer_Ce-4677051.*.js 1 bytes 8.55kB 0.01%
chunks/app_components_feedback_widget_us*kWidget_tsx-app_views_projectDetail_index_tsx.9c0cb998584e2e05d7c6.js (Deleted) -94.59kB 0 bytes -100.0% 🗑️
chunks/app_components_charts_lineChart_tsx-app_utils_discover_discoverQuery_tsx-app_views_alerts_rul-347a10.*.js (Deleted) -73.76kB 0 bytes -100.0% 🗑️
chunks/app_components_charts_eventsRequest_tsx-app_components_metrics_queryFieldGroup_tsx-app_compon-ae927e.*.js (Deleted) -71.95kB 0 bytes -100.0% 🗑️
chunks/app_components_breadcrumbs_tsx-app_components_feedback_widget_us*kWidget_tsx-app_utils-df50cf.012fa7f41cf556741124.js (Deleted) -57.12kB 0 bytes -100.0% 🗑️
chunks/app_components_charts_eventsRequest_tsx-app_components_feedback_widget_us*kWidget_tsx--64a49b.95602987729ef9c379eb.js (Deleted) -37.72kB 0 bytes -100.0% 🗑️
chunks/app_components_feedback_widget_us*kWidget_tsx-app_views_performance_transactionSummary-51d702.19a4b672433bab7becbc.js (Deleted) -37.17kB 0 bytes -100.0% 🗑️
chunks/app_components_feedback_widget_us*kWidget_tsx-app_views_insights_common_components_cha-d2aaf9.8ec051e7aab6961a22d0.js (Deleted) -31.93kB 0 bytes -100.0% 🗑️
chunks/app_components_feedback_widget_us*kWidget_tsx-app_components_performance_transactionSe-feae7d.28cdcf618df7927bc840.js (Deleted) -24.18kB 0 bytes -100.0% 🗑️
chunks/app_components_feedback_widget_us*kWidget_tsx-app_utils_discover_discoverQuery_tsx-app-c5fefe.8fb16f8f30e417123c2c.js (Deleted) -17.01kB 0 bytes -100.0% 🗑️
chunks/app_components_feedback_widget_us*kWidget_tsx-app_components_gridEditable_sortLink_tsx-d372f4.cb062de591f4b3c7234d.js (Deleted) -16.21kB 0 bytes -100.0% 🗑️
chunks/app_components_feedback_widget_us*kWidget_tsx-app_components_performance_transactionSe-f61270.e7259e3472df92f379f9.js (Deleted) -13.36kB 0 bytes -100.0% 🗑️
chunks/app_components_charts_lineChart_tsx-app_components_feedback_widget_us*kWidget_tsx-app_-26fc43.35efd5e99c6e69c782c2.js (Deleted) -12.25kB 0 bytes -100.0% 🗑️
chunks/app_actionCreators_prompts_tsx-app_components_feedback_widget_us*k_tsx-app_components_-5240c4.c1b827f03e7d918597ea.js (Deleted) -12.12kB 0 bytes -100.0% 🗑️
chunks/app_components_checkInTimeline_gridLines_tsx-app_components_checkInTimeline_utils_getConfigFr-321003.*.js (Deleted) -12.01kB 0 bytes -100.0% 🗑️
chunks/vendors-node_modules_lodash_groupBy_js-node_modules_react-virtualized_dist_es_CellMeasurer_Ce-e36efa.*.js (Deleted) -7.92kB 0 bytes -100.0% 🗑️
chunks/app_components_checkInTimeline_checkInTimeline_tsx.*.js (Deleted) -7.42kB 0 bytes -100.0% 🗑️

Files in chunks/app_actionCreators_discoverHomepageQueries_tsx-app_bootstrap_initializeApp_tsx-app_components-2ddc8c.*.js:

  • ./app/utils/fields/index.ts → Total Size: 70.66kB

Files in chunks/app_components_assigneeBadge_tsx-app_components_badge_featureBadge_tsx-app_components_charts_-eed9e1.*.js:

  • ./app/components/searchQueryBuilder/tokens/filterKeyListBox/keyDescription.tsx → Total Size: 35.78kB

  • ./app/actionCreators/tags.tsx → Total Size: 5.89kB

  • ./app/views/issueList/utils/getIssueTagValues.tsx → Total Size: 1.33kB

  • ./app/views/issueList/searchBar.tsx → Total Size: 4.73kB

Files in chunks/app_actionCreators_guides_tsx-app_actionCreators_preferences_tsx-app_components_avatar_actorA-95b65d.*.js:

  • ./app/utils/fields/index.ts → Total Size: 70.66kB

// Strip quotes for feature flags, which may be used to escape special characters in the search bar.
const charsToStrip = '"';
const key =
tag.kind === FieldKind.FEATURE_FLAG
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is questionable to me because tags could have colons too but its fine we're not breaking something. We could always extend this later.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good, @malwilley specifically requested this just to be safe, so the changes are FF only

Copy link
Member

@malwilley malwilley Feb 4, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I asked for this to be added because there's a risk that this new stripping logic might interfere with existing tags. Agree that the final solution should be generic

Copy link
Member

@malwilley malwilley left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good to merge!

If you want to pair on #83968 (comment) just lmk

@aliu39 aliu39 merged commit 8091099 into master Feb 6, 2025
41 checks passed
@aliu39 aliu39 deleted the aliu/ff-searchbar branch February 6, 2025 16:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Scope: Frontend Automatically applied to PRs that change frontend components
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants