Skip to content
Closed
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
2 changes: 1 addition & 1 deletion .agents/skills/generate-frontend-forms/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ This skill provides patterns for building forms using Sentry's new form system b

## Core Principle

- Always use the new form system (`useScrapsForm`, `AutoSaveForm`) for new forms. Never create new forms with the legacy JsonForm or Reflux-based systems.
- Always use the new form system (`useScrapsForm`, `AutoSaveForm`) for new forms. Never create new forms with the legacy JsonForm system.

- All forms should be schema based. DO NOT create a form without schema validation.

Expand Down
3 changes: 0 additions & 3 deletions .github/codeowners-coverage-baseline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1221,8 +1221,6 @@ static/app/stores/tagStore.tsx
static/app/stores/teamStore.spec.tsx
static/app/stores/teamStore.tsx
static/app/stores/types.tsx
static/app/stores/useLegacyStore.spec.tsx
static/app/stores/useLegacyStore.tsx
static/app/stores/useSentryAppComponentsData.tsx
static/app/styles/animations.tsx
static/app/styles/global.tsx
Expand All @@ -1248,7 +1246,6 @@ static/app/types/onboarding.tsx
static/app/types/organization.tsx
static/app/types/profiling/core.tsx
static/app/types/reducerAction.tsx
static/app/types/reflux.d.ts
static/app/types/relay.tsx
static/app/types/release.tsx
static/app/types/sampling.tsx
Expand Down
2 changes: 0 additions & 2 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,9 @@ updates:
# We ignore everything that hasn't yet been upgrade, this way we will
# only get the _freshest_ of new packages to consider upgrading
- dependency-name: '@types/react-select'
- dependency-name: '@types/reflux'
- dependency-name: 'gettext-parser'
- dependency-name: 'react-lazyload'
- dependency-name: 'react-select'
- dependency-name: 'reflux'
- dependency-name: 'sprintf-js'
- package-ecosystem: 'docker'
directory: 'self-hosted/'
Expand Down
2 changes: 0 additions & 2 deletions knip.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,6 @@ const config: KnipConfig = {
'tslib', // subdependency of many packages, declare the latest version
'odiff-bin', // raw binary consumed by Python backend, not a JS import
'zrender', // used in echarts
// Referenced by its node_modules path in tests/js/createJestConfig.ts.
'reflux',
],
// Knip's Less compiler expects the extension in `project`; styles are handled by Rspack,
// so do not report them as unused files.
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@
"less-loader": "^13.0.0",
"peggy": "5.1.1",
"react": "19.3.0",
"reflux": "0.4.1",
"rehype-expressive-code": "^0.44.2",
"remark-frontmatter": "^5.0.0",
"remark-gfm": "^4.0.1",
Expand Down
64 changes: 16 additions & 48 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions static/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
- **Framework**: React 19
- **Build Tool**: Rsbuild (powered by Rspack)
- **Package management**: pnpm
- **State Management**: Reflux, React Query (TanStack Query)
- **State Management**: Zustand, React Query (TanStack Query)
- **Styling**: Emotion (CSS-in-JS), Less
- **Testing**: Jest, React Testing Library

Expand Down Expand Up @@ -45,7 +45,7 @@ Use `apiOptions` with `useQuery` from TanStack Query; **never** use the deprecat

## General Frontend Rules

1. NO new Reflux stores
1. NO new stores in `static/app/stores` (use React Query for server data)
2. NO class components
3. NO CSS files (use [core components](./app/components/core/) or Emotion in edge cases)
4. ALWAYS use TypeScript
Expand Down
8 changes: 4 additions & 4 deletions static/app/components/acl/feature.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {useMemo} from 'react';
import {useSelector} from '@tanstack/react-store';

