Skip to content

feat(feedback): frontend to display summary #93567

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

Open
wants to merge 60 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
60 commits
Select commit Hold shift + click to select a range
1af771f
feedback usecase to generate summary and parse it, and testing it
vishnupsatish Jun 5, 2025
a15f6f7
update tests and some config
vishnupsatish Jun 5, 2025
9ba5ee5
update based on review - rename, strip consecutive whitespaces, etc.
vishnupsatish Jun 5, 2025
3b80ac2
add max tokens and add comment back
vishnupsatish Jun 5, 2025
937f1bf
create endpoint, very rough and no tests
vishnupsatish Jun 5, 2025
860cdb1
create test file using cursor, need to change so it actually works an…
vishnupsatish Jun 6, 2025
376de16
trying out tests and creating user feedbacks using kafka
vishnupsatish Jun 6, 2025
019c174
write endpoint test that actually works
vishnupsatish Jun 9, 2025
0a3360f
more tests for the API endpoint
vishnupsatish Jun 9, 2025
aba030a
format
vishnupsatish Jun 9, 2025
1956230
fix docstring for endpoint
vishnupsatish Jun 9, 2025
b16637f
update comments
vishnupsatish Jun 9, 2025
b34742f
remove custom exception for parse, fix failing test
vishnupsatish Jun 9, 2025
7368e0f
format tests
vishnupsatish Jun 9, 2025
c20e77a
remove default=True for user-feedback-ui
vishnupsatish Jun 9, 2025
4a1b805
Merge branch 'master' into vishnupsatish/uf-summary-api-endpoint
vishnupsatish Jun 9, 2025
5da9100
update based on review
vishnupsatish Jun 9, 2025
a22d4c6
log more stuff
vishnupsatish Jun 9, 2025
7493363
cache summary and write tests for the caching aspect
vishnupsatish Jun 10, 2025
55bfad7
update based on review
vishnupsatish Jun 10, 2025
6a9430d
update url
vishnupsatish Jun 10, 2025
faf5701
gate behind feature flag
vishnupsatish Jun 10, 2025
40dd6cc
test for nonexistent feature flag, test for different project qparam …
vishnupsatish Jun 10, 2025
d497108
Merge branch 'vishnupsatish/uf-summary-api-endpoint' into vishnupsati…
vishnupsatish Jun 10, 2025
c6e3051
merge master, why is a test_create_feedback test failing?
vishnupsatish Jun 10, 2025
d630eef
use monkeypatch instead of patch, but it is still not cleaning up pro…
vishnupsatish Jun 10, 2025
5cda5e8
revert to how it was before as monkeypatch isnt fixing the issue
vishnupsatish Jun 10, 2025
43ce9a4
update based on review, mock generate_summary instead of openai
vishnupsatish Jun 11, 2025
a451cef
Merge branch 'vishnupsatish/uf-summary-api-endpoint' into vishnupsati…
vishnupsatish Jun 11, 2025
72cb051
update cache tests
vishnupsatish Jun 11, 2025
fa40586
fix type so that it is string
vishnupsatish Jun 11, 2025
b3a5395
cnt
vishnupsatish Jun 11, 2025
ee740d1
update url
vishnupsatish Jun 11, 2025
571004b
Merge branch 'vishnupsatish/uf-summary-api-endpoint' into vishnupsati…
vishnupsatish Jun 11, 2025
6cd136f
merge
vishnupsatish Jun 11, 2025
e378da1
barebones frontend
vishnupsatish Jun 11, 2025
3b03f7d
merge master
vishnupsatish Jun 12, 2025
5e2648e
fix frontend bugs and run query
vishnupsatish Jun 13, 2025
2c525a4
hide it behind feature flag
vishnupsatish Jun 13, 2025
f0fe0dc
make summary fit in the correct spot based on the grid
vishnupsatish Jun 13, 2025
2407346
add icon
vishnupsatish Jun 13, 2025
04b5f2c
make the summary not part of the grid anymore, update error, loading,…
vishnupsatish Jun 13, 2025
e383dd0
formatting and some other small fixes
vishnupsatish Jun 16, 2025
03c7aa2
more refactors
vishnupsatish Jun 16, 2025
f3df413
line clamping logic, cursor helped
vishnupsatish Jun 16, 2025
2783134
gate behind feature flag
vishnupsatish Jun 16, 2025
88e5262
clean up code
vishnupsatish Jun 16, 2025
a0ed6c3
removed the line clamp logic, nice to have so we can worry about it l…
vishnupsatish Jun 16, 2025
3645bbc
revert endpoint changes
vishnupsatish Jun 16, 2025
59c98db
revert feature flags
vishnupsatish Jun 16, 2025
bd44743
not enough feedbacks, ensure success is false too
vishnupsatish Jun 16, 2025
5062dfe
update based on review
vishnupsatish Jun 16, 2025
ece7000
num_feedbacks_used -> numFeedbacksUsed in the frontend too
vishnupsatish Jun 16, 2025
5827c79
Merge remote-tracking branch 'origin/master' into vishnupsatish/uf-su…
vishnupsatish Jun 17, 2025
e1e7f99
change the way date and time are sent to the backend, still draft-ish
vishnupsatish Jun 17, 2025
4a81d56
update based on review
vishnupsatish Jun 17, 2025
d6fdea2
reset feature flags
vishnupsatish Jun 17, 2025
607e8da
update based on reviews
vishnupsatish Jun 18, 2025
8232c5d
Merge remote-tracking branch 'origin/master' into vishnupsatish/uf-su…
vishnupsatish Jun 18, 2025
dc83c6d
nit
vishnupsatish Jun 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 64 additions & 0 deletions static/app/components/feedback/feedbackSummary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import styled from '@emotion/styled';

