Browse Source

ref(ui): Replace releaseDetailsRequest with SessionsRequest (#29252)

Matej Minar 3 years ago
parent
commit
716dd7a776

+ 15 - 9
static/app/components/charts/sessionsRequest.tsx

@@ -5,8 +5,8 @@ import omitBy from 'lodash/omitBy';
 import {addErrorMessage} from 'app/actionCreators/indicator';
 import {addErrorMessage} from 'app/actionCreators/indicator';
 import {Client} from 'app/api';
 import {Client} from 'app/api';
 import {t} from 'app/locale';
 import {t} from 'app/locale';
-import {DateString, Organization, SessionApiResponse, SessionField} from 'app/types';
-import {getSessionsInterval} from 'app/utils/sessions';
+import {Organization, SessionApiResponse, SessionField} from 'app/types';
+import {filterSessionsInTimeWindow, getSessionsInterval} from 'app/utils/sessions';
 
 
 const propNamesToIgnore = ['api', 'children', 'organization'];
 const propNamesToIgnore = ['api', 'children', 'organization'];
 const omitIgnoredProps = (props: Props) =>
 const omitIgnoredProps = (props: Props) =>
@@ -27,12 +27,13 @@ type Props = {
   project?: number[];
   project?: number[];
   environment?: string[];
   environment?: string[];
   statsPeriod?: string;
   statsPeriod?: string;
-  start?: DateString;
-  end?: DateString;
+  start?: string;
+  end?: string;
   query?: string;
   query?: string;
   groupBy?: string[];
   groupBy?: string[];
   interval?: string;
   interval?: string;
-  disabled?: boolean;
+  isDisabled?: boolean;
+  shouldFilterSessionsInTimeWindow?: boolean;
 };
 };
 
 
 type State = {
 type State = {
@@ -99,13 +100,12 @@ class SessionsRequest extends React.Component<Props, State> {
   }
   }
 
 
   fetchData = async () => {
   fetchData = async () => {
-    const {api, disabled} = this.props;
+    const {api, isDisabled, shouldFilterSessionsInTimeWindow} = this.props;
 
 
-    if (disabled) {
+    if (isDisabled) {
       return;
       return;
     }
     }
 
 
-    api.clear();
     this.setState(state => ({
     this.setState(state => ({
       reloading: state.response !== null,
       reloading: state.response !== null,
       errored: false,
       errored: false,
@@ -118,7 +118,13 @@ class SessionsRequest extends React.Component<Props, State> {
 
 
       this.setState({
       this.setState({
         reloading: false,
         reloading: false,
-        response,
+        response: shouldFilterSessionsInTimeWindow
+          ? filterSessionsInTimeWindow(
+              response,
+              this.baseQueryParams.start,
+              this.baseQueryParams.end
+            )
+          : response,
       });
       });
     } catch (error) {
     } catch (error) {
       addErrorMessage(error.responseJSON?.detail ?? t('Error loading health data'));
       addErrorMessage(error.responseJSON?.detail ?? t('Error loading health data'));

+ 184 - 150
static/app/views/releases/detail/overview/index.tsx

@@ -7,6 +7,7 @@ import moment from 'moment';
 import {restoreRelease} from 'app/actionCreators/release';
 import {restoreRelease} from 'app/actionCreators/release';
 import {Client} from 'app/api';
 import {Client} from 'app/api';
 import Feature from 'app/components/acl/feature';
 import Feature from 'app/components/acl/feature';
+import SessionsRequest from 'app/components/charts/sessionsRequest';
 import {DateTimeObject} from 'app/components/charts/utils';
 import {DateTimeObject} from 'app/components/charts/utils';
 import DateTime from 'app/components/dateTime';
 import DateTime from 'app/components/dateTime';
 import PerformanceCardTable from 'app/components/discover/performanceCardTable';
 import PerformanceCardTable from 'app/components/discover/performanceCardTable';
@@ -18,7 +19,13 @@ import PageTimeRangeSelector from 'app/components/pageTimeRangeSelector';
 import {DEFAULT_RELATIVE_PERIODS} from 'app/constants';
 import {DEFAULT_RELATIVE_PERIODS} from 'app/constants';
 import {t} from 'app/locale';
 import {t} from 'app/locale';
 import space from 'app/styles/space';
 import space from 'app/styles/space';
-import {GlobalSelection, NewQuery, Organization, ReleaseProject} from 'app/types';
+import {
+  GlobalSelection,
+  NewQuery,
+  Organization,
+  ReleaseProject,
+  SessionField,
+} from 'app/types';
 import {getUtcDateString} from 'app/utils/dates';
 import {getUtcDateString} from 'app/utils/dates';
 import {TableDataRow} from 'app/utils/discover/discoverQuery';
 import {TableDataRow} from 'app/utils/discover/discoverQuery';
 import EventView from 'app/utils/discover/eventView';
 import EventView from 'app/utils/discover/eventView';
@@ -44,7 +51,6 @@ import ProjectReleaseDetails from './projectReleaseDetails';
 import ReleaseAdoption from './releaseAdoption';
 import ReleaseAdoption from './releaseAdoption';
 import ReleaseArchivedNotice from './releaseArchivedNotice';
 import ReleaseArchivedNotice from './releaseArchivedNotice';
 import ReleaseComparisonChart from './releaseComparisonChart';
 import ReleaseComparisonChart from './releaseComparisonChart';
-import ReleaseDetailsRequest from './releaseDetailsRequest';
 import ReleaseStats from './releaseStats';
 import ReleaseStats from './releaseStats';
 import TotalCrashFreeUsers from './totalCrashFreeUsers';
 import TotalCrashFreeUsers from './totalCrashFreeUsers';
 
 
@@ -290,156 +296,184 @@ class ReleaseOverview extends AsyncView<Props> {
             ),
             ),
           };
           };
 
 
+          const sessionsRequestProps: Omit<SessionsRequest['props'], 'children'> = {
+            api,
+            organization,
+            field: [SessionField.USERS, SessionField.SESSIONS, SessionField.DURATION],
+            groupBy: ['session.status'],
+            ...getReleaseParams({location, releaseBounds}),
+            shouldFilterSessionsInTimeWindow: true,
+          };
+
           return (
           return (
-            <ReleaseDetailsRequest
-              organization={organization}
-              location={location}
-              version={version}
-              releaseBounds={releaseBounds}
-            >
-              {({thisRelease, allReleases, loading, reloading, errored}) => (
-                <Body>
-                  <Main>
-                    {isReleaseArchived(release) && (
-                      <ReleaseArchivedNotice
-                        onRestore={() => this.handleRestore(project, refetchData)}
-                      />
-                    )}
-
-                    <StyledPageTimeRangeSelector
-                      organization={organization}
-                      relative={period ?? ''}
-                      start={start ?? null}
-                      end={end ?? null}
-                      utc={utc ?? null}
-                      onUpdate={this.handleDateChange}
-                      relativeOptions={{
-                        [RELEASE_PERIOD_KEY]: (
-                          <Fragment>
-                            {t('Entire Release Period')} (
-                            <DateTime
-                              date={releaseBounds.releaseStart}
-                              timeAndDate
-                            /> - <DateTime date={releaseBounds.releaseEnd} timeAndDate />)
-                          </Fragment>
-                        ),
-                        ...DEFAULT_RELATIVE_PERIODS,
-                      }}
-                      defaultPeriod={RELEASE_PERIOD_KEY}
-                    />
-
-                    {(hasDiscover || hasPerformance || hasHealthData) && (
-                      <ReleaseComparisonChart
-                        release={release}
-                        releaseSessions={thisRelease}
-                        allSessions={allReleases}
-                        platform={project.platform}
-                        location={location}
-                        loading={loading}
-                        reloading={reloading}
-                        errored={errored}
-                        project={project}
-                        organization={organization}
-                        api={api}
-                        hasHealthData={hasHealthData}
-                      />
-                    )}
-
-                    <Issues
-                      organization={organization}
-                      selection={selection}
-                      version={version}
-                      location={location}
-                      releaseBounds={releaseBounds}
-                      queryFilterDescription={t('In this release')}
-                      withChart
-                    />
-
-                    <Feature features={['performance-view']}>
-                      {hasReleaseComparisonPerformance ? (
-                        <PerformanceCardTable
-                          organization={organization}
-                          project={project}
-                          isLoading={loading}
-                          // TODO(kelly): hardcoding this until I have data
-                          isEmpty={false}
-                        />
-                      ) : (
-                        <TransactionsList
-                          location={location}
-                          organization={organization}
-                          eventView={releaseEventView}
-                          trendView={releaseTrendView}
-                          selected={selectedSort}
-                          options={sortOptions}
-                          handleDropdownChange={this.handleTransactionsListSortChange}
-                          titles={titles}
-                          generateLink={generateLink}
-                        />
-                      )}
-                    </Feature>
-                  </Main>
-                  <Side>
-                    <ReleaseStats
-                      organization={organization}
-                      release={release}
-                      project={project}
-                    />
-                    {hasHealthData && (
-                      <ReleaseAdoption
-                        releaseSessions={thisRelease}
-                        allSessions={allReleases}
-                        loading={loading}
-                        reloading={reloading}
-                        errored={errored}
-                        release={release}
-                        project={project}
-                        environment={environments}
-                      />
-                    )}
-                    <ProjectReleaseDetails
-                      release={release}
-                      releaseMeta={releaseMeta}
-                      orgSlug={organization.slug}
-                      projectSlug={project.slug}
-                    />
-                    {commitCount > 0 && (
-                      <CommitAuthorBreakdown
-                        version={version}
-                        orgId={organization.slug}
-                        projectSlug={project.slug}
-                      />
-                    )}
-                    {releaseMeta.projects.length > 1 && (
-                      <OtherProjects
-                        projects={releaseMeta.projects.filter(
-                          p => p.slug !== project.slug
-                        )}
-                        location={location}
-                        version={version}
-                        organization={organization}
-                      />
-                    )}
-                    {hasHealthData && (
-                      <TotalCrashFreeUsers
-                        organization={organization}
-                        version={version}
-                        projectSlug={project.slug}
-                        location={location}
-                      />
-                    )}
-                    {deploys.length > 0 && (
-                      <Deploys
-                        version={version}
-                        orgSlug={organization.slug}
-                        deploys={deploys}
-                        projectId={project.id}
-                      />
-                    )}
-                  </Side>
-                </Body>
+            <SessionsRequest {...sessionsRequestProps}>
+              {({
+                loading: allReleasesLoading,
+                reloading: allReleasesReloading,
+                errored: allReleasesErrored,
+                response: allReleases,
+              }) => (
+                <SessionsRequest {...sessionsRequestProps} query={`release:"${version}"`}>
+                  {({
+                    loading: thisReleaseLoading,
+                    reloading: thisReleaseReloading,
+                    errored: thisReleaseErrored,
+                    response: thisRelease,
+                  }) => {
+                    const loading = allReleasesLoading || thisReleaseLoading;
+                    const reloading = allReleasesReloading || thisReleaseReloading;
+                    const errored = allReleasesErrored || thisReleaseErrored;
+                    return (
+                      <Body>
+                        <Main>
+                          {isReleaseArchived(release) && (
+                            <ReleaseArchivedNotice
+                              onRestore={() => this.handleRestore(project, refetchData)}
+                            />
+                          )}
+
+                          <StyledPageTimeRangeSelector
+                            organization={organization}
+                            relative={period ?? ''}
+                            start={start ?? null}
+                            end={end ?? null}
+                            utc={utc ?? null}
+                            onUpdate={this.handleDateChange}
+                            relativeOptions={{
+                              [RELEASE_PERIOD_KEY]: (
+                                <Fragment>
+                                  {t('Entire Release Period')} (
+                                  <DateTime
+                                    date={releaseBounds.releaseStart}
+                                    timeAndDate
+                                  />{' '}
+                                  -{' '}
+                                  <DateTime date={releaseBounds.releaseEnd} timeAndDate />
+                                  )
+                                </Fragment>
+                              ),
+                              ...DEFAULT_RELATIVE_PERIODS,
+                            }}
+                            defaultPeriod={RELEASE_PERIOD_KEY}
+                          />
+
+                          {(hasDiscover || hasPerformance || hasHealthData) && (
+                            <ReleaseComparisonChart
+                              release={release}
+                              releaseSessions={thisRelease}
+                              allSessions={allReleases}
+                              platform={project.platform}
+                              location={location}
+                              loading={loading}
+                              reloading={reloading}
+                              errored={errored}
+                              project={project}
+                              organization={organization}
+                              api={api}
+                              hasHealthData={hasHealthData}
+                            />
+                          )}
+
+                          <Issues
+                            organization={organization}
+                            selection={selection}
+                            version={version}
+                            location={location}
+                            releaseBounds={releaseBounds}
+                            queryFilterDescription={t('In this release')}
+                            withChart
+                          />
+
+                          <Feature features={['performance-view']}>
+                            {hasReleaseComparisonPerformance ? (
+                              <PerformanceCardTable
+                                organization={organization}
+                                project={project}
+                                isLoading={loading}
+                                // TODO(kelly): hardcoding this until I have data
+                                isEmpty={false}
+                              />
+                            ) : (
+                              <TransactionsList
+                                location={location}
+                                organization={organization}
+                                eventView={releaseEventView}
+                                trendView={releaseTrendView}
+                                selected={selectedSort}
+                                options={sortOptions}
+                                handleDropdownChange={
+                                  this.handleTransactionsListSortChange
+                                }
+                                titles={titles}
+                                generateLink={generateLink}
+                              />
+                            )}
+                          </Feature>
+                        </Main>
+                        <Side>
+                          <ReleaseStats
+                            organization={organization}
+                            release={release}
+                            project={project}
+                          />
+                          {hasHealthData && (
+                            <ReleaseAdoption
+                              releaseSessions={thisRelease}
+                              allSessions={allReleases}
+                              loading={loading}
+                              reloading={reloading}
+                              errored={errored}
+                              release={release}
+                              project={project}
+                              environment={environments}
+                            />
+                          )}
+                          <ProjectReleaseDetails
+                            release={release}
+                            releaseMeta={releaseMeta}
+                            orgSlug={organization.slug}
+                            projectSlug={project.slug}
+                          />
+                          {commitCount > 0 && (
+                            <CommitAuthorBreakdown
+                              version={version}
+                              orgId={organization.slug}
+                              projectSlug={project.slug}
+                            />
+                          )}
+                          {releaseMeta.projects.length > 1 && (
+                            <OtherProjects
+                              projects={releaseMeta.projects.filter(
+                                p => p.slug !== project.slug
+                              )}
+                              location={location}
+                              version={version}
+                              organization={organization}
+                            />
+                          )}
+                          {hasHealthData && (
+                            <TotalCrashFreeUsers
+                              organization={organization}
+                              version={version}
+                              projectSlug={project.slug}
+                              location={location}
+                            />
+                          )}
+                          {deploys.length > 0 && (
+                            <Deploys
+                              version={version}
+                              orgSlug={organization.slug}
+                              deploys={deploys}
+                              projectId={project.id}
+                            />
+                          )}
+                        </Side>
+                      </Body>
+                    );
+                  }}
+                </SessionsRequest>
               )}
               )}
-            </ReleaseDetailsRequest>
+            </SessionsRequest>
           );
           );
         }}
         }}
       </ReleaseContext.Consumer>
       </ReleaseContext.Consumer>

+ 0 - 168
static/app/views/releases/detail/overview/releaseDetailsRequest.tsx

@@ -1,168 +0,0 @@
-import * as React from 'react';
-import {Location} from 'history';
-import isEqual from 'lodash/isEqual';
-
-import {addErrorMessage} from 'app/actionCreators/indicator';
-import {Client} from 'app/api';
-import {t} from 'app/locale';
-import {Organization, SessionApiResponse} from 'app/types';
-import {filterSessionsInTimeWindow, getSessionsInterval} from 'app/utils/sessions';
-import withApi from 'app/utils/withApi';
-
-import {getReleaseParams, ReleaseBounds} from '../../utils';
-
-export type ReleaseHealthRequestRenderProps = {
-  loading: boolean;
-  reloading: boolean;
-  errored: boolean;
-  thisRelease: SessionApiResponse | null;
-  allReleases: SessionApiResponse | null;
-};
-
-type Props = {
-  api: Client;
-  organization: Organization;
-  children: (renderProps: ReleaseHealthRequestRenderProps) => React.ReactNode;
-  location: Location;
-  version: string;
-  releaseBounds: ReleaseBounds;
-  disable?: boolean;
-};
-
-type State = {
-  reloading: boolean;
-  errored: boolean;
-  thisRelease: SessionApiResponse | null;
-  allReleases: SessionApiResponse | null;
-};
-
-class ReleaseDetailsRequest extends React.Component<Props, State> {
-  state: State = {
-    reloading: false,
-    errored: false,
-    thisRelease: null,
-    allReleases: null,
-  };
-
-  componentDidMount() {
-    this.fetchData();
-  }
-
-  componentDidUpdate(prevProps: Props) {
-    if (
-      prevProps.version !== this.props.version ||
-      !isEqual(prevProps.location, this.props.location)
-    ) {
-      this.fetchData();
-    }
-  }
-
-  get path() {
-    const {organization} = this.props;
-
-    return `/organizations/${organization.slug}/sessions/`;
-  }
-
-  get baseQueryParams() {
-    const {location, releaseBounds, organization} = this.props;
-
-    const releaseParams = getReleaseParams({
-      location,
-      releaseBounds,
-    });
-
-    return {
-      field: ['count_unique(user)', 'sum(session)', 'p50(session.duration)'],
-      groupBy: ['session.status'],
-      interval: getSessionsInterval(
-        {
-          start: releaseParams.start,
-          end: releaseParams.end,
-          period: releaseParams.statsPeriod ?? undefined,
-        },
-        {highFidelity: organization.features.includes('minute-resolution-sessions')}
-      ),
-      ...releaseParams,
-    };
-  }
-
-  fetchData = async () => {
-    const {api, disable} = this.props;
-
-    if (disable) {
-      return;
-    }
-
-    api.clear();
-    this.setState(state => ({
-      reloading: state.thisRelease !== null && state.allReleases !== null,
-      errored: false,
-    }));
-
-    const promises = [this.fetchThisRelease(), this.fetchAllReleases()];
-
-    try {
-      const [thisRelease, allReleases] = await Promise.all(promises);
-
-      this.setState({
-        reloading: false,
-        thisRelease: filterSessionsInTimeWindow(
-          thisRelease,
-          this.baseQueryParams.start,
-          this.baseQueryParams.end
-        ),
-        allReleases: filterSessionsInTimeWindow(
-          allReleases,
-          this.baseQueryParams.start,
-          this.baseQueryParams.end
-        ),
-      });
-    } catch (error) {
-      addErrorMessage(error.responseJSON?.detail ?? t('Error loading health data'));
-      this.setState({
-        reloading: false,
-        errored: true,
-      });
-    }
-  };
-
-  async fetchThisRelease() {
-    const {api, version} = this.props;
-
-    const response: SessionApiResponse = await api.requestPromise(this.path, {
-      query: {
-        ...this.baseQueryParams,
-        query: `release:"${version}"`,
-      },
-    });
-
-    return response;
-  }
-
-  async fetchAllReleases() {
-    const {api} = this.props;
-
-    const response: SessionApiResponse = await api.requestPromise(this.path, {
-      query: this.baseQueryParams,
-    });
-
-    return response;
-  }
-
-  render() {
-    const {reloading, errored, thisRelease, allReleases} = this.state;
-    const {children} = this.props;
-
-    const loading = thisRelease === null && allReleases === null;
-
-    return children({
-      loading,
-      reloading,
-      errored,
-      thisRelease,
-      allReleases,
-    });
-  }
-}
-
-export default withApi(ReleaseDetailsRequest);