123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144 |
- import {Component, Fragment} from 'react';
- import {Link} from 'react-router';
- import {css} from '@emotion/react';
- import styled from '@emotion/styled';
- import {ModalRenderProps} from 'sentry/actionCreators/modal';
- import {Client} from 'sentry/api';
- import Button from 'sentry/components/button';
- import Input from 'sentry/components/forms/controls/input';
- import {IconChevron, IconSearch} from 'sentry/icons';
- import {t} from 'sentry/locale';
- import space from 'sentry/styles/space';
- import {Organization, PageFilters} from 'sentry/types';
- import trackAdvancedAnalyticsEvent from 'sentry/utils/analytics/trackAdvancedAnalyticsEvent';
- import withApi from 'sentry/utils/withApi';
- import withPageFilters from 'sentry/utils/withPageFilters';
- import {Widget} from 'sentry/views/dashboardsV2/types';
- import {getWidgetDiscoverUrl} from 'sentry/views/dashboardsV2/utils';
- export type DashboardWidgetQuerySelectorModalOptions = {
- organization: Organization;
- widget: Widget;
- isMetricsData?: boolean;
- };
- type Props = ModalRenderProps &
- DashboardWidgetQuerySelectorModalOptions & {
- api: Client;
- organization: Organization;
- selection: PageFilters;
- };
- class DashboardWidgetQuerySelectorModal extends Component<Props> {
- renderQueries() {
- const {organization, widget, selection, isMetricsData} = this.props;
- const querySearchBars = widget.queries.map((query, index) => {
- const discoverLocation = getWidgetDiscoverUrl(
- {
- ...widget,
- queries: [query],
- },
- selection,
- organization,
- 0,
- isMetricsData
- );
- return (
- <Fragment key={index}>
- <QueryContainer>
- <Container>
- <SearchLabel htmlFor="smart-search-input" aria-label={t('Search events')}>
- <IconSearch />
- </SearchLabel>
- <StyledInput value={query.conditions} disabled />
- </Container>
- <Link to={discoverLocation}>
- <OpenInDiscoverButton
- priority="primary"
- icon={<IconChevron size="xs" direction="right" />}
- onClick={() => {
- trackAdvancedAnalyticsEvent(
- 'dashboards_views.query_selector.selected',
- {
- organization,
- widget_type: widget.displayType,
- }
- );
- }}
- aria-label={t('Open in Discover')}
- />
- </Link>
- </QueryContainer>
- </Fragment>
- );
- });
- return querySearchBars;
- }
- render() {
- const {Body, Header, widget} = this.props;
- return (
- <Fragment>
- <Header closeButton>
- <h4>{widget.title}</h4>
- </Header>
- <Body>
- <p>
- {t(
- 'Multiple queries were used to create this widget visualization. Which query would you like to view in Discover?'
- )}
- </p>
- {this.renderQueries()}
- </Body>
- </Fragment>
- );
- }
- }
- const StyledInput = styled(Input)`
- text-overflow: ellipsis;
- padding: 0px;
- box-shadow: none;
- height: auto;
- &:disabled {
- border: none;
- cursor: default;
- }
- `;
- const QueryContainer = styled('div')`
- display: flex;
- margin-bottom: ${space(1)};
- `;
- const OpenInDiscoverButton = styled(Button)`
- margin-left: ${space(1)};
- `;
- const Container = styled('div')`
- border: 1px solid ${p => p.theme.border};
- box-shadow: inset ${p => p.theme.dropShadowLight};
- background: ${p => p.theme.backgroundSecondary};
- padding: 7px ${space(1)};
- position: relative;
- display: grid;
- grid-template-columns: max-content 1fr max-content;
- gap: ${space(1)};
- align-items: start;
- flex-grow: 1;
- border-radius: ${p => p.theme.borderRadius};
- `;
- const SearchLabel = styled('label')`
- display: flex;
- padding: ${space(0.5)} 0;
- margin: 0;
- color: ${p => p.theme.gray300};
- `;
- export const modalCss = css`
- width: 100%;
- max-width: 700px;
- margin: 70px auto;
- `;
- export default withApi(withPageFilters(DashboardWidgetQuerySelectorModal));
|