import {Fragment, useState} from 'react'; import {css, useTheme} from '@emotion/react'; import styled from '@emotion/styled'; import orderBy from 'lodash/orderBy'; import {openModal} from 'sentry/actionCreators/modal'; import {Button, ButtonLabel} from 'sentry/components/button'; import {openConfirmModal} from 'sentry/components/confirm'; import {DropdownMenu, MenuItemProps} from 'sentry/components/dropdownMenu'; import LoadingError from 'sentry/components/loadingError'; import LoadingIndicator from 'sentry/components/loadingIndicator'; import {CreateSavedSearchModal} from 'sentry/components/modals/savedSearchModal/createSavedSearchModal'; import {EditSavedSearchModal} from 'sentry/components/modals/savedSearchModal/editSavedSearchModal'; import {IconAdd, IconEllipsis} from 'sentry/icons'; import {t} from 'sentry/locale'; import {space} from 'sentry/styles/space'; import {Organization, SavedSearch, SavedSearchVisibility} from 'sentry/types'; import trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAnalyticsEvent'; import useMedia from 'sentry/utils/useMedia'; import {useSyncedLocalStorageState} from 'sentry/utils/useSyncedLocalStorageState'; import {useDeleteSavedSearchOptimistic} from 'sentry/views/issueList/mutations/useDeleteSavedSearch'; import {useFetchSavedSearchesForOrg} from 'sentry/views/issueList/queries/useFetchSavedSearchesForOrg'; import {SAVED_SEARCHES_SIDEBAR_OPEN_LOCALSTORAGE_KEY} from 'sentry/views/issueList/utils'; interface SavedIssueSearchesProps { onSavedSearchSelect: (savedSearch: SavedSearch) => void; organization: Organization; query: string; sort: string; } interface SavedSearchItemProps extends Pick { savedSearch: SavedSearch; } type CreateNewSavedSearchButtonProps = Pick< SavedIssueSearchesProps, 'query' | 'sort' | 'organization' >; const MAX_SHOWN_SEARCHES = 4; const SavedSearchItemDescription = ({ savedSearch, }: Pick) => { if (savedSearch.isGlobal) { return {savedSearch.query}; } return ( {savedSearch.visibility === SavedSearchVisibility.Organization ? t('Anyone in organization can see but not edit') : t('Only you can see and edit')} ); }; const SavedSearchItem = ({ organization, onSavedSearchSelect, savedSearch, }: SavedSearchItemProps) => { const {mutate: deleteSavedSearch} = useDeleteSavedSearchOptimistic(); const hasOrgWriteAccess = organization.access?.includes('org:write'); const canEdit = savedSearch.visibility === SavedSearchVisibility.Owner || hasOrgWriteAccess; const actions: MenuItemProps[] = [ { key: 'edit', label: 'Edit', disabled: !canEdit, details: !canEdit ? t('You do not have permission to edit this search.') : undefined, onAction: () => { openModal(deps => ( )); }, }, { disabled: !canEdit, details: !canEdit ? t('You do not have permission to delete this search.') : undefined, key: 'delete', label: t('Delete'), onAction: () => { openConfirmModal({ message: t('Are you sure you want to delete this saved search?'), onConfirm: () => deleteSavedSearch({orgSlug: organization.slug, id: savedSearch.id}), }); }, priority: 'danger', }, ]; return ( onSavedSearchSelect(savedSearch)} borderless > {savedSearch.name} {!savedSearch.isGlobal && ( (