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

Add a Share View button that persists the original view's name #78665

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 5 additions & 0 deletions static/app/utils/analytics/issueAnalyticsEvents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,10 @@ export type IssueEventParameters = {
'issue_views.renamed_view': {};
'issue_views.reordered_views': {};
'issue_views.saved_changes': {};
'issue_views.shared_view': {
query: string;
viewName?: string;
};
'issue_views.shared_view_opened': {
query: string;
};
Expand Down Expand Up @@ -381,6 +385,7 @@ export const issueEventMap: Record<IssueEventKey, string | null> = {
'issue_views.discarded_changes': 'Issue Views: Discarded Changes',
'issue_views.renamed_view': 'Issue Views: Renamed View',
'issue_views.duplicated_view': 'Issue Views: Duplicated View',
'issue_views.shared_view': 'Issue Views: Shared View',
'issue_views.deleted_view': 'Issue Views: Deleted View',
'issue_views.reordered_views': 'Issue Views: Views Reordered',
'issue_views.add_view.clicked': 'Issue Views: Add View Clicked',
Expand Down
4 changes: 2 additions & 2 deletions static/app/views/issueList/customViewsHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ function CustomViewsIssueListHeaderTabsContent({
const pageFilters = usePageFilters();

// TODO(msun): Use the location from useLocation instead of props router in the future
const {cursor: _cursor, page: _page, ...queryParams} = router?.location.query;
const {cursor: _cursor, page: _page, viewName, ...queryParams} = router?.location.query;

const {query, sort, viewId, project, environment} = queryParams;

Expand Down Expand Up @@ -179,7 +179,7 @@ function CustomViewsIssueListHeaderTabsContent({
? {
id: TEMPORARY_TAB_KEY,
key: TEMPORARY_TAB_KEY,
label: t('Unsaved'),
label: viewName ?? t('Unsaved'),
query: query,
querySort: sort ?? IssueSortOptions.DATE,
isCommitted: true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import type {InjectedRouter} from 'sentry/types/legacyReactRouter';
import {defined} from 'sentry/utils';
import {trackAnalytics} from 'sentry/utils/analytics';
import normalizeUrl from 'sentry/utils/url/normalizeUrl';
import useCopyToClipboard from 'sentry/utils/useCopyToClipboard';
import {useLocation} from 'sentry/utils/useLocation';
import {useNavigate} from 'sentry/utils/useNavigate';
import useOrganization from 'sentry/utils/useOrganization';
Expand Down Expand Up @@ -120,12 +121,27 @@ export function DraggableTabBar({
const organization = useOrganization();
const navigate = useNavigate();
const location = useLocation();
const {tabListState} = useContext(TabsContext);
const {setNewViewActive, setOnNewViewsSaved} = useContext(NewTabContext);

const {cursor: _cursor, page: _page, ...queryParams} = router?.location?.query ?? {};
const {viewId} = queryParams;

const {tabListState} = useContext(TabsContext);
const {setNewViewActive, setOnNewViewsSaved} = useContext(NewTabContext);
const constructSharedViewUrl = () => {
const currentUrl = new URL(window.location.href);
currentUrl.searchParams.delete('cursor');
currentUrl.searchParams.delete('page');
currentUrl.searchParams.delete('viewId');
if (tabListState?.selectedItem?.textValue) {
currentUrl.searchParams.append('viewName', tabListState?.selectedItem?.textValue);
}
return currentUrl.href;
};

const {onClick: onCopyViewLink} = useCopyToClipboard({
text: constructSharedViewUrl(),
successMessage: t('Copied link to clipboard'),
});

const handleOnReorder = (newOrder: Node<DraggableTabListItemProps>[]) => {
const newTabs: Tab[] = newOrder
Expand Down Expand Up @@ -202,6 +218,15 @@ export function DraggableTabBar({
}
};

const handleOnShareView = () => {
onCopyViewLink();
trackAnalytics('issue_views.shared_view', {
organization,
query: queryParams.query,
viewName: tabListState?.selectedItem?.textValue,
});
};

const handleOnDuplicate = () => {
const idx = tabs.findIndex(tb => tb.key === tabListState?.selectedKey);
if (idx !== -1) {
Expand Down Expand Up @@ -252,7 +277,7 @@ export function DraggableTabBar({
const newTab: Tab = {
id: tempId,
key: tempId,
label: 'New View',
label: tempTab.label === t('Unsaved') ? 'New View' : tempTab.label,
query: tempTab.query,
querySort: tempTab.querySort,
isCommitted: true,
Expand All @@ -264,7 +289,7 @@ export function DraggableTabBar({
query: {
...queryParams,
query: tempTab.query,
querySort: tempTab.querySort,
sort: tempTab.querySort,
viewId: tempId,
},
},
Expand Down Expand Up @@ -398,6 +423,7 @@ export function DraggableTabBar({
return makeUnsavedChangesMenuOptions({
onRename: () => setEditingTabKey(tab.key),
onDuplicate: handleOnDuplicate,
onShareView: handleOnShareView,
onDelete: tabs.length > 1 ? handleOnDelete : undefined,
onSave: handleOnSaveChanges,
onDiscard: handleOnDiscardChanges,
Expand All @@ -406,6 +432,7 @@ export function DraggableTabBar({
return makeDefaultMenuOptions({
onRename: () => setEditingTabKey(tab.key),
onDuplicate: handleOnDuplicate,
onShareView: handleOnShareView,
onDelete: tabs.length > 1 ? handleOnDelete : undefined,
});
};
Expand Down Expand Up @@ -474,11 +501,13 @@ export function DraggableTabBar({
const makeDefaultMenuOptions = ({
onRename,
onDuplicate,
onShareView,
onDelete,
}: {
onDuplicate: () => void;
onRename: () => void;
onShareView: () => void;
onDelete?: () => void;
onDuplicate?: () => void;
onRename?: () => void;
}): MenuItemProps[] => {
const menuOptions: MenuItemProps[] = [
{
Expand All @@ -491,6 +520,11 @@ const makeDefaultMenuOptions = ({
label: t('Duplicate'),
onAction: onDuplicate,
},
{
key: 'share-tab',
label: t('Share View'),
onAction: onShareView,
},
];
if (onDelete) {
menuOptions.push({
Expand All @@ -506,15 +540,17 @@ const makeDefaultMenuOptions = ({
const makeUnsavedChangesMenuOptions = ({
onRename,
onDuplicate,
onShareView,
onDelete,
onSave,
onDiscard,
}: {
onDiscard: () => void;
onDuplicate: () => void;
onRename: () => void;
onSave: () => void;
onShareView: () => void;
onDelete?: () => void;
onDiscard?: () => void;
onDuplicate?: () => void;
onRename?: () => void;
onSave?: () => void;
}): MenuItemProps[] => {
return [
{
Expand All @@ -535,7 +571,7 @@ const makeUnsavedChangesMenuOptions = ({
},
{
key: 'default',
children: makeDefaultMenuOptions({onRename, onDuplicate, onDelete}),
children: makeDefaultMenuOptions({onRename, onDuplicate, onShareView, onDelete}),
},
];
};
Expand Down
Loading