Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
3b48b12
lock file
jonathanawesome Nov 14, 2025
56446de
rename hasUnusedArguments to hasArguments
jonathanawesome Nov 14, 2025
ab246ec
Merge branch 'main' into console-1493-schema-explorer-displaying-argu…
jonathanawesome Nov 17, 2025
3ca8821
extract shared filtering logic to hook, pull out - fields and -argume…
jonathanawesome Nov 17, 2025
7fe9a6b
refactor arguments list toggle to descriptions visible toggle, keep l…
jonathanawesome Nov 17, 2025
1c172fe
clean up conditionals to match /explorer/*
jonathanawesome Nov 17, 2025
9c77707
lock file
jonathanawesome Nov 17, 2025
159ec1a
fix backwards switch
jonathanawesome Nov 17, 2025
e4b2798
set default descriptionsVisible to false
jonathanawesome Nov 18, 2025
d62cc36
remove collapsed props
jonathanawesome Nov 18, 2025
13ba6b4
gemini catches one!
jonathanawesome Nov 18, 2025
37fd0d8
Merge branch 'main' into console-1493-schema-explorer-displaying-argu…
jonathanawesome Nov 19, 2025
d1d8619
enhance fed seed schema arguments with descriptions
jonathanawesome Nov 19, 2025
b012343
lock file
jonathanawesome Nov 20, 2025
bf67aa6
Merge branch 'main' into console-1493-schema-explorer-displaying-argu…
jonathanawesome Nov 20, 2025
70c54b3
lock file
jonathanawesome Nov 20, 2025
df36bfb
bump argument type font weight
jonathanawesome Nov 20, 2025
7f81933
Merge branch 'main' into console-1493-schema-explorer-displaying-argu…
jonathanawesome Nov 21, 2025
b7f3acc
Merge branch 'main' into console-1493-schema-explorer-displaying-argu…
jonathanawesome Nov 22, 2025
cdfe84f
fix composition errors...why didn't this flag before?
jonathanawesome Nov 22, 2025
02d1078
prettier --write
jonathanawesome Nov 22, 2025
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
425 changes: 31 additions & 394 deletions packages/web/app/src/components/target/explorer/common.tsx

Large diffs are not rendered by default.

8 changes: 4 additions & 4 deletions packages/web/app/src/components/target/explorer/enum-type.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { FragmentType, graphql, useFragment } from '@/gql';
import { useRouter } from '@tanstack/react-router';
import {
DeprecationNote,
DescriptionInline,
Description,
GraphQLTypeCard,
GraphQLTypeCardListItem,
LinkToCoordinatePage,
Expand Down Expand Up @@ -99,16 +99,16 @@ export function GraphQLEnumTypeComponent(props: {
{value.name}
</LinkToCoordinatePage>
</DeprecationNote>
{value.description ? <DescriptionInline description={value.description} /> : null}
{value.description && <Description description={value.description} />}
</div>
{value.supergraphMetadata ? (
{value.supergraphMetadata && (
<SupergraphMetadataList
targetSlug={props.targetSlug}
projectSlug={props.projectSlug}
organizationSlug={props.organizationSlug}
supergraphMetadata={value.supergraphMetadata}
/>
) : null}
)}
</GraphQLTypeCardListItem>
))}
</div>
Expand Down
26 changes: 15 additions & 11 deletions packages/web/app/src/components/target/explorer/filter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ import {
useLocation,
useRouter,
} from '@tanstack/react-router';
import { useArgumentListToggle, usePeriodSelector, useSchemaExplorerContext } from './provider';
import {
useDescriptionsVisibleToggle,
usePeriodSelector,
useSchemaExplorerContext,
} from './provider';

const TypeFilter_AllTypes = graphql(`
query TypeFilter_AllTypes(
Expand Down Expand Up @@ -195,28 +199,28 @@ export function DateRangeFilter() {
);
}

export function ArgumentVisibilityFilter() {
const [collapsed, toggleCollapsed] = useArgumentListToggle();
export function DescriptionsVisibilityFilter() {
const { isDescriptionsVisible, toggleDescriptionsVisible } = useDescriptionsVisibleToggle();
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<div className="bg-secondary flex h-[40px] flex-row items-center gap-x-4 rounded-md border px-3">
<div>
<Label htmlFor="filter-toggle-arguments" className="text-sm font-normal">
All arguments
<Label htmlFor="filter-toggle-descriptions" className="text-sm font-normal">
Show descriptions
</Label>
</div>
<Switch
checked={!collapsed}
onCheckedChange={toggleCollapsed}
id="filter-toggle-arguments"
checked={isDescriptionsVisible}
onCheckedChange={toggleDescriptionsVisible}
id="filter-toggle-descriptions"
/>
</div>
</TooltipTrigger>
<TooltipContent>
List of arguments is collapsed by default. You can toggle this setting to display all
arguments.
Descriptions are not visible by default. You can toggle this setting to display all
descriptions.
</TooltipContent>
</Tooltip>
</TooltipProvider>
Expand Down Expand Up @@ -320,7 +324,7 @@ export function MetadataFilter(props: { options: Array<{ name: string; values: s
>
{props.options.map(({ name, values }, i) => (
<React.Fragment key={name}>
{i > 0 ? <DropdownMenuSeparator /> : null}
{i > 0 && <DropdownMenuSeparator />}
<DropdownMenuGroup
className="flex cursor-pointer overflow-x-hidden text-sm text-gray-400 hover:underline"
onClick={() => {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
import { FragmentType, graphql, useFragment } from '@/gql';
import { DeprecationNote, Description, GraphQLTypeAsLink, LinkToCoordinatePage } from './common';
import { useDescriptionsVisibleToggle } from './provider';

export const GraphQLArguments_ArgumentFragment = graphql(`
fragment GraphQLArguments_ArgumentFragment on GraphQLArgument {
name
description
type
isDeprecated
deprecationReason
}
`);

export function GraphQLArguments(props: {
parentCoordinate: string;
args: FragmentType<typeof GraphQLArguments_ArgumentFragment>[];
styleDeprecated: boolean;
organizationSlug: string;
projectSlug: string;
targetSlug: string;
}) {
const args = useFragment(GraphQLArguments_ArgumentFragment, props.args);

const { isDescriptionsVisible } = useDescriptionsVisibleToggle();

return (
<span className="ml-1 text-gray-400">
<span>(</span>
<div className="pl-4 text-gray-300">
{args.map(arg => {
const coordinate = `${props.parentCoordinate}.${arg.name}`;
return (
<div key={arg.name}>
<DeprecationNote
styleDeprecated={props.styleDeprecated}
deprecationReason={arg.deprecationReason}
>
<LinkToCoordinatePage
organizationSlug={props.organizationSlug}
projectSlug={props.projectSlug}
targetSlug={props.targetSlug}
coordinate={coordinate}
>
{arg.name}
</LinkToCoordinatePage>
</DeprecationNote>
{': '}
<GraphQLTypeAsLink
className="font-medium"
organizationSlug={props.organizationSlug}
projectSlug={props.projectSlug}
targetSlug={props.targetSlug}
type={arg.type}
/>
{arg.description && isDescriptionsVisible && (
<Description description={arg.description} />
)}
</div>
);
})}
</div>
<span>)</span>
</span>
);
}
154 changes: 154 additions & 0 deletions packages/web/app/src/components/target/explorer/graphql-fields.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
import { FragmentType, graphql, useFragment } from '@/gql';
import {
DeprecationNote,
Description,
GraphQLTypeAsLink,
GraphQLTypeCardListItem,
LinkToCoordinatePage,
SchemaExplorerUsageStats,
} from './common';
import { GraphQLArguments } from './graphql-arguments';
import { SupergraphMetadataList } from './super-graph-metadata';
import { useExplorerFieldFiltering } from './utils';

const GraphQLFields_FieldFragment = graphql(`
fragment GraphQLFields_FieldFragment on GraphQLField {
name
description
type
isDeprecated
deprecationReason
usage {
total
...SchemaExplorerUsageStats_UsageFragment
}
args {
...GraphQLArguments_ArgumentFragment
}
supergraphMetadata {
...SupergraphMetadataList_SupergraphMetadataFragment
}
}
`);

export function GraphQLFields(props: {
typeName: string;
fields: Array<FragmentType<typeof GraphQLFields_FieldFragment>>;
totalRequests?: number;
targetSlug: string;
projectSlug: string;
organizationSlug: string;
warnAboutUnusedArguments: boolean;
warnAboutDeprecatedArguments: boolean;
styleDeprecated: boolean;
}) {
const { totalRequests } = props;
const fieldsFromFragment = useFragment(GraphQLFields_FieldFragment, props.fields);

const sortedAndFilteredFields = useExplorerFieldFiltering({
fields: fieldsFromFragment,
});

return (
<TooltipProvider delayDuration={0}>
<div className="flex flex-col">
{sortedAndFilteredFields.map((field, i) => {
const coordinate = `${props.typeName}.${field.name}`;
const isUsed = field.usage.total > 0;
const hasArguments = field.args.length > 0;
const showsUnusedSchema = typeof totalRequests !== 'number';
const isDeprecated = field.isDeprecated;

return (
<GraphQLTypeCardListItem key={field.name} index={i}>
<div className="w-full">
<div className="flex w-full flex-row items-baseline justify-between">
<div>
{props.warnAboutUnusedArguments &&
isUsed &&
hasArguments &&
showsUnusedSchema && (
<Tooltip>
<TooltipContent>
This field is used but the presented arguments are not.
</TooltipContent>
<TooltipTrigger>
<span className="mr-1 text-sm text-orange-500">*</span>
</TooltipTrigger>
</Tooltip>
)}
{props.warnAboutDeprecatedArguments && !isDeprecated && (
<Tooltip>
<TooltipContent>
This field is not deprecated but the presented arguments are.
</TooltipContent>
<TooltipTrigger>
<span className="mr-1 text-sm text-orange-500">*</span>
</TooltipTrigger>
</Tooltip>
)}
<DeprecationNote
styleDeprecated={props.styleDeprecated}
deprecationReason={field.deprecationReason}
>
<LinkToCoordinatePage
organizationSlug={props.organizationSlug}
projectSlug={props.projectSlug}
targetSlug={props.targetSlug}
coordinate={coordinate}
className="font-semibold"
>
{field.name}
</LinkToCoordinatePage>
</DeprecationNote>
{field.args.length > 0 && (
<GraphQLArguments
organizationSlug={props.organizationSlug}
projectSlug={props.projectSlug}
targetSlug={props.targetSlug}
styleDeprecated={props.styleDeprecated}
parentCoordinate={coordinate}
args={field.args}
/>
)}
<span className="mr-1">:</span>
<GraphQLTypeAsLink
organizationSlug={props.organizationSlug}
projectSlug={props.projectSlug}
targetSlug={props.targetSlug}
className="font-semibold text-gray-300"
type={field.type}
/>
</div>
<div className="flex flex-row items-center">
{field.supergraphMetadata && (
<div className="ml-1">
<SupergraphMetadataList
targetSlug={props.targetSlug}
projectSlug={props.projectSlug}
organizationSlug={props.organizationSlug}
supergraphMetadata={field.supergraphMetadata}
/>
</div>
)}
{typeof totalRequests === 'number' && (
<SchemaExplorerUsageStats
totalRequests={totalRequests}
usage={field.usage}
targetSlug={props.targetSlug}
projectSlug={props.projectSlug}
organizationSlug={props.organizationSlug}
/>
)}
</div>
</div>
{field.description && <Description description={field.description} />}
</div>
</GraphQLTypeCardListItem>
);
})}
</div>
</TooltipProvider>
);
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FragmentType, graphql, useFragment } from '@/gql';
import { useRouter } from '@tanstack/react-router';
import { GraphQLFields, GraphQLTypeCard } from './common';
import { GraphQLTypeCard } from './common';
import { GraphQLFields } from './graphql-fields';

const GraphQLInterfaceTypeComponent_TypeFragment = graphql(`
fragment GraphQLInterfaceTypeComponent_TypeFragment on GraphQLInterfaceType {
Expand Down Expand Up @@ -29,12 +29,6 @@ export function GraphQLInterfaceTypeComponent(props: {
warnAboutDeprecatedArguments: boolean;
styleDeprecated: boolean;
}) {
const router = useRouter();
const searchObj = router.latestLocation.search;
const search =
'search' in searchObj && typeof searchObj.search === 'string'
? searchObj.search.toLowerCase()
: undefined;
const ttype = useFragment(GraphQLInterfaceTypeComponent_TypeFragment, props.type);
return (
<GraphQLTypeCard
Expand All @@ -50,7 +44,6 @@ export function GraphQLInterfaceTypeComponent(props: {
<GraphQLFields
typeName={ttype.name}
fields={ttype.fields}
filterValue={search}
totalRequests={props.totalRequests}
targetSlug={props.targetSlug}
projectSlug={props.projectSlug}
Expand Down
13 changes: 2 additions & 11 deletions packages/web/app/src/components/target/explorer/object-type.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FragmentType, graphql, useFragment } from '@/gql';
import { useRouter } from '@tanstack/react-router';
import { GraphQLFields, GraphQLTypeCard } from './common';
import { GraphQLTypeCard } from './common';
import { GraphQLFields } from './graphql-fields';

const GraphQLObjectTypeComponent_TypeFragment = graphql(`
fragment GraphQLObjectTypeComponent_TypeFragment on GraphQLObjectType {
Expand All @@ -22,7 +22,6 @@ const GraphQLObjectTypeComponent_TypeFragment = graphql(`
export function GraphQLObjectTypeComponent(props: {
type: FragmentType<typeof GraphQLObjectTypeComponent_TypeFragment>;
totalRequests?: number;
collapsed?: boolean;
organizationSlug: string;
projectSlug: string;
targetSlug: string;
Expand All @@ -31,12 +30,6 @@ export function GraphQLObjectTypeComponent(props: {
styleDeprecated: boolean;
}) {
const ttype = useFragment(GraphQLObjectTypeComponent_TypeFragment, props.type);
const router = useRouter();
const searchObj = router.latestLocation.search;
const search =
'search' in searchObj && typeof searchObj.search === 'string'
? searchObj.search.toLowerCase()
: undefined;

return (
<GraphQLTypeCard
Expand All @@ -52,9 +45,7 @@ export function GraphQLObjectTypeComponent(props: {
<GraphQLFields
typeName={ttype.name}
fields={ttype.fields}
filterValue={search}
totalRequests={props.totalRequests}
collapsed={props.collapsed}
targetSlug={props.targetSlug}
projectSlug={props.projectSlug}
organizationSlug={props.organizationSlug}
Expand Down
Loading
Loading