Skip to content
Merged
104 changes: 50 additions & 54 deletions static/app/components/feedback/feedbackOnboarding/sidebar.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import type {ReactNode} from 'react';
import {Fragment, useEffect, useMemo, useState} from 'react';
import styled from '@emotion/styled';
import {parseAsStringLiteral, useQueryState} from 'nuqs';
import {PlatformIcon} from 'platformicons';

import HighlightTopRightPattern from 'sentry-images/pattern/highlight-top-right.svg';

import {LinkButton} from '@sentry/scraps/button';
import {CompactSelect} from '@sentry/scraps/compactSelect';
import {Flex} from '@sentry/scraps/layout';
import {Container, Flex} from '@sentry/scraps/layout';
import {OverlayTrigger} from '@sentry/scraps/overlayTrigger';

import {FeedbackOnboardingLayout} from 'sentry/components/feedback/feedbackOnboarding/feedbackOnboardingLayout';
Expand Down Expand Up @@ -42,7 +43,6 @@ import {useLegacyStore} from 'sentry/stores/useLegacyStore';
import type {SelectValue} from 'sentry/types/core';
import type {PlatformKey, Project} from 'sentry/types/project';
import {trackAnalytics} from 'sentry/utils/analytics';
import {useUrlParams} from 'sentry/utils/url/useUrlParams';
import {useLocation} from 'sentry/utils/useLocation';
import {useOrganization} from 'sentry/utils/useOrganization';

Expand Down Expand Up @@ -197,21 +197,20 @@ function OnboardingContent({currentProject}: {currentProject: Project}) {
textValue?: string;
}>(jsFrameworkSelectOptions[0]!);

const defaultTab = 'npm';
const location = useLocation();
const crashReportOnboarding = location.hash === CRASH_REPORT_HASH;

