perf(front): query only rendered fields in application settings pages (#22454)

Part of the application settings architecture work:
https://github.com/twentyhq/core-team-issues/issues/2456

Application settings pages pulled far more data than they render:

- **`FindOneApplicationByUniversalIdentifier`** fetched the full
`ApplicationFields` fragment (all nested agents, objects,
logicFunctions, frontComponents, commandMenuItems) just so
`SettingsAvailableApplicationDetails` could check whether an app is
installed. Slimmed to `id, universalIdentifier, name, version` (its only
caller; every field usage audited).
- **`FindManyApplicationRegistrations`** (developer tab list) fetched
the 17-field registration fragment including `isConfigured`, which
triggers a per-row DataLoader resolve. The list renders only `id, name,
universalIdentifier, sourceType` — new lean
`ApplicationRegistrationListItem` fragment. The detail page and admin
list, which actually render `isConfigured`, keep the full fragment.
- **`SidePanelEditOwnerSection`** pulled the full `FindOneApplication`
payload to render a name — new `FindOneApplicationName` (`id, name`)
query.

Regenerated `generated-metadata/graphql.ts` (document-level changes
only, zero schema drift; data/admin outputs byte-identical).
Deliberately untouched: the installed-app detail page query (renders its
nested collections across tabs), the sub-detail pages that share its
cache entry, and the marketplace manifest usage (needs backend fields —
later PR).

Verified: typecheck, oxlint/oxfmt on touched files, jest (applications
19/19, navigation-menu-item 86/86).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_011sST4rPLU1Koi2oVGi84ei

---
_Generated by [Claude
Code](https://claude.ai/code/session_011sST4rPLU1Koi2oVGi84ei)_

<!-- This is an auto-generated description by cubic. -->
<a
href="https://cubic.dev/pr/twentyhq/twenty/pull/22454?utm_source=github"
target="_blank" rel="noopener noreferrer"
data-no-image-dialog="true"><picture><source
media="(prefers-color-scheme: dark)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source
media="(prefers-color-scheme: light)"
srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img
alt="Review in cubic"
src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a>
<!-- End of auto-generated description by cubic. -->
This commit is contained in:
martmull
2026-07-02 16:52:28 +02:00
committed by GitHub
parent 49095dcfe0
commit 4f44131901
6 changed files with 44 additions and 15 deletions
File diff suppressed because one or more lines are too long
@@ -1,11 +1,12 @@
import { gql } from '@apollo/client';
import { APPLICATION_FRAGMENT } from '@/applications/graphql/fragments/applicationFragment';
export const FIND_ONE_APPLICATION_BY_UNIVERSAL_IDENTIFIER = gql`
${APPLICATION_FRAGMENT}
query FindOneApplicationByUniversalIdentifier($universalIdentifier: UUID!) {
findOneApplication(universalIdentifier: $universalIdentifier) {
...ApplicationFields
id
universalIdentifier
name
version
}
}
`;
@@ -0,0 +1,10 @@
import { gql } from '@apollo/client';
export const FIND_ONE_APPLICATION_NAME = gql`
query FindOneApplicationName($id: UUID!) {
findOneApplication(id: $id) {
id
name
}
}
`;
@@ -8,7 +8,7 @@ import { useNavigationMenuItemEditController } from '@/navigation-menu-item/edit
import { useSelectedNavigationMenuItemEditItem } from '@/navigation-menu-item/edit/hooks/useSelectedNavigationMenuItemEditItem';
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
import { useQuery } from '@apollo/client/react';
import { FindOneApplicationDocument } from '~/generated-metadata/graphql';
import { FindOneApplicationNameDocument } from '~/generated-metadata/graphql';
type SidePanelEditOwnerSectionProps = {
applicationId?: string | null;
@@ -28,7 +28,7 @@ export const SidePanelEditOwnerSection = ({
const applicationId = applicationIdProp ?? applicationIdFromSection;
const { data } = useQuery(FindOneApplicationDocument, {
const { data } = useQuery(FindOneApplicationNameDocument, {
variables: { id: applicationId ?? '' },
skip: !isDefined(applicationId),
});
@@ -1,12 +1,19 @@
import { gql } from '@apollo/client';
import { APPLICATION_REGISTRATION_FRAGMENT } from '@/settings/application-registrations/graphql/fragments/applicationRegistrationFragment';
export const APPLICATION_REGISTRATION_LIST_ITEM_FRAGMENT = gql`
fragment ApplicationRegistrationListItem on ApplicationRegistration {
id
universalIdentifier
name
sourceType
}
`;
export const FIND_MANY_APPLICATION_REGISTRATIONS = gql`
query FindManyApplicationRegistrations {
findManyApplicationRegistrations {
...ApplicationRegistrationFragment
...ApplicationRegistrationListItem
}
}
${APPLICATION_REGISTRATION_FRAGMENT}
${APPLICATION_REGISTRATION_LIST_ITEM_FRAGMENT}
`;
@@ -25,7 +25,7 @@ import { H2Title } from 'twenty-ui/typography';
import { Button, SearchInput } from 'twenty-ui/input';
import { Section } from 'twenty-ui/layout';
import {
type ApplicationRegistrationFragmentFragment,
type ApplicationRegistrationListItemFragment,
FindManyApplicationRegistrationsDocument,
} from '~/generated-metadata/graphql';
import { useCopyToClipboard } from '~/hooks/useCopyToClipboard';
@@ -90,7 +90,7 @@ export const SettingsApplicationsDeveloperTab = () => {
);
}, [marketplaceApps, marketplaceAppSearchTerm]);
const registrations: ApplicationRegistrationFragmentFragment[] =
const registrations: ApplicationRegistrationListItemFragment[] =
data?.findManyApplicationRegistrations ?? [];
const createCommands = [
@@ -114,7 +114,7 @@ export const SettingsApplicationsDeveloperTab = () => {
);
const getRegistrationLink = (
registration: ApplicationRegistrationFragmentFragment,
registration: ApplicationRegistrationListItemFragment,
) =>
getSettingsPath(SettingsPath.ApplicationRegistrationDetail, {
applicationRegistrationId: registration.id,