Skip to content

Commit c3bbdac

Browse files
committed
ref(ui): Add deprecation warning to useProjects() without slugs
Add a development-time console warning when useProjects() is called without the slugs parameter. This prepares for removing the all_projects=1 bootstrap fetch by encouraging explicit project fetching. Updates 18 components to pass specific slugs to useProjects(), ensuring they will continue working when projects are no longer pre-loaded.
1 parent 8f6defa commit c3bbdac

File tree

18 files changed

+53
-27
lines changed

18 files changed

+53
-27
lines changed

static/app/components/profiling/exportProfileButton.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ export function ExportProfileButton(props: ExportProfileButtonProps) {
2121
const api = useApi();
2222
const organization = useOrganization();
2323

24-
const project = useProjects().projects.find(p => {
24+
const {projects} = useProjects({slugs: props.projectId ? [props.projectId] : []});
25+
const project = projects.find(p => {
2526
return p.slug === props.projectId;
2627
});
2728

static/app/components/profiling/profilingBreadcrumbs.tsx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,14 @@ export interface ProfilingBreadcrumbsProps {
2121
}
2222

2323
function ProfilingBreadcrumbs({organization, trails}: ProfilingBreadcrumbsProps) {
24-
const {projects} = useProjects();
24+
// Extract project slugs from trails that have them
25+
const projectSlugs = trails
26+
.filter(
27+
(trail): trail is ProfileSummaryTrail | FlamegraphTrail =>
28+
trail.type === 'profile summary' || trail.type === 'flamechart'
29+
)
30+
.map(trail => trail.payload.projectSlug);
31+
const {projects} = useProjects({slugs: projectSlugs});
2532
const crumbs = useMemo(
2633
() => trails.map(trail => trailToCrumb(trail, {organization, projects})),
2734
[organization, trails, projects]

static/app/utils/discover/teamKeyTransactionField.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ export default function TeamKeyTransactionFieldWrapper({
8787
transactionName,
8888
...props
8989
}: WrapperProps) {
90-
const {projects} = useProjects();
90+
const {projects} = useProjects({slugs: projectSlug ? [projectSlug] : []});
9191
const project = projects.find(proj => proj.slug === projectSlug);
9292

9393
// All these fields need to be defined in order to toggle a team key

static/app/utils/useProjects.tsx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,25 @@ async function fetchProjects(
149149
* This hook also provides a way to select specific project slugs, and search
150150
* (type-ahead) for more projects that may not be in the project store.
151151
*
152-
* NOTE: Currently ALL projects are always loaded, but this hook is designed
153-
* for future-compat in a world where we do _not_ load all projects.
152+
* DEPRECATED USAGE: Calling useProjects() without the `slugs` parameter is
153+
* deprecated. This pattern assumes all projects are loaded in the store,
154+
* which will not be true once we remove the all_projects=1 bootstrap fetch.
155+
*
156+
* RECOMMENDED: Always pass specific slugs you need:
157+
* const {projects} = useProjects({slugs: [group.project.slug]});
158+
*
159+
* This ensures projects are fetched on-demand if not already in the store.
154160
*/
155161
function useProjects({limit, slugs, orgId: propOrgId}: Options = {}) {
162+
if (process.env.NODE_ENV !== 'production' && !slugs) {
163+
// eslint-disable-next-line no-console
164+
console.warn(
165+
'useProjects() called without slugs parameter. ' +
166+
'This usage is deprecated and may break when all_projects=1 is removed. ' +
167+
'Pass specific slugs to ensure projects are fetched on-demand.'
168+
);
169+
}
170+
156171
const api = useApi();
157172

158173
const organization = useOrganization({allowNull: true});

static/app/views/alerts/rules/issue/details/ruleDetails.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ function AlertRuleDetails({params, location, router}: AlertRuleDetailsProps) {
7474
const queryClient = useQueryClient();
7575
const organization = useOrganization();
7676
const api = useApi();
77-
const {projects, fetching: projectIsLoading} = useProjects();
77+
const {projects, fetching: projectIsLoading} = useProjects({slugs: [params.projectId]});
7878
const project = projects.find(({slug}) => slug === params.projectId);
7979
const {projectId: projectSlug, ruleId} = params;
8080
const {

static/app/views/insights/common/components/tableCells/starredSegmentCell.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const STARRED_SEGMENT_TABLE_QUERY_KEY = ['starred-segment-table'];
2727

2828
export function StarredSegmentCell({segmentName, isStarred, projectSlug}: Props) {
2929
const queryClient = useQueryClient();
30-
const {projects} = useProjects();
30+
const {projects} = useProjects({slugs: [projectSlug]});
3131
const project = projects.find(p => p.slug === projectSlug);
3232

3333
const {setStarredSegment, isPending} = useStarredSegment({

static/app/views/insights/pages/transactionCell.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,12 @@ interface Props {
1616
}
1717

1818
export function TransactionCell({project, transaction, transactionMethod}: Props) {
19-
const projects = useProjects();
19+
const {projects} = useProjects({slugs: project ? [project] : []});
2020
const organization = useOrganization();
2121
const location = useLocation();
2222
const {view} = useDomainViewFilters();
2323

24-
const projectId = projects.projects.find(p => p.slug === project)?.id;
24+
const projectId = projects.find(p => p.slug === project)?.id;
2525

2626
const searchQuery = new MutableSearch('');
2727
if (transactionMethod) {

static/app/views/issueDetails/groupDetails.tsx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,6 @@ function useFetchGroupDetails(): FetchGroupDetailsState {
234234
const navigate = useNavigate();
235235
const defaultIssueEvent = useDefaultIssueEvent();
236236
const hasStreamlinedUI = useHasStreamlinedUI();
237-
const {projects} = useProjects();
238237

239238
const [allProjectChanged, setAllProjectChanged] = useState<boolean>(false);
240239

@@ -261,6 +260,9 @@ function useFetchGroupDetails(): FetchGroupDetailsState {
261260
refetch: refetchGroupCall,
262261
} = useGroup({groupId});
263262

263+
const groupProjectSlug = groupData?.project?.slug;
264+
const {projects} = useProjects({slugs: groupProjectSlug ? [groupProjectSlug] : []});
265+
264266
/**
265267
* TODO(streamline-ui): Remove this whole hook once the legacy UI is removed. The streamlined UI exposes the
266268
* filters on the page so the user is expected to clear it themselves, and the empty state is actually expected.

static/app/views/issueDetails/groupDistributionsDrawer.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,8 @@ type Props = {
2222
*/
2323
export function GroupDistributionsDrawer({group, includeFeatureFlagsTab}: Props) {
2424
const organization = useOrganization();
25-
const {projects} = useProjects();
26-
const project = projects.find(p => p.slug === group.project.slug)!;
25+
const {projects} = useProjects({slugs: [group.project.slug]});
26+
const project = projects.find(p => p.slug === group.project.slug);
2727

2828
const {tab, setTab} = useDrawerTab({enabled: includeFeatureFlagsTab});
2929

static/app/views/issueDetails/groupFeatureFlags/flagDrawerContent.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ export default function FlagDrawerContent({
4545
});
4646

4747
// CTA logic
48-
const {projects} = useProjects();
49-
const project = projects.find(p => p.slug === group.project.slug)!;
48+
const {projects} = useProjects({slugs: [group.project.slug]});
49+
const project = projects.find(p => p.slug === group.project.slug);
5050

5151
const showCTA =
5252
allGroupFlagCount === 0 &&

0 commit comments

Comments
 (0)