const {getParamValue: setupMode, setParamValue: setSetupMode} = useUrlParams(
const [setupMode, setSetupMode] = useQueryState(
'mode',
defaultTab
parseAsStringLiteral(['npm', 'jsLoader'] as const).withDefault('npm')
);

const currentPlatform = currentProject.platform
? (platforms.find(p => p.id === currentProject.platform) ?? otherPlatform)
: otherPlatform;

const webBackendPlatform = replayBackendPlatforms.includes(currentPlatform.id);
const showJsFrameworkInstructions = webBackendPlatform && setupMode() === 'npm';
const showJsFrameworkInstructions = webBackendPlatform && setupMode === 'npm';

const crashApiPlatform = feedbackCrashApiPlatforms.includes(currentPlatform.id);
const widgetPlatform = feedbackWidgetPlatforms.includes(currentPlatform.id);
Expand Down Expand Up @@ -261,48 +260,50 @@ function OnboardingContent({currentProject}: {currentProject: Project}) {
const radioButtons = (
<Header>
{showRadioButtons ? (
<StyledRadioGroup
label="mode"
choices={[
[
'npm',
webBackendPlatform ? (
<Flex align="center" wrap="wrap" gap="md" key="platform-select">
{tct('I use [platformSelect]', {
platformSelect: (
<CompactSelect
size="xs"
trigger={triggerProps => (
<OverlayTrigger.Button {...triggerProps}>
{jsFramework.label ?? triggerProps.children}
</OverlayTrigger.Button>
)}
value={jsFramework.value}
onChange={setJsFramework}
options={jsFrameworkSelectOptions}
position="bottom-end"
key={jsFramework.textValue}
disabled={setupMode() === 'jsLoader'}
<Container padding="md 0">
<RadioGroup<typeof setupMode>
label="mode"
choices={[
[
'npm',
webBackendPlatform ? (
<Flex align="center" wrap="wrap" gap="md" key="platform-select">
{tct('I use [platformSelect]', {
platformSelect: (
<CompactSelect
size="xs"
trigger={triggerProps => (
<OverlayTrigger.Button {...triggerProps}>
{jsFramework.label ?? triggerProps.children}
</OverlayTrigger.Button>
)}
value={jsFramework.value}
onChange={setJsFramework}
options={jsFrameworkSelectOptions}
position="bottom-end"
key={jsFramework.textValue}
disabled={setupMode === 'jsLoader'}
/>
),
})}
{jsFrameworkDocs?.platformOptions && (
<PlatformOptionDropdown
platformOptions={jsFrameworkDocs?.platformOptions}
disabled={setupMode === 'jsLoader'}
/>
),
})}
{jsFrameworkDocs?.platformOptions && (
<PlatformOptionDropdown
platformOptions={jsFrameworkDocs?.platformOptions}
disabled={setupMode() === 'jsLoader'}
/>
)}
</Flex>
) : (
t('I use NPM or Yarn')
),
],
['jsLoader', t('I use HTML templates (Loader Script)')],
]}
value={setupMode()}
onChange={setSetupMode}
tooltipPosition="top-start"
/>
)}
</Flex>
) : (
t('I use NPM or Yarn')
),
],
['jsLoader', t('I use HTML templates (Loader Script)')],
]}
value={setupMode}
onChange={value => setSetupMode(value)}
tooltipPosition="top-start"
/>
</Container>
) : (
(newDocs?.platformOptions?.siblingOption ||
newDocs?.platformOptions?.packageManager) &&
Expand Down Expand Up @@ -370,9 +371,8 @@ function OnboardingContent({currentProject}: {currentProject: Project}) {
return 'feedbackOnboardingCrashApi';
}
if (
setupMode() === 'npm' || // switched to NPM option
(!setupMode() && defaultTab === 'npm' && widgetPlatform) || // default value for FE frameworks when ?mode={...} in URL is not set yet
npmOnlyFramework // even if '?mode=jsLoader', only show npm instructions for FE frameworks)
setupMode === 'npm' || // switched to NPM option
npmOnlyFramework // even if '?mode=jsLoader', only show npm instructions for FE frameworks
) {
return 'feedbackOnboardingNpm';
}
Expand Down Expand Up @@ -431,7 +431,3 @@ const StyledIdBadge = styled(IdBadge)`
white-space: nowrap;
flex-shrink: 1;
`;

const StyledRadioGroup = styled(RadioGroup)`
padding: ${p => p.theme.space.md} 0;
`;
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {createMemoryRouter, RouterProvider} from 'react-router-dom';
import {ProjectFixture} from 'sentry-fixture/project';

import {SentryNuqsTestingAdapter} from 'sentry-test/nuqsTestingAdapter';
import {act, renderHook} from 'sentry-test/reactTestingLibrary';

import {useCurrentProjectState} from 'sentry/components/onboarding/gettingStartedDoc/utils/useCurrentProjectState';
Expand All @@ -16,14 +17,15 @@ import type {Project} from 'sentry/types/project';

function createWrapper(projectSlug?: string) {
return function Wrapper({children}: any) {
const wrapped = <SentryNuqsTestingAdapter>{children}</SentryNuqsTestingAdapter>;
const memoryRouter = createMemoryRouter([
{
path: '/',
element: children,
element: wrapped,
},
{
path: '/:projectId/',
element: children,
element: wrapped,
},
]);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import {useCallback, useEffect, useMemo, useState} from 'react';
import partition from 'lodash/partition';
import {parseAsString, useQueryState} from 'nuqs';

import {PageFiltersStore} from 'sentry/components/pageFilters/store';
import type {OnboardingDrawerKey} from 'sentry/stores/onboardingDrawerStore';
import {useLegacyStore} from 'sentry/stores/useLegacyStore';
import type {PlatformKey, Project} from 'sentry/types/project';
import {getSelectedProjectList} from 'sentry/utils/project/useSelectedProjectsHaveField';
import {useUrlParams} from 'sentry/utils/url/useUrlParams';
import {useProjects} from 'sentry/utils/useProjects';

type Props = {
Expand All @@ -24,8 +24,7 @@ export function useCurrentProjectState({
}: Props) {
const {projects, initiallyLoaded: projectsLoaded} = useProjects();
const {selection, isReady} = useLegacyStore(PageFiltersStore);
const {getParamValue: projectIds} = useUrlParams('project');
const projectId = projectIds()?.split('&').at(0);
const [projectId] = useQueryState('project', parseAsString);
const isActive = currentPanel === targetPanel;

// Projects with onboarding instructions
Expand Down
23 changes: 11 additions & 12 deletions static/app/components/replays/virtualizedGrid/useDetailsSplit.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type {RefObject} from 'react';
import {useCallback} from 'react';
import {parseAsInteger, useQueryState} from 'nuqs';

import {useUrlParams} from 'sentry/utils/url/useUrlParams';
import {useResizableDrawer} from 'sentry/utils/useResizableDrawer';

interface OnClickProps {
Expand All @@ -26,26 +26,23 @@ export function useDetailsSplit({
onShowDetails,
urlParamName,
}: Props) {
const {getParamValue: getDetailIndex, setParamValue: setDetailIndex} = useUrlParams(
urlParamName,
''
);
const [detailIndex, setDetailIndex] = useQueryState(urlParamName, parseAsInteger);

const onClickCell = useCallback(
({dataIndex, rowIndex}: OnClickProps) => {
if (getDetailIndex() === String(dataIndex)) {
setDetailIndex('');
if (detailIndex === dataIndex) {
setDetailIndex(null);
onHideDetails?.();
} else {
setDetailIndex(String(dataIndex));
setDetailIndex(dataIndex);
onShowDetails?.({dataIndex, rowIndex});
}
},
[getDetailIndex, setDetailIndex, onHideDetails, onShowDetails]
[detailIndex, setDetailIndex, onHideDetails, onShowDetails]
);

const onCloseDetailsSplit = useCallback(() => {
setDetailIndex('');
setDetailIndex(null);
onHideDetails?.();
}, [setDetailIndex, onHideDetails]);

Expand All @@ -63,13 +60,15 @@ export function useDetailsSplit({
const maxContainerHeight =
(containerRef.current?.clientHeight || window.innerHeight) - handleHeight;
const splitSize =
frames && getDetailIndex() ? Math.min(maxContainerHeight, containerSize) : undefined;
frames && detailIndex !== null
? Math.min(maxContainerHeight, containerSize)
: undefined;

return {
onClickCell,
onCloseDetailsSplit,
resizableDrawerProps,
selectedIndex: getDetailIndex(),
selectedIndex: detailIndex,
splitSize,
};
}
Loading
Loading