import {getOverride} from 'sentry/overrideRegistry';
import {ConfigStore} from 'sentry/stores/configStore';
import {useLegacyStore} from 'sentry/stores/useLegacyStore';
import type {Organization} from 'sentry/types/organization';
import type {FeatureDisabledOverrides} from 'sentry/types/overrides';
import type {Project} from 'sentry/types/project';
Expand Down Expand Up @@ -138,7 +138,7 @@ function Feature({
renderDisabled = false,
requireAll = true,
}: Props) {
const config = useLegacyStore(ConfigStore);
const configFeatures = useSelector(ConfigStore.store, state => state.features);

const features = useMemo(
() => (Array.isArray(featuresProp) ? featuresProp : [featuresProp]),
Expand All @@ -147,11 +147,11 @@ function Feature({

const allFeatures = useMemo<AllFeatures>(
() => ({
configFeatures: config.features ? Array.from(config.features) : [],
configFeatures: configFeatures ? Array.from(configFeatures) : [],
organization: organization?.features ?? [],
project: project?.features ?? [],
}),
[config.features, organization?.features, project?.features]
[configFeatures, organization?.features, project?.features]
);

const hasFeatureEnabled = useMemo(() => {
Expand Down
7 changes: 5 additions & 2 deletions static/app/components/assistant/guideAnchor.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import {useCallback, useEffect, useRef} from 'react';
import * as Sentry from '@sentry/react';
import {useSelector} from '@tanstack/react-store';

import {Container, Grid} from '@sentry/scraps/layout';

Expand All @@ -15,7 +16,6 @@ import type {Hovercard} from 'sentry/components/hovercard';
import {TourAction, TourGuide} from 'sentry/components/tours/components';
import {t} from 'sentry/locale';
import {GuideStore} from 'sentry/stores/guideStore';
import {useLegacyStore} from 'sentry/stores/useLegacyStore';

interface Props {
target: string;
Expand Down Expand Up @@ -64,7 +64,10 @@ function BaseGuideAnchor({
onFinish,
onStepComplete,
}: Props) {
const {currentGuide, currentStep: step, orgId, forceHide} = useLegacyStore(GuideStore);
const currentGuide = useSelector(GuideStore.store, state => state.currentGuide);
const step = useSelector(GuideStore.store, state => state.currentStep);
const orgId = useSelector(GuideStore.store, state => state.orgId);
const forceHide = useSelector(GuideStore.store, state => state.forceHide);

useEffect(() => {
registerAnchor(target);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {IconTerminal} from '@sentry/icons/terminal';
import {IconUser} from '@sentry/icons/user';
import * as Sentry from '@sentry/react';
import {skipToken, useMutation, useQuery} from '@tanstack/react-query';
import {useSelector} from '@tanstack/react-store';
import DOMPurify from 'dompurify';

import {
Expand Down Expand Up @@ -57,7 +58,6 @@ import {DEPLOY_PREVIEW_CONFIG, NODE_ENV} from 'sentry/constants';
import {t, toggleLocaleDebug} from 'sentry/locale';
import {ConfigStore} from 'sentry/stores/configStore';
import {OrganizationsStore} from 'sentry/stores/organizationsStore';
import {useLegacyStore} from 'sentry/stores/useLegacyStore';
import type {EventIdResponse} from 'sentry/types/event';
import type {ShortIdResponse} from 'sentry/types/group';
import type {Member, Team} from 'sentry/types/organization';
Expand Down Expand Up @@ -309,8 +309,15 @@ export function GlobalCommandPaletteActions() {
const user = useUser();
const isSentryEmployee = useIsSentryEmployee();
const {projects} = useProjects();
const {organizations} = useLegacyStore(OrganizationsStore);
const sentryConfig = useLegacyStore(ConfigStore);
const organizations = useSelector(
OrganizationsStore.store,
state => state.organizations
);
const isSelfHosted = useSelector(ConfigStore.store, state => state.isSelfHosted);
const singleOrganization = useSelector(
ConfigStore.store,
state => state.singleOrganization
);
const params = useParams();
const location = useLocation();
const {mutateAsync: mutateUserOptions} = useMutateUserOptions();
Expand Down Expand Up @@ -362,7 +369,7 @@ export function GlobalCommandPaletteActions() {
const context: Omit<NavigationGroupProps, 'items' | 'name' | 'id'> = {
access: new Set(organization.access),
features: new Set(organization.features),
isSelfHosted: sentryConfig.isSelfHosted,
isSelfHosted,
organization,
};
return getUserOrgNavigationConfiguration()
Expand All @@ -372,7 +379,7 @@ export function GlobalCommandPaletteActions() {
)
)
.sort((a, b) => a.title.localeCompare(b.title));
}, [organization, sentryConfig.isSelfHosted]);
}, [organization, isSelfHosted]);

const prefix = `/organizations/${organization.slug}`;
const hasInsightsRollout = organization.features.includes(
Expand Down Expand Up @@ -638,7 +645,7 @@ export function GlobalCommandPaletteActions() {
to={makeProjectsPathname({path: '/', organization})}
/>

{!sentryConfig.singleOrganization && !isDemoModeActive() && (
{!singleOrganization && !isDemoModeActive() && (
<CMDKAction
display={{label: t('Switch Organization'), icon: <IconBuilding />}}
keywords={[t('organization'), t('change'), t('change organization')]}
Expand Down
Loading
Loading