Skip to content

Commit ba7c5b4

Browse files
authored
feat(shared-views): Add star toggle to view header. (#89500)
1 parent 93d0dbc commit ba7c5b4

File tree

3 files changed

+74
-27
lines changed

3 files changed

+74
-27
lines changed

static/app/views/issueList/issueViews/issueViewsList/issueViewsList.tsx

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,10 @@ import {
2020
makeFetchGroupSearchViewsKey,
2121
useFetchGroupSearchViews,
2222
} from 'sentry/views/issueList/queries/useFetchGroupSearchViews';
23-
import {makeFetchStarredGroupSearchViewsKey} from 'sentry/views/issueList/queries/useFetchStarredGroupSearchViews';
2423
import {
2524
type GroupSearchView,
2625
GroupSearchViewCreatedBy,
2726
GroupSearchViewSort,
28-
type StarredGroupSearchView,
2927
} from 'sentry/views/issueList/types';
3028

3129
type IssueViewSectionProps = {
@@ -80,33 +78,13 @@ function IssueViewSection({createdBy, limit, cursorQueryParam}: IssueViewSection
8078
view.id === variables.id ? {...view, starred: variables.starred} : view
8179
);
8280
});
83-
if (variables.starred) {
84-
setApiQueryData<StarredGroupSearchView[]>(
85-
queryClient,
86-
makeFetchStarredGroupSearchViewsKey({orgSlug: organization.slug}),
87-
data => [...(data ?? []), variables.view]
88-
);
89-
} else {
90-
setApiQueryData<StarredGroupSearchView[]>(
91-
queryClient,
92-
makeFetchStarredGroupSearchViewsKey({orgSlug: organization.slug}),
93-
data => data?.filter(view => view.id !== variables.id)
94-
);
95-
}
9681
},
9782
onError: (_error, variables) => {
9883
setApiQueryData<GroupSearchView[]>(queryClient, tableQueryKey, data => {
9984
return data?.map(view =>
10085
view.id === variables.id ? {...view, starred: !variables.starred} : view
10186
);
10287
});
103-
if (variables.starred) {
104-
setApiQueryData<StarredGroupSearchView[]>(
105-
queryClient,
106-
makeFetchStarredGroupSearchViewsKey({orgSlug: organization.slug}),
107-
data => data?.filter(view => view.id !== variables.id)
108-
);
109-
}
11088
},
11189
});
11290

static/app/views/issueList/leftNavViewsHeader.tsx

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,97 @@
1+
import {Fragment} from 'react';
12
import styled from '@emotion/styled';
23

4+
import {Button} from 'sentry/components/core/button';
35
import GlobalEventProcessingAlert from 'sentry/components/globalEventProcessingAlert';
46
import * as Layout from 'sentry/components/layouts/thirds';
7+
import {IconStar} from 'sentry/icons';
58
import {t} from 'sentry/locale';
69
import {space} from 'sentry/styles/space';
10+
import {setApiQueryData, useQueryClient} from 'sentry/utils/queryClient';
11+
import useOrganization from 'sentry/utils/useOrganization';
712
import useProjects from 'sentry/utils/useProjects';
813
import {useSelectedGroupSearchView} from 'sentry/views/issueList/issueViews/useSelectedGroupSeachView';
14+
import {useUpdateGroupSearchViewStarred} from 'sentry/views/issueList/mutations/useUpdateGroupSearchViewStarred';
15+
import {makeFetchGroupSearchViewKey} from 'sentry/views/issueList/queries/useFetchGroupSearchView';
16+
import type {GroupSearchView} from 'sentry/views/issueList/types';
917
import {usePrefersStackedNav} from 'sentry/views/nav/prefersStackedNav';
1018

1119
type LeftNavViewsHeaderProps = {
1220
selectedProjectIds: number[];
1321
};
1422

1523
function LeftNavViewsHeader({selectedProjectIds}: LeftNavViewsHeaderProps) {
24+
const organization = useOrganization();
1625
const {projects} = useProjects();
1726
const prefersStackedNav = usePrefersStackedNav();
27+
const queryClient = useQueryClient();
1828

1929
const selectedProjects = projects.filter(({id}) =>
2030
selectedProjectIds.includes(Number(id))
2131
);
2232

2333
const {data: groupSearchView} = useSelectedGroupSearchView();
34+
const {mutate: mutateViewStarred} = useUpdateGroupSearchViewStarred({
35+
onMutate: variables => {
36+
setApiQueryData<GroupSearchView>(
37+
queryClient,
38+
makeFetchGroupSearchViewKey({
39+
orgSlug: organization.slug,
40+
id: variables.id,
41+
}),
42+
oldGroupSearchView =>
43+
oldGroupSearchView
44+
? {...oldGroupSearchView, starred: variables.starred}
45+
: oldGroupSearchView
46+
);
47+
},
48+
onError: (_error, variables) => {
49+
setApiQueryData<GroupSearchView>(
50+
queryClient,
51+
makeFetchGroupSearchViewKey({
52+
orgSlug: organization.slug,
53+
id: variables.id,
54+
}),
55+
oldGroupSearchView =>
56+
oldGroupSearchView
57+
? {...oldGroupSearchView, starred: !variables.starred}
58+
: oldGroupSearchView
59+
);
60+
},
61+
});
2462

2563
return (
2664
<Layout.Header noActionWrap unified={prefersStackedNav}>
2765
<Layout.HeaderContent unified={prefersStackedNav}>
28-
<Layout.Title>{groupSearchView?.name ?? t('Issues')}</Layout.Title>
66+
<StyledLayoutTitle>
67+
{groupSearchView ? (
68+
<Fragment>
69+
{groupSearchView.name}
70+
{organization.features.includes('issue-view-sharing') ? (
71+
<Button
72+
onClick={() => {
73+
mutateViewStarred({
74+
id: groupSearchView.id,
75+
starred: !groupSearchView?.starred,
76+
view: groupSearchView,
77+
});
78+
}}
79+
aria-label={
80+
groupSearchView?.starred ? t('Unstar view') : t('Star view')
81+
}
82+
icon={
83+
<IconStar
84+
isSolid={groupSearchView?.starred}
85+
color={groupSearchView?.starred ? 'yellow300' : 'subText'}
86+
/>
87+
}
88+
/>
89+
) : null}
90+
</Fragment>
91+
) : (
92+
t('Issues')
93+
)}
94+
</StyledLayoutTitle>
2995
</Layout.HeaderContent>
3096
<Layout.HeaderActions />
3197
<StyledGlobalEventProcessingAlert projects={selectedProjects} />
@@ -45,3 +111,8 @@ const StyledGlobalEventProcessingAlert = styled(GlobalEventProcessingAlert)`
45111
margin-bottom: 0;
46112
}
47113
`;
114+
115+
const StyledLayoutTitle = styled(Layout.Title)`
116+
display: flex;
117+
justify-content: space-between;
118+
`;

static/app/views/nav/secondary/sections/issues/issueViews/issueViewNavItemContent.tsx

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -146,10 +146,8 @@ export function IssueViewNavItemContent({
146146
e.preventDefault();
147147
}}
148148
onClick={e => {
149-
if (isDragging) {
150-
e.stopPropagation();
151-
e.preventDefault();
152-
}
149+
e.stopPropagation();
150+
e.preventDefault();
153151
}}
154152
>
155153
<StyledInteractionStateLayer isPressed={isDragging === view.id} />

0 commit comments

Comments
 (0)