import useFeedbackSummary from 'sentry/components/feedback/list/useFeedbackSummary';
import Placeholder from 'sentry/components/placeholder';
import {IconSeer} from 'sentry/icons/iconSeer';
import {t} from 'sentry/locale';
import {space} from 'sentry/styles/space';
import useOrganization from 'sentry/utils/useOrganization';

export default function FeedbackSummary() {
const {isError, isPending, summary, tooFewFeedbacks} = useFeedbackSummary();

const organization = useOrganization();

if (
!organization.features.includes('user-feedback-ai-summaries') ||
tooFewFeedbacks ||
isError
) {
return null;
}

if (isPending) {
return <Placeholder height="100px" />;
}

return (
<SummaryIconContainer>
<IconSeer size="xs" />
<SummaryContainer>
<SummaryHeader>{t('Feedback Summary')}</SummaryHeader>
<SummaryContent>{summary}</SummaryContent>
</SummaryContainer>
</SummaryIconContainer>
);
}

const SummaryContainer = styled('div')`
display: flex;
flex-direction: column;
gap: ${space(1)};
width: 100%;
`;

const SummaryHeader = styled('p')`
font-size: ${p => p.theme.fontSizeMedium};
font-weight: ${p => p.theme.fontWeightBold};
margin: 0;
`;

const SummaryContent = styled('p')`
font-size: ${p => p.theme.fontSizeSmall};
color: ${p => p.theme.subText};
margin: 0;
`;

const SummaryIconContainer = styled('div')`
display: flex;
gap: ${space(1)};
padding: ${space(2)};
border: 1px solid ${p => p.theme.border};
border-radius: ${p => p.theme.borderRadius};
align-items: baseline;
`;
67 changes: 67 additions & 0 deletions static/app/components/feedback/list/useFeedbackSummary.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import {normalizeDateTimeParams} from 'sentry/components/organizations/pageFilters/parse';
import {useApiQuery} from 'sentry/utils/queryClient';
import useOrganization from 'sentry/utils/useOrganization';
import usePageFilters from 'sentry/utils/usePageFilters';

type FeedbackSummaryResponse = {
numFeedbacksUsed: number;
success: boolean;
summary: string | null;
};

export default function useFeedbackSummary(): {
isError: boolean;
isPending: boolean;
summary: string | null;
tooFewFeedbacks: boolean;
} {
const organization = useOrganization();

const {selection} = usePageFilters();

const normalizedDateRange = normalizeDateTimeParams(selection.datetime);
Comment on lines +20 to +22
Copy link
Member Author

Choose a reason for hiding this comment

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

I've updated the way the date range filtering is done and from my testing (and looking at the code) this seems to work. Can you please have a look @ryan953 @michellewzhang?

Copy link
Member

Choose a reason for hiding this comment

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

woo, fewer weird things going on!


const {data, isPending, isError} = useApiQuery<FeedbackSummaryResponse>(
[
`/organizations/${organization.slug}/feedback-summary/`,
{
query: {
...normalizedDateRange,
project: selection.projects,
},
},
],
{
staleTime: 5000,
enabled:
Boolean(normalizedDateRange) &&
organization.features.includes('user-feedback-ai-summaries'),
retry: 1,
}
);

if (isPending) {
return {
summary: null,
isPending: true,
isError: false,
tooFewFeedbacks: false,
};
}

if (isError) {
return {
summary: null,
isPending: false,
isError: true,
tooFewFeedbacks: false,
};
}

return {
summary: data.summary,
isPending: false,
isError: false,
tooFewFeedbacks: data.numFeedbacksUsed === 0 && !data.success,
};
}
18 changes: 14 additions & 4 deletions static/app/views/feedback/feedbackListPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import FeedbackItemLoader from 'sentry/components/feedback/feedbackItem/feedback
import FeedbackWidgetBanner from 'sentry/components/feedback/feedbackOnboarding/feedbackWidgetBanner';
import FeedbackSearch from 'sentry/components/feedback/feedbackSearch';
import FeedbackSetupPanel from 'sentry/components/feedback/feedbackSetupPanel';
import FeedbackSummary from 'sentry/components/feedback/feedbackSummary';
import FeedbackWhatsNewBanner from 'sentry/components/feedback/feedbackWhatsNewBanner';
import FeedbackList from 'sentry/components/feedback/list/feedbackList';
import useCurrentFeedbackId from 'sentry/components/feedback/useCurrentFeedbackId';
Expand Down Expand Up @@ -84,9 +85,12 @@ export default function FeedbackListPage() {
<FeedbackFilters style={{gridArea: 'filters'}} />
{hasSetupOneFeedback || hasSlug ? (
<Fragment>
<Container style={{gridArea: 'list'}}>
<FeedbackList />
</Container>
<SummaryListContainer style={{gridArea: 'list'}}>
<FeedbackSummary />
<Container>
<FeedbackList />
</Container>
</SummaryListContainer>
<SearchContainer>
<FeedbackSearch />
</SearchContainer>
Expand Down Expand Up @@ -118,6 +122,12 @@ const Background = styled('div')`
gap: ${space(2)};
`;

const SummaryListContainer = styled('div')`
display: flex;
flex-direction: column;
gap: ${space(1)};
`;

const LayoutGrid = styled('div')`
overflow: hidden;
flex-grow: 1;
Expand Down Expand Up @@ -153,7 +163,7 @@ const LayoutGrid = styled('div')`
}

@media (min-width: ${p => p.theme.breakpoints.medium}) {
grid-template-columns: minmax(1fr, 195px) 1fr;
grid-template-columns: minmax(195px, 1fr) 1.5fr;
}

@media (min-width: ${p => p.theme.breakpoints.large}) {
Expand Down
Loading