mirror of
https://github.com/graphql-hive/console
synced 2026-05-24 01:28:32 +00:00
Add {Organization,Project,Target}Layout level query to improve UX (#4780)
This commit is contained in:
parent
90d785968c
commit
28148130e2
40 changed files with 501 additions and 856 deletions
|
|
@ -0,0 +1,57 @@
|
|||
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select';
|
||||
import { FragmentType, graphql, useFragment } from '@/gql';
|
||||
import { useRouter } from '@tanstack/react-router';
|
||||
|
||||
const OrganizationSelector_OrganizationConnectionFragment = graphql(`
|
||||
fragment OrganizationSelector_OrganizationConnectionFragment on OrganizationConnection {
|
||||
nodes {
|
||||
id
|
||||
name
|
||||
cleanId
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
export function OrganizationSelector(props: {
|
||||
currentOrganizationCleanId: string;
|
||||
organizations: FragmentType<typeof OrganizationSelector_OrganizationConnectionFragment> | null;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
const organizations = useFragment(
|
||||
OrganizationSelector_OrganizationConnectionFragment,
|
||||
props.organizations,
|
||||
)?.nodes;
|
||||
|
||||
const currentOrganization = organizations?.find(
|
||||
node => node.cleanId === props.currentOrganizationCleanId,
|
||||
);
|
||||
|
||||
return organizations ? (
|
||||
<Select
|
||||
value={props.currentOrganizationCleanId}
|
||||
onValueChange={id => {
|
||||
void router.navigate({
|
||||
to: '/$organizationId',
|
||||
params: {
|
||||
organizationId: id,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
<SelectTrigger variant="default">
|
||||
<div className="font-medium" data-cy="organization-picker-current">
|
||||
{currentOrganization?.name}
|
||||
</div>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{organizations.map(org => (
|
||||
<SelectItem key={org.cleanId} value={org.cleanId}>
|
||||
{org.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
) : (
|
||||
<div className="h-5 w-48 animate-pulse rounded-full bg-gray-800" />
|
||||
);
|
||||
}
|
||||
|
|
@ -1,12 +1,12 @@
|
|||
import { ReactElement, ReactNode } from 'react';
|
||||
import { useQuery } from 'urql';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select';
|
||||
import { UserMenu } from '@/components/ui/user-menu';
|
||||
import { HiveLink, Tabs } from '@/components/v2';
|
||||
import { PlusIcon } from '@/components/v2/icon';
|
||||
import { CreateProjectModal } from '@/components/v2/modals';
|
||||
import { env } from '@/env/frontend';
|
||||
import { FragmentType, graphql, useFragment } from '@/gql';
|
||||
import { graphql, useFragment } from '@/gql';
|
||||
import {
|
||||
canAccessOrganization,
|
||||
OrganizationAccessScope,
|
||||
|
|
@ -15,9 +15,11 @@ import {
|
|||
import { getIsStripeEnabled } from '@/lib/billing/stripe-public-key';
|
||||
import { useToggle } from '@/lib/hooks';
|
||||
import { useLastVisitedOrganizationWriter } from '@/lib/last-visited-org';
|
||||
import { Link, useRouter } from '@tanstack/react-router';
|
||||
import { Link } from '@tanstack/react-router';
|
||||
import { ProPlanBilling } from '../organization/billing/ProPlanBillingWarm';
|
||||
import { RateLimitWarn } from '../organization/billing/RateLimitWarn';
|
||||
import { QueryError } from '../ui/query-error';
|
||||
import { OrganizationSelector } from './organization-selectors';
|
||||
|
||||
export enum Page {
|
||||
Overview = 'overview',
|
||||
|
|
@ -28,35 +30,31 @@ export enum Page {
|
|||
Subscription = 'subscription',
|
||||
}
|
||||
|
||||
const OrganizationLayout_CurrentOrganizationFragment = graphql(`
|
||||
fragment OrganizationLayout_CurrentOrganizationFragment on Organization {
|
||||
export const OrganizationLayout_OrganizationFragment = graphql(`
|
||||
fragment OrganizationLayout_OrganizationFragment on Organization {
|
||||
id
|
||||
name
|
||||
cleanId
|
||||
me {
|
||||
...CanAccessOrganization_MemberFragment
|
||||
}
|
||||
...ProPlanBilling_OrganizationFragment
|
||||
...RateLimitWarn_OrganizationFragment
|
||||
...UserMenu_CurrentOrganizationFragment
|
||||
}
|
||||
`);
|
||||
|
||||
const OrganizationLayout_MeFragment = graphql(`
|
||||
fragment OrganizationLayout_MeFragment on User {
|
||||
id
|
||||
...UserMenu_MeFragment
|
||||
}
|
||||
`);
|
||||
|
||||
const OrganizationLayout_OrganizationConnectionFragment = graphql(`
|
||||
fragment OrganizationLayout_OrganizationConnectionFragment on OrganizationConnection {
|
||||
nodes {
|
||||
const OrganizationLayoutQuery = graphql(`
|
||||
query OrganizationLayoutQuery {
|
||||
me {
|
||||
id
|
||||
cleanId
|
||||
name
|
||||
...UserMenu_MeFragment
|
||||
}
|
||||
organizations {
|
||||
...OrganizationSelector_OrganizationConnectionFragment
|
||||
...UserMenu_OrganizationConnectionFragment
|
||||
nodes {
|
||||
...OrganizationLayout_OrganizationFragment
|
||||
}
|
||||
}
|
||||
...UserMenu_OrganizationConnectionFragment
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -68,19 +66,20 @@ export function OrganizationLayout({
|
|||
}: {
|
||||
page?: Page;
|
||||
className?: string;
|
||||
me: FragmentType<typeof OrganizationLayout_MeFragment> | null;
|
||||
organizationId: string;
|
||||
currentOrganization: FragmentType<typeof OrganizationLayout_CurrentOrganizationFragment> | null;
|
||||
organizations: FragmentType<typeof OrganizationLayout_OrganizationConnectionFragment> | null;
|
||||
children: ReactNode;
|
||||
}): ReactElement | null {
|
||||
const router = useRouter();
|
||||
const [isModalOpen, toggleModalOpen] = useToggle();
|
||||
const [query] = useQuery({
|
||||
query: OrganizationLayoutQuery,
|
||||
requestPolicy: 'cache-first',
|
||||
});
|
||||
|
||||
const currentOrganization = useFragment(
|
||||
OrganizationLayout_CurrentOrganizationFragment,
|
||||
props.currentOrganization,
|
||||
const organizations = useFragment(
|
||||
OrganizationLayout_OrganizationFragment,
|
||||
query.data?.organizations.nodes,
|
||||
);
|
||||
const currentOrganization = organizations?.find(org => org.cleanId === props.organizationId);
|
||||
|
||||
useOrganizationAccess({
|
||||
member: currentOrganization?.me ?? null,
|
||||
|
|
@ -92,12 +91,10 @@ export function OrganizationLayout({
|
|||
useLastVisitedOrganizationWriter(currentOrganization?.cleanId);
|
||||
|
||||
const meInCurrentOrg = currentOrganization?.me;
|
||||
const me = useFragment(OrganizationLayout_MeFragment, props.me);
|
||||
const organizationConnection = useFragment(
|
||||
OrganizationLayout_OrganizationConnectionFragment,
|
||||
props.organizations,
|
||||
);
|
||||
const organizations = organizationConnection?.nodes;
|
||||
|
||||
if (query.error) {
|
||||
return <QueryError error={query.error} organizationId={props.organizationId} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
|
|
@ -105,40 +102,16 @@ export function OrganizationLayout({
|
|||
<div className="container flex h-[84px] items-center justify-between">
|
||||
<div className="flex flex-row items-center gap-4">
|
||||
<HiveLink className="size-8" />
|
||||
{currentOrganization && organizations ? (
|
||||
<Select
|
||||
defaultValue={currentOrganization.cleanId}
|
||||
onValueChange={id => {
|
||||
void router.navigate({
|
||||
to: '/$organizationId',
|
||||
params: {
|
||||
organizationId: id,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
<SelectTrigger variant="default">
|
||||
<div className="font-medium" data-cy="organization-picker-current">
|
||||
{currentOrganization.name}
|
||||
</div>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{organizations.map(org => (
|
||||
<SelectItem key={org.cleanId} value={org.cleanId}>
|
||||
{org.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
) : (
|
||||
<div className="h-5 w-48 animate-pulse rounded-full bg-gray-800" />
|
||||
)}
|
||||
<OrganizationSelector
|
||||
currentOrganizationCleanId={props.organizationId}
|
||||
organizations={query.data?.organizations ?? null}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<UserMenu
|
||||
me={me ?? null}
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
me={query.data?.me ?? null}
|
||||
currentOrganizationCleanId={props.organizationId}
|
||||
organizations={query.data?.organizations ?? null}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
86
packages/web/app/src/components/layouts/project-selector.tsx
Normal file
86
packages/web/app/src/components/layouts/project-selector.tsx
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select';
|
||||
import { FragmentType, graphql, useFragment } from '@/gql';
|
||||
import { Link, useRouter } from '@tanstack/react-router';
|
||||
|
||||
const ProjectSelector_OrganizationConnectionFragment = graphql(`
|
||||
fragment ProjectSelector_OrganizationConnectionFragment on OrganizationConnection {
|
||||
nodes {
|
||||
id
|
||||
name
|
||||
cleanId
|
||||
projects {
|
||||
nodes {
|
||||
id
|
||||
name
|
||||
cleanId
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
export function ProjectSelector(props: {
|
||||
currentOrganizationCleanId: string;
|
||||
currentProjectCleanId: string;
|
||||
organizations: FragmentType<typeof ProjectSelector_OrganizationConnectionFragment> | null;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
|
||||
const organizations = useFragment(
|
||||
ProjectSelector_OrganizationConnectionFragment,
|
||||
props.organizations,
|
||||
)?.nodes;
|
||||
|
||||
const currentOrganization = organizations?.find(
|
||||
node => node.cleanId === props.currentOrganizationCleanId,
|
||||
);
|
||||
|
||||
const projects = currentOrganization?.projects.nodes;
|
||||
const currentProject = projects?.find(node => node.cleanId === props.currentProjectCleanId);
|
||||
|
||||
return (
|
||||
<>
|
||||
{currentOrganization ? (
|
||||
<Link
|
||||
to="/$organizationId"
|
||||
params={{ organizationId: props.currentOrganizationCleanId }}
|
||||
className="max-w-[200px] shrink-0 truncate font-medium"
|
||||
>
|
||||
{currentOrganization.name}
|
||||
</Link>
|
||||
) : (
|
||||
<div className="h-5 w-48 max-w-[200px] animate-pulse rounded-full bg-gray-800" />
|
||||
)}
|
||||
{projects?.length && currentProject ? (
|
||||
<>
|
||||
<div className="italic text-gray-500">/</div>
|
||||
<Select
|
||||
value={props.currentProjectCleanId}
|
||||
onValueChange={id => {
|
||||
void router.navigate({
|
||||
to: '/$organizationId/$projectId',
|
||||
params: {
|
||||
organizationId: props.currentOrganizationCleanId,
|
||||
projectId: id,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
<SelectTrigger variant="default">
|
||||
<div className="font-medium">{currentProject.name}</div>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{projects.map(project => (
|
||||
<SelectItem key={project.cleanId} value={project.cleanId}>
|
||||
{project.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</>
|
||||
) : (
|
||||
<div className="h-5 w-48 animate-pulse rounded-full bg-gray-800" />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,16 +1,17 @@
|
|||
import { ReactElement, ReactNode } from 'react';
|
||||
import { useQuery } from 'urql';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select';
|
||||
import { UserMenu } from '@/components/ui/user-menu';
|
||||
import { HiveLink, Tabs } from '@/components/v2';
|
||||
import { PlusIcon } from '@/components/v2/icon';
|
||||
import { CreateTargetModal } from '@/components/v2/modals';
|
||||
import { FragmentType, graphql, useFragment } from '@/gql';
|
||||
import { graphql } from '@/gql';
|
||||
import { canAccessProject, ProjectAccessScope, useProjectAccess } from '@/lib/access/project';
|
||||
import { useToggle } from '@/lib/hooks';
|
||||
import { useLastVisitedOrganizationWriter } from '@/lib/last-visited-org';
|
||||
import { Link, useRouter } from '@tanstack/react-router';
|
||||
import { Link } from '@tanstack/react-router';
|
||||
import { ProjectMigrationToast } from '../project/migration-toast';
|
||||
import { ProjectSelector } from './project-selector';
|
||||
|
||||
export enum Page {
|
||||
Targets = 'targets',
|
||||
|
|
@ -19,54 +20,32 @@ export enum Page {
|
|||
Settings = 'settings',
|
||||
}
|
||||
|
||||
const ProjectLayout_CurrentOrganizationFragment = graphql(`
|
||||
fragment ProjectLayout_CurrentOrganizationFragment on Organization {
|
||||
id
|
||||
name
|
||||
cleanId
|
||||
const ProjectLayoutQuery = graphql(`
|
||||
query ProjectLayoutQuery {
|
||||
me {
|
||||
...CanAccessProject_MemberFragment
|
||||
}
|
||||
...UserMenu_CurrentOrganizationFragment
|
||||
projects {
|
||||
...ProjectLayout_ProjectConnectionFragment
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
const ProjectLayout_MeFragment = graphql(`
|
||||
fragment ProjectLayout_MeFragment on User {
|
||||
id
|
||||
...UserMenu_MeFragment
|
||||
}
|
||||
`);
|
||||
|
||||
const ProjectLayout_OrganizationConnectionFragment = graphql(`
|
||||
fragment ProjectLayout_OrganizationConnectionFragment on OrganizationConnection {
|
||||
nodes {
|
||||
id
|
||||
cleanId
|
||||
name
|
||||
...UserMenu_MeFragment
|
||||
}
|
||||
...UserMenu_OrganizationConnectionFragment
|
||||
}
|
||||
`);
|
||||
|
||||
const ProjectLayout_CurrentProjectFragment = graphql(`
|
||||
fragment ProjectLayout_CurrentProjectFragment on Project {
|
||||
id
|
||||
cleanId
|
||||
name
|
||||
registryModel
|
||||
}
|
||||
`);
|
||||
|
||||
const ProjectLayout_ProjectConnectionFragment = graphql(`
|
||||
fragment ProjectLayout_ProjectConnectionFragment on ProjectConnection {
|
||||
nodes {
|
||||
id
|
||||
cleanId
|
||||
name
|
||||
organizations {
|
||||
nodes {
|
||||
id
|
||||
cleanId
|
||||
name
|
||||
me {
|
||||
id
|
||||
...CanAccessProject_MemberFragment
|
||||
}
|
||||
projects {
|
||||
nodes {
|
||||
id
|
||||
cleanId
|
||||
name
|
||||
registryModel
|
||||
}
|
||||
}
|
||||
}
|
||||
...ProjectSelector_OrganizationConnectionFragment
|
||||
...UserMenu_OrganizationConnectionFragment
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
|
@ -81,20 +60,21 @@ export function ProjectLayout({
|
|||
organizationId: string;
|
||||
projectId: string;
|
||||
className?: string;
|
||||
me: FragmentType<typeof ProjectLayout_MeFragment> | null;
|
||||
currentOrganization: FragmentType<typeof ProjectLayout_CurrentOrganizationFragment> | null;
|
||||
currentProject: FragmentType<typeof ProjectLayout_CurrentProjectFragment> | null;
|
||||
organizations: FragmentType<typeof ProjectLayout_OrganizationConnectionFragment> | null;
|
||||
children: ReactNode;
|
||||
}): ReactElement | null {
|
||||
const router = useRouter();
|
||||
const [isModalOpen, toggleModalOpen] = useToggle();
|
||||
const [query] = useQuery({
|
||||
query: ProjectLayoutQuery,
|
||||
requestPolicy: 'cache-first',
|
||||
});
|
||||
|
||||
const currentOrganization = useFragment(
|
||||
ProjectLayout_CurrentOrganizationFragment,
|
||||
props.currentOrganization,
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organizations.nodes.find(
|
||||
node => node.cleanId === props.organizationId,
|
||||
);
|
||||
const currentProject = currentOrganization?.projects.nodes.find(
|
||||
node => node.cleanId === props.projectId,
|
||||
);
|
||||
const currentProject = useFragment(ProjectLayout_CurrentProjectFragment, props.currentProject);
|
||||
|
||||
useProjectAccess({
|
||||
scope: ProjectAccessScope.Read,
|
||||
|
|
@ -106,70 +86,23 @@ export function ProjectLayout({
|
|||
|
||||
useLastVisitedOrganizationWriter(currentOrganization?.cleanId);
|
||||
|
||||
const me = useFragment(ProjectLayout_MeFragment, props.me);
|
||||
const organizationConnection = useFragment(
|
||||
ProjectLayout_OrganizationConnectionFragment,
|
||||
props.organizations,
|
||||
);
|
||||
const projectConnection = useFragment(
|
||||
ProjectLayout_ProjectConnectionFragment,
|
||||
currentOrganization?.projects ?? null,
|
||||
);
|
||||
const projects = projectConnection?.nodes;
|
||||
|
||||
return (
|
||||
<>
|
||||
<header>
|
||||
<div className="container flex h-[84px] items-center justify-between">
|
||||
<div className="flex flex-row items-center gap-4">
|
||||
<HiveLink className="size-8" />
|
||||
{currentOrganization ? (
|
||||
<Link
|
||||
to="/$organizationId"
|
||||
params={{ organizationId: currentOrganization.cleanId }}
|
||||
className="max-w-[200px] shrink-0 truncate font-medium"
|
||||
>
|
||||
{currentOrganization.name}
|
||||
</Link>
|
||||
) : (
|
||||
<div className="h-5 w-48 max-w-[200px] animate-pulse rounded-full bg-gray-800" />
|
||||
)}
|
||||
{projects?.length && currentProject ? (
|
||||
<>
|
||||
<div className="italic text-gray-500">/</div>
|
||||
<Select
|
||||
defaultValue={currentProject.cleanId}
|
||||
onValueChange={id => {
|
||||
void router.navigate({
|
||||
to: '/$organizationId/$projectId',
|
||||
params: {
|
||||
organizationId: props.organizationId,
|
||||
projectId: id,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
<SelectTrigger variant="default">
|
||||
<div className="font-medium">{currentProject.name}</div>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{projects.map(project => (
|
||||
<SelectItem key={project.cleanId} value={project.cleanId}>
|
||||
{project.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</>
|
||||
) : (
|
||||
<div className="h-5 w-48 animate-pulse rounded-full bg-gray-800" />
|
||||
)}
|
||||
<ProjectSelector
|
||||
currentOrganizationCleanId={props.organizationId}
|
||||
currentProjectCleanId={props.projectId}
|
||||
organizations={query.data?.organizations ?? null}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<UserMenu
|
||||
me={me ?? null}
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
currentOrganizationCleanId={props.organizationId}
|
||||
organizations={query.data?.organizations ?? null}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
123
packages/web/app/src/components/layouts/target-selector.tsx
Normal file
123
packages/web/app/src/components/layouts/target-selector.tsx
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select';
|
||||
import { FragmentType, graphql, useFragment } from '@/gql';
|
||||
import { Link, useRouter } from '@tanstack/react-router';
|
||||
|
||||
const TargetSelector_OrganizationConnectionFragment = graphql(`
|
||||
fragment TargetSelector_OrganizationConnectionFragment on OrganizationConnection {
|
||||
nodes {
|
||||
id
|
||||
name
|
||||
cleanId
|
||||
projects {
|
||||
nodes {
|
||||
id
|
||||
name
|
||||
cleanId
|
||||
targets {
|
||||
nodes {
|
||||
id
|
||||
name
|
||||
cleanId
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
export function TargetSelector(props: {
|
||||
currentOrganizationCleanId: string;
|
||||
currentProjectCleanId: string;
|
||||
currentTargetCleanId: string;
|
||||
organizations: FragmentType<typeof TargetSelector_OrganizationConnectionFragment> | null;
|
||||
}) {
|
||||
const router = useRouter();
|
||||
|
||||
const organizations = useFragment(
|
||||
TargetSelector_OrganizationConnectionFragment,
|
||||
props.organizations,
|
||||
)?.nodes;
|
||||
|
||||
const currentOrganization = organizations?.find(
|
||||
node => node.cleanId === props.currentOrganizationCleanId,
|
||||
);
|
||||
|
||||
const projects = currentOrganization?.projects.nodes;
|
||||
const currentProject = projects?.find(node => node.cleanId === props.currentProjectCleanId);
|
||||
|
||||
const targets = currentProject?.targets.nodes;
|
||||
const currentTarget = targets?.find(node => node.cleanId === props.currentTargetCleanId);
|
||||
|
||||
console.log({
|
||||
organizations,
|
||||
props,
|
||||
currentOrganization,
|
||||
currentProject,
|
||||
currentTarget,
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
{currentOrganization ? (
|
||||
<Link
|
||||
to="/$organizationId"
|
||||
params={{
|
||||
organizationId: currentOrganization.cleanId,
|
||||
}}
|
||||
className="max-w-[200px] shrink-0 truncate font-medium"
|
||||
>
|
||||
{currentOrganization.name}
|
||||
</Link>
|
||||
) : (
|
||||
<div className="h-5 w-48 max-w-[200px] animate-pulse rounded-full bg-gray-800" />
|
||||
)}
|
||||
<div className="italic text-gray-500">/</div>
|
||||
{currentOrganization && currentProject ? (
|
||||
<Link
|
||||
to="/$organizationId/$projectId"
|
||||
params={{
|
||||
organizationId: props.currentOrganizationCleanId,
|
||||
projectId: props.currentProjectCleanId,
|
||||
}}
|
||||
className="max-w-[200px] shrink-0 truncate font-medium"
|
||||
>
|
||||
{currentProject.name}
|
||||
</Link>
|
||||
) : (
|
||||
<div className="h-5 w-48 max-w-[200px] animate-pulse rounded-full bg-gray-800" />
|
||||
)}
|
||||
<div className="italic text-gray-500">/</div>
|
||||
{targets?.length && currentOrganization && currentProject && currentTarget ? (
|
||||
<>
|
||||
<Select
|
||||
value={props.currentTargetCleanId}
|
||||
onValueChange={id => {
|
||||
void router.navigate({
|
||||
to: '/$organizationId/$projectId/$targetId',
|
||||
params: {
|
||||
organizationId: props.currentOrganizationCleanId,
|
||||
projectId: props.currentProjectCleanId,
|
||||
targetId: id,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
<SelectTrigger variant="default">
|
||||
<div className="font-medium">{currentTarget.name}</div>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{targets.map(target => (
|
||||
<SelectItem key={target.cleanId} value={target.cleanId}>
|
||||
{target.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</>
|
||||
) : (
|
||||
<div className="h-5 w-48 max-w-[200px] animate-pulse rounded-full bg-gray-800" />
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,17 +1,18 @@
|
|||
import { ReactElement, ReactNode } from 'react';
|
||||
import { LinkIcon } from 'lucide-react';
|
||||
import { useQuery } from 'urql';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select';
|
||||
import { UserMenu } from '@/components/ui/user-menu';
|
||||
import { HiveLink, Tabs } from '@/components/v2';
|
||||
import { ConnectSchemaModal } from '@/components/v2/modals';
|
||||
import { FragmentType, graphql, useFragment } from '@/gql';
|
||||
import { graphql } from '@/gql';
|
||||
import { canAccessTarget, TargetAccessScope, useTargetAccess } from '@/lib/access/target';
|
||||
import { useToggle } from '@/lib/hooks';
|
||||
import { useLastVisitedOrganizationWriter } from '@/lib/last-visited-org';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { Link, useRouter } from '@tanstack/react-router';
|
||||
import { Link } from '@tanstack/react-router';
|
||||
import { ProjectMigrationToast } from '../project/migration-toast';
|
||||
import { TargetSelector } from './target-selector';
|
||||
|
||||
export enum Page {
|
||||
Schema = 'schema',
|
||||
|
|
@ -23,64 +24,40 @@ export enum Page {
|
|||
Settings = 'settings',
|
||||
}
|
||||
|
||||
const TargetLayout_CurrentOrganizationFragment = graphql(`
|
||||
fragment TargetLayout_CurrentOrganizationFragment on Organization {
|
||||
id
|
||||
name
|
||||
cleanId
|
||||
const TargetLayoutQuery = graphql(`
|
||||
query TargetLayoutQuery {
|
||||
me {
|
||||
id
|
||||
...CanAccessTarget_MemberFragment
|
||||
...UserMenu_MeFragment
|
||||
}
|
||||
...UserMenu_CurrentOrganizationFragment
|
||||
projects {
|
||||
...ProjectLayout_ProjectConnectionFragment
|
||||
organizations {
|
||||
nodes {
|
||||
id
|
||||
cleanId
|
||||
name
|
||||
me {
|
||||
id
|
||||
...CanAccessTarget_MemberFragment
|
||||
}
|
||||
projects {
|
||||
nodes {
|
||||
id
|
||||
cleanId
|
||||
name
|
||||
registryModel
|
||||
targets {
|
||||
nodes {
|
||||
id
|
||||
cleanId
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
...TargetSelector_OrganizationConnectionFragment
|
||||
...UserMenu_OrganizationConnectionFragment
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
const TargetLayout_MeFragment = graphql(`
|
||||
fragment TargetLayout_MeFragment on User {
|
||||
id
|
||||
...UserMenu_MeFragment
|
||||
}
|
||||
`);
|
||||
|
||||
const TargetLayout_OrganizationConnectionFragment = graphql(`
|
||||
fragment TargetLayout_OrganizationConnectionFragment on OrganizationConnection {
|
||||
nodes {
|
||||
id
|
||||
cleanId
|
||||
name
|
||||
}
|
||||
...UserMenu_OrganizationConnectionFragment
|
||||
}
|
||||
`);
|
||||
|
||||
const TargetLayout_CurrentProjectFragment = graphql(`
|
||||
fragment TargetLayout_CurrentProjectFragment on Project {
|
||||
id
|
||||
cleanId
|
||||
name
|
||||
registryModel
|
||||
targets {
|
||||
...TargetLayout_TargetConnectionFragment
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
const TargetLayout_TargetConnectionFragment = graphql(`
|
||||
fragment TargetLayout_TargetConnectionFragment on TargetConnection {
|
||||
total
|
||||
nodes {
|
||||
cleanId
|
||||
name
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
const TargetLayout_IsCDNEnabledFragment = graphql(`
|
||||
fragment TargetLayout_IsCDNEnabledFragment on Query {
|
||||
isCDNEnabled
|
||||
}
|
||||
`);
|
||||
|
|
@ -99,35 +76,24 @@ export const TargetLayout = ({
|
|||
className?: string;
|
||||
children: ReactNode;
|
||||
connect?: ReactNode;
|
||||
me: FragmentType<typeof TargetLayout_MeFragment> | null;
|
||||
currentOrganization: FragmentType<typeof TargetLayout_CurrentOrganizationFragment> | null;
|
||||
currentProject: FragmentType<typeof TargetLayout_CurrentProjectFragment> | null;
|
||||
organizations: FragmentType<typeof TargetLayout_OrganizationConnectionFragment> | null;
|
||||
isCDNEnabled: FragmentType<typeof TargetLayout_IsCDNEnabledFragment> | null;
|
||||
}): ReactElement | null => {
|
||||
const router = useRouter();
|
||||
const [isModalOpen, toggleModalOpen] = useToggle();
|
||||
const [query] = useQuery({
|
||||
query: TargetLayoutQuery,
|
||||
requestPolicy: 'cache-first',
|
||||
});
|
||||
|
||||
const { organizationId: orgId, projectId } = props;
|
||||
|
||||
const currentOrganization = useFragment(
|
||||
TargetLayout_CurrentOrganizationFragment,
|
||||
props.currentOrganization,
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organizations.nodes.find(
|
||||
node => node.cleanId === props.organizationId,
|
||||
);
|
||||
const currentProject = useFragment(TargetLayout_CurrentProjectFragment, props.currentProject);
|
||||
|
||||
const me = useFragment(TargetLayout_MeFragment, props.me);
|
||||
const organizationConnection = useFragment(
|
||||
TargetLayout_OrganizationConnectionFragment,
|
||||
props.organizations,
|
||||
const currentProject = currentOrganization?.projects.nodes.find(
|
||||
node => node.cleanId === props.projectId,
|
||||
);
|
||||
const targetConnection = useFragment(
|
||||
TargetLayout_TargetConnectionFragment,
|
||||
currentProject?.targets,
|
||||
);
|
||||
const targets = targetConnection?.nodes;
|
||||
const currentTarget = targets?.find(target => target.cleanId === props.targetId);
|
||||
const isCDNEnabled = useFragment(TargetLayout_IsCDNEnabledFragment, props.isCDNEnabled);
|
||||
const currentTarget = currentProject?.targets.nodes.find(node => node.cleanId === props.targetId);
|
||||
const isCDNEnabled = query.data?.isCDNEnabled === true;
|
||||
|
||||
useTargetAccess({
|
||||
scope: TargetAccessScope.Read,
|
||||
|
|
@ -155,71 +121,18 @@ export const TargetLayout = ({
|
|||
<div className="container flex h-[84px] items-center justify-between">
|
||||
<div className="flex flex-row items-center gap-4">
|
||||
<HiveLink className="size-8" />
|
||||
{currentOrganization ? (
|
||||
<Link
|
||||
to="/$organizationId"
|
||||
params={{
|
||||
organizationId: currentOrganization.cleanId,
|
||||
}}
|
||||
className="max-w-[200px] shrink-0 truncate font-medium"
|
||||
>
|
||||
{currentOrganization.name}
|
||||
</Link>
|
||||
) : (
|
||||
<div className="h-5 w-48 max-w-[200px] animate-pulse rounded-full bg-gray-800" />
|
||||
)}
|
||||
<div className="italic text-gray-500">/</div>
|
||||
{currentOrganization && currentProject ? (
|
||||
<Link
|
||||
to="/$organizationId/$projectId"
|
||||
params={{
|
||||
organizationId: currentOrganization.cleanId,
|
||||
projectId: currentProject.cleanId,
|
||||
}}
|
||||
className="max-w-[200px] shrink-0 truncate font-medium"
|
||||
>
|
||||
{currentProject.name}
|
||||
</Link>
|
||||
) : (
|
||||
<div className="h-5 w-48 max-w-[200px] animate-pulse rounded-full bg-gray-800" />
|
||||
)}
|
||||
<div className="italic text-gray-500">/</div>
|
||||
{targets?.length && currentOrganization && currentProject && currentTarget ? (
|
||||
<>
|
||||
<Select
|
||||
defaultValue={currentTarget.cleanId}
|
||||
onValueChange={id => {
|
||||
void router.navigate({
|
||||
to: '/$organizationId/$projectId/$targetId',
|
||||
params: {
|
||||
organizationId: currentOrganization.cleanId,
|
||||
projectId: currentProject.cleanId,
|
||||
targetId: id,
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
<SelectTrigger variant="default">
|
||||
<div className="font-medium">{currentTarget.name}</div>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{targets.map(target => (
|
||||
<SelectItem key={target.cleanId} value={target.cleanId}>
|
||||
{target.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</>
|
||||
) : (
|
||||
<div className="h-5 w-48 max-w-[200px] animate-pulse rounded-full bg-gray-800" />
|
||||
)}
|
||||
<TargetSelector
|
||||
organizations={query.data?.organizations ?? null}
|
||||
currentOrganizationCleanId={props.organizationId}
|
||||
currentProjectCleanId={props.projectId}
|
||||
currentTargetCleanId={props.targetId}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<UserMenu
|
||||
me={me ?? null}
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
currentOrganizationCleanId={props.organizationId}
|
||||
organizations={query.data?.organizations ?? null}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -240,9 +153,9 @@ export const TargetLayout = ({
|
|||
<Link
|
||||
to="/$organizationId/$projectId/$targetId"
|
||||
params={{
|
||||
organizationId: currentOrganization.cleanId,
|
||||
projectId: currentProject.cleanId,
|
||||
targetId: currentTarget.cleanId,
|
||||
organizationId: props.organizationId,
|
||||
projectId: props.projectId,
|
||||
targetId: props.targetId,
|
||||
}}
|
||||
>
|
||||
Schema
|
||||
|
|
@ -252,9 +165,9 @@ export const TargetLayout = ({
|
|||
<Link
|
||||
to="/$organizationId/$projectId/$targetId/checks"
|
||||
params={{
|
||||
organizationId: currentOrganization.cleanId,
|
||||
projectId: currentProject.cleanId,
|
||||
targetId: currentTarget.cleanId,
|
||||
organizationId: props.organizationId,
|
||||
projectId: props.projectId,
|
||||
targetId: props.targetId,
|
||||
}}
|
||||
>
|
||||
Checks
|
||||
|
|
@ -264,9 +177,9 @@ export const TargetLayout = ({
|
|||
<Link
|
||||
to="/$organizationId/$projectId/$targetId/explorer"
|
||||
params={{
|
||||
organizationId: currentOrganization.cleanId,
|
||||
projectId: currentProject.cleanId,
|
||||
targetId: currentTarget.cleanId,
|
||||
organizationId: props.organizationId,
|
||||
projectId: props.projectId,
|
||||
targetId: props.targetId,
|
||||
}}
|
||||
>
|
||||
Explorer
|
||||
|
|
@ -288,9 +201,9 @@ export const TargetLayout = ({
|
|||
<Link
|
||||
to="/$organizationId/$projectId/$targetId/insights"
|
||||
params={{
|
||||
organizationId: currentOrganization.cleanId,
|
||||
projectId: currentProject.cleanId,
|
||||
targetId: currentTarget.cleanId,
|
||||
organizationId: props.organizationId,
|
||||
projectId: props.projectId,
|
||||
targetId: props.targetId,
|
||||
}}
|
||||
>
|
||||
Insights
|
||||
|
|
@ -300,9 +213,9 @@ export const TargetLayout = ({
|
|||
<Link
|
||||
to="/$organizationId/$projectId/$targetId/laboratory"
|
||||
params={{
|
||||
organizationId: currentOrganization.cleanId,
|
||||
projectId: currentProject.cleanId,
|
||||
targetId: currentTarget.cleanId,
|
||||
organizationId: props.organizationId,
|
||||
projectId: props.projectId,
|
||||
targetId: props.targetId,
|
||||
}}
|
||||
>
|
||||
Laboratory
|
||||
|
|
@ -315,9 +228,9 @@ export const TargetLayout = ({
|
|||
<Link
|
||||
to="/$organizationId/$projectId/$targetId/settings"
|
||||
params={{
|
||||
organizationId: currentOrganization.cleanId,
|
||||
projectId: currentProject.cleanId,
|
||||
targetId: currentTarget.cleanId,
|
||||
organizationId: props.organizationId,
|
||||
projectId: props.projectId,
|
||||
targetId: props.targetId,
|
||||
}}
|
||||
>
|
||||
Settings
|
||||
|
|
@ -336,7 +249,7 @@ export const TargetLayout = ({
|
|||
{currentTarget ? (
|
||||
connect != null ? (
|
||||
connect
|
||||
) : isCDNEnabled?.isCDNEnabled ? (
|
||||
) : isCDNEnabled ? (
|
||||
<>
|
||||
<Button onClick={toggleModalOpen} variant="link" className="text-orange-500">
|
||||
<LinkIcon size={16} className="mr-2" />
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ const NumericFormatter = Intl.NumberFormat('en', { notation: 'standard' });
|
|||
|
||||
const OrganizationUsageEstimationView_OrganizationFragment = graphql(`
|
||||
fragment OrganizationUsageEstimationView_OrganizationFragment on Organization {
|
||||
id
|
||||
cleanId
|
||||
rateLimit {
|
||||
operations
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ import { PlanSummary } from './PlanSummary';
|
|||
|
||||
const BillingView_OrganizationFragment = graphql(`
|
||||
fragment BillingView_OrganizationFragment on Organization {
|
||||
id
|
||||
cleanId
|
||||
plan
|
||||
rateLimit {
|
||||
retentionInDays
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import { CurrencyFormatter, DateFormatter } from './helpers';
|
|||
|
||||
const OrganizationInvoicesList_OrganizationFragment = graphql(`
|
||||
fragment OrganizationInvoicesList_OrganizationFragment on Organization {
|
||||
id
|
||||
cleanId
|
||||
billingConfiguration {
|
||||
hasPaymentIssues
|
||||
invoices {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@ import { BillingPlanType } from '@/gql/graphql';
|
|||
|
||||
const RateLimitWarn_OrganizationFragment = graphql(`
|
||||
fragment RateLimitWarn_OrganizationFragment on Organization {
|
||||
id
|
||||
cleanId
|
||||
name
|
||||
plan
|
||||
rateLimit {
|
||||
|
|
|
|||
|
|
@ -37,27 +37,19 @@ import { UserSettingsModal } from '../user/settings';
|
|||
import { Changelog } from './changelog/changelog';
|
||||
import { latestChangelog } from './changelog/generated-changelog';
|
||||
|
||||
export const UserMenu_CurrentOrganizationFragment = graphql(`
|
||||
fragment UserMenu_CurrentOrganizationFragment on Organization {
|
||||
id
|
||||
cleanId
|
||||
name
|
||||
getStarted {
|
||||
...GetStartedWizard_GetStartedProgress
|
||||
}
|
||||
me {
|
||||
...UserMenu_MemberFragment
|
||||
}
|
||||
...MemberRoleMigrationStickyNote_OrganizationFragment
|
||||
}
|
||||
`);
|
||||
|
||||
export const UserMenu_OrganizationConnectionFragment = graphql(`
|
||||
fragment UserMenu_OrganizationConnectionFragment on OrganizationConnection {
|
||||
nodes {
|
||||
id
|
||||
cleanId
|
||||
name
|
||||
me {
|
||||
...UserMenu_MemberFragment
|
||||
}
|
||||
getStarted {
|
||||
...GetStartedWizard_GetStartedProgress
|
||||
}
|
||||
...MemberRoleMigrationStickyNote_OrganizationFragment
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
|
@ -66,7 +58,6 @@ export const UserMenu_MeFragment = graphql(`
|
|||
fragment UserMenu_MeFragment on User {
|
||||
id
|
||||
email
|
||||
fullName
|
||||
displayName
|
||||
provider
|
||||
isAdmin
|
||||
|
|
@ -74,7 +65,7 @@ export const UserMenu_MeFragment = graphql(`
|
|||
}
|
||||
`);
|
||||
|
||||
const UserMenu_MemberFragment = graphql(`
|
||||
export const UserMenu_MemberFragment = graphql(`
|
||||
fragment UserMenu_MemberFragment on Member {
|
||||
canLeaveOrganization
|
||||
}
|
||||
|
|
@ -82,19 +73,21 @@ const UserMenu_MemberFragment = graphql(`
|
|||
|
||||
export function UserMenu(props: {
|
||||
me: FragmentType<typeof UserMenu_MeFragment> | null;
|
||||
currentOrganization: FragmentType<typeof UserMenu_CurrentOrganizationFragment> | null;
|
||||
organizations: FragmentType<typeof UserMenu_OrganizationConnectionFragment> | null;
|
||||
currentOrganizationCleanId: string;
|
||||
}) {
|
||||
const docsUrl = getDocsUrl();
|
||||
const me = useFragment(UserMenu_MeFragment, props.me);
|
||||
const currentOrganization = useFragment(
|
||||
UserMenu_CurrentOrganizationFragment,
|
||||
props.currentOrganization,
|
||||
);
|
||||
const meInOrg = useFragment(UserMenu_MemberFragment, currentOrganization?.me);
|
||||
const organizations = useFragment(UserMenu_OrganizationConnectionFragment, props.organizations);
|
||||
const organizations = useFragment(
|
||||
UserMenu_OrganizationConnectionFragment,
|
||||
props.organizations,
|
||||
)?.nodes;
|
||||
const [isUserSettingsModalOpen, toggleUserSettingsModalOpen] = useToggle();
|
||||
const [isLeaveOrganizationModalOpen, toggleLeaveOrganizationModalOpen] = useToggle();
|
||||
const currentOrganization = organizations?.find(
|
||||
org => org.cleanId === props.currentOrganizationCleanId,
|
||||
);
|
||||
const meInOrg = useFragment(UserMenu_MemberFragment, currentOrganization?.me);
|
||||
|
||||
const canLeaveOrganization = !!currentOrganization && meInOrg?.canLeaveOrganization === true;
|
||||
|
||||
|
|
@ -158,11 +151,11 @@ export function UserMenu(props: {
|
|||
</DropdownMenuSubTrigger>
|
||||
) : null}
|
||||
<DropdownMenuSubContent className="max-w-[300px]">
|
||||
{organizations.nodes.length ? (
|
||||
{organizations.length ? (
|
||||
<DropdownMenuLabel>Organizations</DropdownMenuLabel>
|
||||
) : null}
|
||||
<DropdownMenuSeparator />
|
||||
{organizations.nodes.map(org => (
|
||||
{organizations.map(org => (
|
||||
<Link
|
||||
to="/$organizationId"
|
||||
params={{
|
||||
|
|
|
|||
|
|
@ -35,10 +35,12 @@ export const CreateProjectMutation = graphql(`
|
|||
ok {
|
||||
createdProject {
|
||||
id
|
||||
name
|
||||
cleanId
|
||||
}
|
||||
createdTargets {
|
||||
id
|
||||
name
|
||||
cleanId
|
||||
}
|
||||
updatedOrganization {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ export const CreateTarget_CreateTargetMutation = graphql(`
|
|||
createdTarget {
|
||||
id
|
||||
cleanId
|
||||
name
|
||||
}
|
||||
}
|
||||
error {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ export const DeleteOrganizationDocument = graphql(`
|
|||
|
||||
const DeleteOrganizationModal_OrganizationFragment = graphql(`
|
||||
fragment DeleteOrganizationModal_OrganizationFragment on Organization {
|
||||
id
|
||||
cleanId
|
||||
}
|
||||
`);
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ type Member = NonNullable<
|
|||
|
||||
const TransferOrganizationOwnershipModal_OrganizationFragment = graphql(`
|
||||
fragment TransferOrganizationOwnershipModal_OrganizationFragment on Organization {
|
||||
id
|
||||
cleanId
|
||||
}
|
||||
`);
|
||||
|
|
|
|||
|
|
@ -121,17 +121,9 @@ const OrganizationMembersPageQuery = graphql(`
|
|||
query OrganizationMembersPageQuery($selector: OrganizationSelectorInput!) {
|
||||
organization(selector: $selector) {
|
||||
organization {
|
||||
...OrganizationLayout_CurrentOrganizationFragment
|
||||
...OrganizationMembersPage_OrganizationFragment
|
||||
}
|
||||
}
|
||||
organizations {
|
||||
...OrganizationLayout_OrganizationConnectionFragment
|
||||
}
|
||||
me {
|
||||
id
|
||||
...OrganizationLayout_MeFragment
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -153,18 +145,13 @@ function OrganizationMembersPageContent(props: {
|
|||
return <QueryError organizationId={props.organizationId} error={query.error} />;
|
||||
}
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
|
||||
return (
|
||||
<OrganizationLayout
|
||||
organizationId={props.organizationId}
|
||||
page={Page.Members}
|
||||
className="flex flex-col gap-y-10"
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
me={me ?? null}
|
||||
>
|
||||
{currentOrganization ? (
|
||||
<PageContent
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@ const OrganizationPolicyPageQuery = graphql(`
|
|||
organization(selector: $selector) {
|
||||
organization {
|
||||
id
|
||||
...OrganizationLayout_CurrentOrganizationFragment
|
||||
me {
|
||||
...CanAccessOrganization_MemberFragment
|
||||
}
|
||||
|
|
@ -36,12 +35,6 @@ const OrganizationPolicyPageQuery = graphql(`
|
|||
}
|
||||
}
|
||||
}
|
||||
organizations {
|
||||
...OrganizationLayout_OrganizationConnectionFragment
|
||||
}
|
||||
me {
|
||||
...OrganizationLayout_MeFragment
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -62,7 +55,6 @@ const UpdateSchemaPolicyForOrganization = graphql(`
|
|||
ok {
|
||||
organization {
|
||||
id
|
||||
...OrganizationLayout_CurrentOrganizationFragment
|
||||
schemaPolicy {
|
||||
id
|
||||
updatedAt
|
||||
|
|
@ -87,9 +79,7 @@ function PolicyPageContent(props: { organizationId: string }) {
|
|||
const [mutation, mutate] = useMutation(UpdateSchemaPolicyForOrganization);
|
||||
const { toast } = useToast();
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
|
||||
const hasAccess = useOrganizationAccess({
|
||||
scope: OrganizationAccessScope.Settings,
|
||||
|
|
@ -98,10 +88,6 @@ function PolicyPageContent(props: { organizationId: string }) {
|
|||
organizationId: props.organizationId,
|
||||
});
|
||||
|
||||
if (!hasAccess) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const legacyProjects = currentOrganization?.projects.nodes.filter(
|
||||
p => p.registryModel === RegistryModel.Legacy,
|
||||
);
|
||||
|
|
@ -115,9 +101,6 @@ function PolicyPageContent(props: { organizationId: string }) {
|
|||
page={Page.Policy}
|
||||
organizationId={props.organizationId}
|
||||
className="flex flex-col gap-y-10"
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
me={me ?? null}
|
||||
>
|
||||
<div>
|
||||
<div className="py-6">
|
||||
|
|
@ -127,7 +110,7 @@ function PolicyPageContent(props: { organizationId: string }) {
|
|||
schema.
|
||||
</Subtitle>
|
||||
</div>
|
||||
{currentOrganization ? (
|
||||
{hasAccess && currentOrganization ? (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Rules</CardTitle>
|
||||
|
|
|
|||
|
|
@ -180,6 +180,7 @@ const UpdateOrganizationNameMutation = graphql(`
|
|||
}
|
||||
organization {
|
||||
id
|
||||
cleanId
|
||||
name
|
||||
}
|
||||
}
|
||||
|
|
@ -193,6 +194,7 @@ const UpdateOrganizationNameMutation = graphql(`
|
|||
|
||||
const SettingsPageRenderer_OrganizationFragment = graphql(`
|
||||
fragment SettingsPageRenderer_OrganizationFragment on Organization {
|
||||
id
|
||||
name
|
||||
me {
|
||||
...CanAccessOrganization_MemberFragment
|
||||
|
|
@ -424,16 +426,9 @@ const OrganizationSettingsPageQuery = graphql(`
|
|||
query OrganizationSettingsPageQuery($selector: OrganizationSelectorInput!) {
|
||||
organization(selector: $selector) {
|
||||
organization {
|
||||
...OrganizationLayout_CurrentOrganizationFragment
|
||||
...SettingsPageRenderer_OrganizationFragment
|
||||
}
|
||||
}
|
||||
organizations {
|
||||
...OrganizationLayout_OrganizationConnectionFragment
|
||||
}
|
||||
me {
|
||||
...OrganizationLayout_MeFragment
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -451,18 +446,13 @@ function SettingsPageContent(props: { organizationId: string }) {
|
|||
return <QueryError organizationId={props.organizationId} error={query.error} />;
|
||||
}
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
|
||||
return (
|
||||
<OrganizationLayout
|
||||
page={Page.Settings}
|
||||
organizationId={props.organizationId}
|
||||
className="flex flex-col gap-y-10"
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
me={me ?? null}
|
||||
>
|
||||
{currentOrganization ? (
|
||||
<SettingsPageRenderer
|
||||
|
|
|
|||
|
|
@ -429,19 +429,12 @@ const ManageSubscriptionPageQuery = graphql(`
|
|||
organization(selector: $selector) {
|
||||
organization {
|
||||
cleanId
|
||||
...OrganizationLayout_CurrentOrganizationFragment
|
||||
...ManageSubscriptionInner_OrganizationFragment
|
||||
}
|
||||
}
|
||||
billingPlans {
|
||||
...ManageSubscriptionInner_BillingPlansFragment
|
||||
}
|
||||
organizations {
|
||||
...OrganizationLayout_OrganizationConnectionFragment
|
||||
}
|
||||
me {
|
||||
...OrganizationLayout_MeFragment
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -455,16 +448,14 @@ function ManageSubscriptionPageContent(props: { organizationId: string }) {
|
|||
},
|
||||
});
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
const billingPlans = query.data?.billingPlans;
|
||||
|
||||
const organization = useFragment(
|
||||
ManageSubscriptionInner_OrganizationFragment,
|
||||
currentOrganization,
|
||||
);
|
||||
const canAccess = useOrganizationAccess({
|
||||
useOrganizationAccess({
|
||||
scope: OrganizationAccessScope.Settings,
|
||||
member: organization?.me ?? null,
|
||||
redirect: true,
|
||||
|
|
@ -475,22 +466,11 @@ function ManageSubscriptionPageContent(props: { organizationId: string }) {
|
|||
return <QueryError organizationId={props.organizationId} error={query.error} />;
|
||||
}
|
||||
|
||||
if (!currentOrganization || !me || !organizationConnection || !organization || !billingPlans) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!canAccess) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<OrganizationLayout
|
||||
page={Page.Subscription}
|
||||
organizationId={props.organizationId}
|
||||
className="flex flex-col gap-y-10"
|
||||
currentOrganization={currentOrganization}
|
||||
organizations={organizationConnection}
|
||||
me={me}
|
||||
>
|
||||
<div className="grow">
|
||||
<div className="flex flex-row items-center justify-between py-6">
|
||||
|
|
@ -498,19 +478,23 @@ function ManageSubscriptionPageContent(props: { organizationId: string }) {
|
|||
<Title>Manage subscription</Title>
|
||||
<Subtitle>Manage your current plan and invoices.</Subtitle>
|
||||
</div>
|
||||
<div>
|
||||
<Button asChild>
|
||||
<Link
|
||||
to="/$organizationId/view/subscription"
|
||||
params={{ organizationId: currentOrganization.cleanId }}
|
||||
>
|
||||
Subscription usage
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
{currentOrganization ? (
|
||||
<div>
|
||||
<Button asChild>
|
||||
<Link
|
||||
to="/$organizationId/view/subscription"
|
||||
params={{ organizationId: currentOrganization.cleanId }}
|
||||
>
|
||||
Subscription usage
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
<div>
|
||||
<Inner organization={currentOrganization} billingPlans={billingPlans} />
|
||||
{currentOrganization && billingPlans ? (
|
||||
<Inner organization={currentOrganization} billingPlans={billingPlans} />
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</OrganizationLayout>
|
||||
|
|
|
|||
|
|
@ -32,6 +32,8 @@ const numberFormatter = Intl.NumberFormat('en-US');
|
|||
|
||||
const SubscriptionPage_OrganizationFragment = graphql(`
|
||||
fragment SubscriptionPage_OrganizationFragment on Organization {
|
||||
id
|
||||
cleanId
|
||||
me {
|
||||
...CanAccessOrganization_MemberFragment
|
||||
}
|
||||
|
|
@ -65,17 +67,10 @@ const SubscriptionPageQuery = graphql(`
|
|||
organization(selector: $selector) {
|
||||
organization {
|
||||
cleanId
|
||||
...OrganizationLayout_CurrentOrganizationFragment
|
||||
...SubscriptionPage_OrganizationFragment
|
||||
}
|
||||
}
|
||||
...SubscriptionPage_QueryFragment
|
||||
organizations {
|
||||
...OrganizationLayout_OrganizationConnectionFragment
|
||||
}
|
||||
me {
|
||||
...OrganizationLayout_MeFragment
|
||||
}
|
||||
monthlyUsage(selector: $selector) {
|
||||
date
|
||||
total
|
||||
|
|
@ -93,9 +88,7 @@ function SubscriptionPageContent(props: { organizationId: string }) {
|
|||
},
|
||||
});
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
|
||||
const organization = useFragment(SubscriptionPage_OrganizationFragment, currentOrganization);
|
||||
const queryForBilling = useFragment(SubscriptionPage_QueryFragment, query.data);
|
||||
|
|
@ -121,7 +114,7 @@ function SubscriptionPageContent(props: { organizationId: string }) {
|
|||
return null;
|
||||
}
|
||||
|
||||
if (!currentOrganization || !me || !organizationConnection || !organization || !queryForBilling) {
|
||||
if (!currentOrganization || !organization || !queryForBilling) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
@ -138,9 +131,6 @@ function SubscriptionPageContent(props: { organizationId: string }) {
|
|||
page={Page.Subscription}
|
||||
organizationId={props.organizationId}
|
||||
className="flex flex-col gap-y-10"
|
||||
currentOrganization={currentOrganization}
|
||||
organizations={organizationConnection}
|
||||
me={me}
|
||||
>
|
||||
<div className="grow">
|
||||
<div className="flex flex-row items-center justify-between py-6">
|
||||
|
|
|
|||
|
|
@ -271,6 +271,7 @@ function SupportTicket(props: {
|
|||
|
||||
const SupportTicket_OrganizationFragment = graphql(`
|
||||
fragment SupportTicket_OrganizationFragment on Organization {
|
||||
id
|
||||
cleanId
|
||||
name
|
||||
me {
|
||||
|
|
@ -284,19 +285,12 @@ const SupportTicketPageQuery = graphql(`
|
|||
query SupportTicketPageQuery($selector: OrganizationSelectorInput!, $ticketId: ID!) {
|
||||
organization(selector: $selector) {
|
||||
organization {
|
||||
...OrganizationLayout_CurrentOrganizationFragment
|
||||
...SupportTicket_OrganizationFragment
|
||||
supportTicket(id: $ticketId) {
|
||||
...SupportTicket_SupportTicketFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
organizations {
|
||||
...OrganizationLayout_OrganizationConnectionFragment
|
||||
}
|
||||
me {
|
||||
...OrganizationLayout_MeFragment
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -321,9 +315,7 @@ function SupportTicketPageContent(props: { ticketId: string; organizationId: str
|
|||
return <QueryError organizationId={props.organizationId} error={query.error} />;
|
||||
}
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
const ticket = query.data?.organization?.organization.supportTicket;
|
||||
|
||||
return (
|
||||
|
|
@ -331,9 +323,6 @@ function SupportTicketPageContent(props: { ticketId: string; organizationId: str
|
|||
page={Page.Support}
|
||||
organizationId={props.organizationId}
|
||||
className="flex flex-col gap-y-10"
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
me={me ?? null}
|
||||
>
|
||||
{currentOrganization ? (
|
||||
ticket ? (
|
||||
|
|
|
|||
|
|
@ -292,6 +292,7 @@ function SupportTicketRow(props: {
|
|||
|
||||
const Support_OrganizationFragment = graphql(`
|
||||
fragment Support_OrganizationFragment on Organization {
|
||||
id
|
||||
cleanId
|
||||
name
|
||||
me {
|
||||
|
|
@ -390,16 +391,9 @@ const SupportPageQuery = graphql(`
|
|||
query SupportPageQuery($selector: OrganizationSelectorInput!) {
|
||||
organization(selector: $selector) {
|
||||
organization {
|
||||
...OrganizationLayout_CurrentOrganizationFragment
|
||||
...Support_OrganizationFragment
|
||||
}
|
||||
}
|
||||
organizations {
|
||||
...OrganizationLayout_OrganizationConnectionFragment
|
||||
}
|
||||
me {
|
||||
...OrganizationLayout_MeFragment
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -422,18 +416,13 @@ function SupportPageContent(props: { organizationId: string }) {
|
|||
return <QueryError organizationId={props.organizationId} error={query.error} />;
|
||||
}
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
|
||||
return (
|
||||
<OrganizationLayout
|
||||
page={Page.Support}
|
||||
organizationId={props.organizationId}
|
||||
className="flex flex-col gap-y-10"
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
me={me ?? null}
|
||||
>
|
||||
{currentOrganization ? (
|
||||
<Support organization={currentOrganization} refetch={refetch} />
|
||||
|
|
|
|||
|
|
@ -223,7 +223,6 @@ const OrganizationProjectsPageQuery = graphql(`
|
|||
) {
|
||||
organization(selector: { organization: $organizationId }) {
|
||||
organization {
|
||||
...OrganizationLayout_CurrentOrganizationFragment
|
||||
id
|
||||
cleanId
|
||||
}
|
||||
|
|
@ -242,12 +241,6 @@ const OrganizationProjectsPageQuery = graphql(`
|
|||
schemaVersionsCount(period: $period)
|
||||
}
|
||||
}
|
||||
organizations {
|
||||
...OrganizationLayout_OrganizationConnectionFragment
|
||||
}
|
||||
me {
|
||||
...OrganizationLayout_MeFragment
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -273,11 +266,10 @@ function OrganizationPageContent(props: { organizationId: string }) {
|
|||
chartResolution: days, // 14 days = 14 data points
|
||||
period: period.current,
|
||||
},
|
||||
requestPolicy: 'cache-and-network',
|
||||
});
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
const projects = query.data?.projects;
|
||||
|
||||
const highestNumberOfRequests = useMemo(() => {
|
||||
|
|
@ -305,9 +297,6 @@ function OrganizationPageContent(props: { organizationId: string }) {
|
|||
page={Page.Overview}
|
||||
organizationId={props.organizationId}
|
||||
className="flex justify-between gap-12"
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
me={me ?? null}
|
||||
>
|
||||
<>
|
||||
<div className="grow">
|
||||
|
|
|
|||
|
|
@ -178,12 +178,11 @@ const ProjectAlertsPageQuery = graphql(`
|
|||
query ProjectAlertsPageQuery($organizationId: ID!, $projectId: ID!) {
|
||||
organization(selector: { organization: $organizationId }) {
|
||||
organization {
|
||||
...ProjectLayout_CurrentOrganizationFragment
|
||||
...ProjectAlertsPage_OrganizationFragment
|
||||
}
|
||||
}
|
||||
project(selector: { organization: $organizationId, project: $projectId }) {
|
||||
...ProjectLayout_CurrentProjectFragment
|
||||
id
|
||||
targets {
|
||||
nodes {
|
||||
...CreateAlertModal_TargetFragment
|
||||
|
|
@ -197,13 +196,6 @@ const ProjectAlertsPageQuery = graphql(`
|
|||
...CreateAlertModal_AlertChannelFragment
|
||||
}
|
||||
}
|
||||
organizations {
|
||||
...ProjectLayout_OrganizationConnectionFragment
|
||||
}
|
||||
me {
|
||||
id
|
||||
...ProjectLayout_MeFragment
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -217,10 +209,8 @@ function AlertsPageContent(props: { organizationId: string; projectId: string })
|
|||
requestPolicy: 'cache-and-network',
|
||||
});
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const currentProject = query.data?.project;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
const organizationForAlerts = useFragment(
|
||||
ProjectAlertsPage_OrganizationFragment,
|
||||
currentOrganization,
|
||||
|
|
@ -246,10 +236,6 @@ function AlertsPageContent(props: { organizationId: string; projectId: string })
|
|||
<ProjectLayout
|
||||
projectId={props.projectId}
|
||||
organizationId={props.organizationId}
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
currentProject={currentProject ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
me={me ?? null}
|
||||
page={Page.Alerts}
|
||||
className="flex flex-col gap-y-10"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -20,12 +20,10 @@ const ProjectPolicyPageQuery = graphql(`
|
|||
id
|
||||
...CanAccessProject_MemberFragment
|
||||
}
|
||||
...ProjectLayout_CurrentOrganizationFragment
|
||||
}
|
||||
}
|
||||
project(selector: { organization: $organizationId, project: $projectId }) {
|
||||
id
|
||||
...ProjectLayout_CurrentProjectFragment
|
||||
registryModel
|
||||
schemaPolicy {
|
||||
id
|
||||
|
|
@ -43,13 +41,6 @@ const ProjectPolicyPageQuery = graphql(`
|
|||
}
|
||||
}
|
||||
}
|
||||
organizations {
|
||||
...ProjectLayout_OrganizationConnectionFragment
|
||||
}
|
||||
me {
|
||||
id
|
||||
...ProjectLayout_MeFragment
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -65,7 +56,6 @@ const UpdateSchemaPolicyForProject = graphql(`
|
|||
ok {
|
||||
project {
|
||||
id
|
||||
...ProjectLayout_CurrentProjectFragment
|
||||
schemaPolicy {
|
||||
id
|
||||
updatedAt
|
||||
|
|
@ -89,10 +79,8 @@ function ProjectPolicyContent(props: { organizationId: string; projectId: string
|
|||
});
|
||||
const { toast } = useToast();
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const currentProject = query.data?.project;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
|
||||
const hasAccess = useProjectAccess({
|
||||
scope: ProjectAccessScope.Settings,
|
||||
|
|
@ -112,10 +100,6 @@ function ProjectPolicyContent(props: { organizationId: string; projectId: string
|
|||
<ProjectLayout
|
||||
organizationId={props.organizationId}
|
||||
projectId={props.projectId}
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
currentProject={currentProject ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
me={me ?? null}
|
||||
page={Page.Policy}
|
||||
className="flex flex-col gap-y-10"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -218,20 +218,11 @@ const ProjectSettingsPageQuery = graphql(`
|
|||
organization(selector: { organization: $organizationId }) {
|
||||
organization {
|
||||
...ProjectSettingsPage_OrganizationFragment
|
||||
...ProjectLayout_CurrentOrganizationFragment
|
||||
}
|
||||
}
|
||||
project(selector: { organization: $organizationId, project: $projectId }) {
|
||||
...ProjectLayout_CurrentProjectFragment
|
||||
...ProjectSettingsPage_ProjectFragment
|
||||
}
|
||||
organizations {
|
||||
...ProjectLayout_OrganizationConnectionFragment
|
||||
}
|
||||
me {
|
||||
id
|
||||
...ProjectLayout_MeFragment
|
||||
}
|
||||
isGitHubIntegrationFeatureEnabled
|
||||
}
|
||||
`);
|
||||
|
|
@ -248,10 +239,8 @@ function ProjectSettingsContent(props: { organizationId: string; projectId: stri
|
|||
requestPolicy: 'cache-and-network',
|
||||
});
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const currentProject = query.data?.project;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
|
||||
const organization = useFragment(ProjectSettingsPage_OrganizationFragment, currentOrganization);
|
||||
const project = useFragment(ProjectSettingsPage_ProjectFragment, currentProject);
|
||||
|
|
@ -316,10 +305,6 @@ function ProjectSettingsContent(props: { organizationId: string; projectId: stri
|
|||
<ProjectLayout
|
||||
organizationId={props.organizationId}
|
||||
projectId={props.projectId}
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
currentProject={currentProject ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
me={me ?? null}
|
||||
page={Page.Settings}
|
||||
className="flex flex-col gap-y-10"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -225,12 +225,9 @@ const ProjectsPageContent = (props: { organizationId: string; projectId: string
|
|||
chartResolution: days, // 14 days = 14 data points
|
||||
period: period.current,
|
||||
},
|
||||
requestPolicy: 'cache-and-network',
|
||||
});
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const currentProject = query.data?.project;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
const targetConnection = query.data?.targets;
|
||||
const targets = targetConnection?.nodes;
|
||||
|
||||
|
|
@ -257,10 +254,6 @@ const ProjectsPageContent = (props: { organizationId: string; projectId: string
|
|||
organizationId={props.organizationId}
|
||||
projectId={props.projectId}
|
||||
className="flex justify-between gap-12"
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
currentProject={currentProject ?? null}
|
||||
me={me ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
>
|
||||
<div className="grow">
|
||||
<div className="py-6">
|
||||
|
|
@ -338,17 +331,6 @@ const ProjectOverviewPageQuery = graphql(`
|
|||
$chartResolution: Int!
|
||||
$period: DateRangeInput!
|
||||
) {
|
||||
organization(selector: { organization: $organizationId }) {
|
||||
organization {
|
||||
...ProjectLayout_CurrentOrganizationFragment
|
||||
}
|
||||
}
|
||||
project(selector: { organization: $organizationId, project: $projectId }) {
|
||||
...ProjectLayout_CurrentProjectFragment
|
||||
}
|
||||
organizations {
|
||||
...ProjectLayout_OrganizationConnectionFragment
|
||||
}
|
||||
targets(selector: { organization: $organizationId, project: $projectId }) {
|
||||
total
|
||||
nodes {
|
||||
|
|
@ -363,10 +345,6 @@ const ProjectOverviewPageQuery = graphql(`
|
|||
schemaVersionsCount(period: $period)
|
||||
}
|
||||
}
|
||||
me {
|
||||
id
|
||||
...ProjectLayout_MeFragment
|
||||
}
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
|
|||
|
|
@ -171,20 +171,14 @@ const ChecksPageQuery = graphql(`
|
|||
$targetId: ID!
|
||||
$filters: SchemaChecksFilter
|
||||
) {
|
||||
organizations {
|
||||
...TargetLayout_OrganizationConnectionFragment
|
||||
}
|
||||
organization(selector: { organization: $organizationId }) {
|
||||
organization {
|
||||
...TargetLayout_CurrentOrganizationFragment
|
||||
id
|
||||
rateLimit {
|
||||
retentionInDays
|
||||
}
|
||||
}
|
||||
}
|
||||
project(selector: { organization: $organizationId, project: $projectId }) {
|
||||
...TargetLayout_CurrentProjectFragment
|
||||
}
|
||||
target(selector: { organization: $organizationId, project: $projectId, target: $targetId }) {
|
||||
id
|
||||
schemaChecks(first: 1) {
|
||||
|
|
@ -202,10 +196,6 @@ const ChecksPageQuery = graphql(`
|
|||
}
|
||||
}
|
||||
}
|
||||
me {
|
||||
...TargetLayout_MeFragment
|
||||
}
|
||||
...TargetLayout_IsCDNEnabledFragment
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -247,11 +237,6 @@ function ChecksPageContent(props: { organizationId: string; projectId: string; t
|
|||
return <QueryError organizationId={props.organizationId} error={query.error} />;
|
||||
}
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const currentProject = query.data?.project;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
const isCDNEnabled = query.data;
|
||||
const hasSchemaChecks = !!query.data?.target?.schemaChecks?.edges?.length;
|
||||
const hasFilteredSchemaChecks = !!query.data?.target?.filteredSchemaChecks?.edges?.length;
|
||||
const hasActiveSchemaCheck = !!schemaCheckId;
|
||||
|
|
@ -295,11 +280,6 @@ function ChecksPageContent(props: { organizationId: string; projectId: string; t
|
|||
targetId={props.targetId}
|
||||
page={Page.Checks}
|
||||
className="h-full"
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
currentProject={currentProject ?? null}
|
||||
me={me ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
isCDNEnabled={isCDNEnabled ?? null}
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
|
|
|
|||
|
|
@ -295,29 +295,18 @@ const TargetExplorerDeprecatedSchemaPageQuery = graphql(`
|
|||
$projectId: ID!
|
||||
$targetId: ID!
|
||||
) {
|
||||
organizations {
|
||||
...TargetLayout_OrganizationConnectionFragment
|
||||
}
|
||||
organization(selector: { organization: $organizationId }) {
|
||||
organization {
|
||||
...TargetLayout_CurrentOrganizationFragment
|
||||
id
|
||||
rateLimit {
|
||||
retentionInDays
|
||||
}
|
||||
cleanId
|
||||
}
|
||||
}
|
||||
project(selector: { organization: $organizationId, project: $projectId }) {
|
||||
...TargetLayout_CurrentProjectFragment
|
||||
cleanId
|
||||
}
|
||||
hasCollectedOperations(
|
||||
selector: { organization: $organizationId, project: $projectId, target: $targetId }
|
||||
)
|
||||
me {
|
||||
...TargetLayout_MeFragment
|
||||
}
|
||||
...TargetLayout_IsCDNEnabledFragment
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -339,11 +328,7 @@ function ExplorerDeprecatedSchemaPageContent(props: {
|
|||
return <QueryError organizationId={props.organizationId} error={query.error} />;
|
||||
}
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const currentProject = query.data?.project;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
const isCDNEnabled = query.data;
|
||||
const hasCollectedOperations = query.data?.hasCollectedOperations === true;
|
||||
|
||||
return (
|
||||
|
|
@ -352,11 +337,6 @@ function ExplorerDeprecatedSchemaPageContent(props: {
|
|||
projectId={props.projectId}
|
||||
targetId={props.targetId}
|
||||
page={Page.Explorer}
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
currentProject={currentProject ?? null}
|
||||
me={me ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
isCDNEnabled={isCDNEnabled ?? null}
|
||||
>
|
||||
{currentOrganization ? (
|
||||
hasCollectedOperations ? (
|
||||
|
|
|
|||
|
|
@ -129,22 +129,16 @@ const TargetExplorerTypenamePageQuery = graphql(`
|
|||
$period: DateRangeInput!
|
||||
$typename: String!
|
||||
) {
|
||||
organizations {
|
||||
...TargetLayout_OrganizationConnectionFragment
|
||||
}
|
||||
organization(selector: { organization: $organizationId }) {
|
||||
organization {
|
||||
...TargetLayout_CurrentOrganizationFragment
|
||||
id
|
||||
name
|
||||
cleanId
|
||||
rateLimit {
|
||||
retentionInDays
|
||||
}
|
||||
}
|
||||
}
|
||||
project(selector: { organization: $organizationId, project: $projectId }) {
|
||||
...TargetLayout_CurrentProjectFragment
|
||||
cleanId
|
||||
}
|
||||
target(selector: { organization: $organizationId, project: $projectId, target: $targetId }) {
|
||||
id
|
||||
cleanId
|
||||
|
|
@ -169,10 +163,6 @@ const TargetExplorerTypenamePageQuery = graphql(`
|
|||
) {
|
||||
totalRequests
|
||||
}
|
||||
me {
|
||||
...TargetLayout_MeFragment
|
||||
}
|
||||
...TargetLayout_IsCDNEnabledFragment
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -208,11 +198,7 @@ function TypeExplorerPageContent(props: {
|
|||
return <QueryError organizationId={props.organizationId} error={query.error} />;
|
||||
}
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentProject = query.data?.project;
|
||||
const currentTarget = query.data?.target;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
const isCDNEnabled = query.data;
|
||||
const type = currentTarget?.latestSchemaVersion?.explorer?.type;
|
||||
const latestSchemaVersion = currentTarget?.latestSchemaVersion;
|
||||
|
||||
|
|
@ -222,11 +208,6 @@ function TypeExplorerPageContent(props: {
|
|||
projectId={props.projectId}
|
||||
targetId={props.targetId}
|
||||
page={Page.Explorer}
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
currentProject={currentProject ?? null}
|
||||
me={me ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
isCDNEnabled={isCDNEnabled ?? null}
|
||||
>
|
||||
<div className="flex flex-row items-center justify-between py-6">
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -289,29 +289,18 @@ function UnusedSchemaExplorer(props: {
|
|||
|
||||
const TargetExplorerUnusedSchemaPageQuery = graphql(`
|
||||
query TargetExplorerUnusedSchemaPageQuery($organizationId: ID!, $projectId: ID!, $targetId: ID!) {
|
||||
organizations {
|
||||
...TargetLayout_OrganizationConnectionFragment
|
||||
}
|
||||
organization(selector: { organization: $organizationId }) {
|
||||
organization {
|
||||
...TargetLayout_CurrentOrganizationFragment
|
||||
id
|
||||
rateLimit {
|
||||
retentionInDays
|
||||
}
|
||||
cleanId
|
||||
}
|
||||
}
|
||||
project(selector: { organization: $organizationId, project: $projectId }) {
|
||||
...TargetLayout_CurrentProjectFragment
|
||||
cleanId
|
||||
}
|
||||
hasCollectedOperations(
|
||||
selector: { organization: $organizationId, project: $projectId, target: $targetId }
|
||||
)
|
||||
me {
|
||||
...TargetLayout_MeFragment
|
||||
}
|
||||
...TargetLayout_IsCDNEnabledFragment
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -333,11 +322,7 @@ function ExplorerUnusedSchemaPageContent(props: {
|
|||
return <QueryError organizationId={props.organizationId} error={query.error} />;
|
||||
}
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const currentProject = query.data?.project;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
const isCDNEnabled = query.data;
|
||||
const hasCollectedOperations = query.data?.hasCollectedOperations === true;
|
||||
|
||||
return (
|
||||
|
|
@ -346,11 +331,6 @@ function ExplorerUnusedSchemaPageContent(props: {
|
|||
projectId={props.projectId}
|
||||
targetId={props.targetId}
|
||||
page={Page.Explorer}
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
currentProject={currentProject ?? null}
|
||||
me={me ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
isCDNEnabled={isCDNEnabled ?? null}
|
||||
>
|
||||
{currentOrganization ? (
|
||||
hasCollectedOperations ? (
|
||||
|
|
|
|||
|
|
@ -101,22 +101,15 @@ const TargetExplorerPageQuery = graphql(`
|
|||
$targetId: ID!
|
||||
$period: DateRangeInput!
|
||||
) {
|
||||
organizations {
|
||||
...TargetLayout_OrganizationConnectionFragment
|
||||
}
|
||||
organization(selector: { organization: $organizationId }) {
|
||||
organization {
|
||||
...TargetLayout_CurrentOrganizationFragment
|
||||
id
|
||||
rateLimit {
|
||||
retentionInDays
|
||||
}
|
||||
cleanId
|
||||
}
|
||||
}
|
||||
project(selector: { organization: $organizationId, project: $projectId }) {
|
||||
...TargetLayout_CurrentProjectFragment
|
||||
cleanId
|
||||
}
|
||||
target(selector: { organization: $organizationId, project: $projectId, target: $targetId }) {
|
||||
id
|
||||
cleanId
|
||||
|
|
@ -142,10 +135,6 @@ const TargetExplorerPageQuery = graphql(`
|
|||
) {
|
||||
totalRequests
|
||||
}
|
||||
me {
|
||||
...TargetLayout_MeFragment
|
||||
}
|
||||
...TargetLayout_IsCDNEnabledFragment
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -182,11 +171,7 @@ function ExplorerPageContent(props: {
|
|||
return <QueryError organizationId={props.organizationId} error={query.error} />;
|
||||
}
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentProject = query.data?.project;
|
||||
const currentTarget = query.data?.target;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
const isCDNEnabled = query.data;
|
||||
const latestSchemaVersion = currentTarget?.latestSchemaVersion;
|
||||
const latestValidSchemaVersion = currentTarget?.latestValidSchemaVersion;
|
||||
|
||||
|
|
@ -200,11 +185,6 @@ function ExplorerPageContent(props: {
|
|||
projectId={props.projectId}
|
||||
targetId={props.targetId}
|
||||
page={Page.Explorer}
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
currentProject={currentProject ?? null}
|
||||
me={me ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
isCDNEnabled={isCDNEnabled ?? null}
|
||||
>
|
||||
<div className="flex flex-row items-center justify-between py-6">
|
||||
<div>
|
||||
|
|
|
|||
|
|
@ -157,30 +157,12 @@ function ListPage(props: {
|
|||
|
||||
const TargetHistoryPageQuery = graphql(`
|
||||
query TargetHistoryPageQuery($organizationId: ID!, $projectId: ID!, $targetId: ID!) {
|
||||
organizations {
|
||||
...TargetLayout_OrganizationConnectionFragment
|
||||
}
|
||||
organization(selector: { organization: $organizationId }) {
|
||||
organization {
|
||||
id
|
||||
...TargetLayout_CurrentOrganizationFragment
|
||||
}
|
||||
}
|
||||
project(selector: { organization: $organizationId, project: $projectId }) {
|
||||
id
|
||||
...TargetLayout_CurrentProjectFragment
|
||||
}
|
||||
target(selector: { organization: $organizationId, project: $projectId, target: $targetId }) {
|
||||
id
|
||||
latestSchemaVersion {
|
||||
id
|
||||
}
|
||||
}
|
||||
me {
|
||||
id
|
||||
...TargetLayout_MeFragment
|
||||
}
|
||||
...TargetLayout_IsCDNEnabledFragment
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -199,12 +181,7 @@ function HistoryPageContent(props: {
|
|||
},
|
||||
});
|
||||
const [pageVariables, setPageVariables] = useState([{ first: 10, after: null as string | null }]);
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const currentProject = query.data?.project;
|
||||
const currentTarget = query.data?.target;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
const isCDNEnabled = query.data;
|
||||
const hasVersions = !!currentTarget?.latestSchemaVersion?.id;
|
||||
|
||||
const { versionId } = useParams({
|
||||
|
|
@ -236,11 +213,6 @@ function HistoryPageContent(props: {
|
|||
targetId={props.targetId}
|
||||
page={Page.History}
|
||||
className="h-full"
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
currentProject={currentProject ?? null}
|
||||
me={me ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
isCDNEnabled={isCDNEnabled ?? null}
|
||||
>
|
||||
{hasVersions ? (
|
||||
<div className="flex size-full flex-row gap-x-6">
|
||||
|
|
|
|||
|
|
@ -334,33 +334,18 @@ function ClientView(props: {
|
|||
|
||||
const ClientInsightsPageQuery = graphql(`
|
||||
query ClientInsightsPageQuery($organizationId: ID!, $projectId: ID!, $targetId: ID!) {
|
||||
organizations {
|
||||
...TargetLayout_OrganizationConnectionFragment
|
||||
}
|
||||
organization(selector: { organization: $organizationId }) {
|
||||
organization {
|
||||
...TargetLayout_CurrentOrganizationFragment
|
||||
id
|
||||
cleanId
|
||||
rateLimit {
|
||||
retentionInDays
|
||||
}
|
||||
}
|
||||
}
|
||||
project(selector: { organization: $organizationId, project: $projectId }) {
|
||||
...TargetLayout_CurrentProjectFragment
|
||||
cleanId
|
||||
}
|
||||
target(selector: { organization: $organizationId, project: $projectId, target: $targetId }) {
|
||||
id
|
||||
cleanId
|
||||
}
|
||||
hasCollectedOperations(
|
||||
selector: { organization: $organizationId, project: $projectId, target: $targetId }
|
||||
)
|
||||
me {
|
||||
...TargetLayout_MeFragment
|
||||
}
|
||||
...TargetLayout_IsCDNEnabledFragment
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -383,12 +368,7 @@ function ClientInsightsPageContent(props: {
|
|||
return <QueryError organizationId={props.organizationId} error={query.error} />;
|
||||
}
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const currentProject = query.data?.project;
|
||||
const currentTarget = query.data?.target;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
const isCDNEnabled = query.data;
|
||||
const hasCollectedOperations = query.data?.hasCollectedOperations === true;
|
||||
|
||||
return (
|
||||
|
|
@ -397,13 +377,8 @@ function ClientInsightsPageContent(props: {
|
|||
projectId={props.projectId}
|
||||
targetId={props.targetId}
|
||||
page={Page.Insights}
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
currentProject={currentProject ?? null}
|
||||
me={me ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
isCDNEnabled={isCDNEnabled ?? null}
|
||||
>
|
||||
{currentOrganization && currentProject && currentTarget ? (
|
||||
{currentOrganization ? (
|
||||
hasCollectedOperations ? (
|
||||
<ClientView
|
||||
clientName={props.name}
|
||||
|
|
|
|||
|
|
@ -386,34 +386,18 @@ function SchemaCoordinateView(props: {
|
|||
|
||||
const TargetSchemaCoordinatePageQuery = graphql(`
|
||||
query TargetSchemaCoordinatePageQuery($organizationId: ID!, $projectId: ID!, $targetId: ID!) {
|
||||
organizations {
|
||||
...TargetLayout_OrganizationConnectionFragment
|
||||
}
|
||||
organization(selector: { organization: $organizationId }) {
|
||||
organization {
|
||||
...TargetLayout_CurrentOrganizationFragment
|
||||
id
|
||||
cleanId
|
||||
rateLimit {
|
||||
retentionInDays
|
||||
}
|
||||
}
|
||||
}
|
||||
project(selector: { organization: $organizationId, project: $projectId }) {
|
||||
...TargetLayout_CurrentProjectFragment
|
||||
id
|
||||
cleanId
|
||||
}
|
||||
target(selector: { organization: $organizationId, project: $projectId, target: $targetId }) {
|
||||
id
|
||||
cleanId
|
||||
}
|
||||
hasCollectedOperations(
|
||||
selector: { organization: $organizationId, project: $projectId, target: $targetId }
|
||||
)
|
||||
me {
|
||||
...TargetLayout_MeFragment
|
||||
}
|
||||
...TargetLayout_IsCDNEnabledFragment
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -436,12 +420,7 @@ function TargetSchemaCoordinatePageContent(props: {
|
|||
return <QueryError organizationId={props.organizationId} error={query.error} />;
|
||||
}
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const currentProject = query.data?.project;
|
||||
const currentTarget = query.data?.target;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
const isCDNEnabled = query.data;
|
||||
const hasCollectedOperations = query.data?.hasCollectedOperations === true;
|
||||
|
||||
return (
|
||||
|
|
@ -450,13 +429,8 @@ function TargetSchemaCoordinatePageContent(props: {
|
|||
projectId={props.projectId}
|
||||
targetId={props.targetId}
|
||||
page={Page.Insights}
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
currentProject={currentProject ?? null}
|
||||
me={me ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
isCDNEnabled={isCDNEnabled ?? null}
|
||||
>
|
||||
{currentOrganization && currentProject && currentTarget ? (
|
||||
{currentOrganization ? (
|
||||
hasCollectedOperations ? (
|
||||
<SchemaCoordinateView
|
||||
coordinate={props.coordinate}
|
||||
|
|
|
|||
|
|
@ -154,33 +154,18 @@ function OperationView({
|
|||
|
||||
const OperationInsightsPageQuery = graphql(`
|
||||
query OperationInsightsPageQuery($organizationId: ID!, $projectId: ID!, $targetId: ID!) {
|
||||
organizations {
|
||||
...TargetLayout_OrganizationConnectionFragment
|
||||
}
|
||||
organization(selector: { organization: $organizationId }) {
|
||||
organization {
|
||||
...TargetLayout_CurrentOrganizationFragment
|
||||
id
|
||||
cleanId
|
||||
rateLimit {
|
||||
retentionInDays
|
||||
}
|
||||
}
|
||||
}
|
||||
project(selector: { organization: $organizationId, project: $projectId }) {
|
||||
...TargetLayout_CurrentProjectFragment
|
||||
cleanId
|
||||
}
|
||||
target(selector: { organization: $organizationId, project: $projectId, target: $targetId }) {
|
||||
id
|
||||
cleanId
|
||||
}
|
||||
hasCollectedOperations(
|
||||
selector: { organization: $organizationId, project: $projectId, target: $targetId }
|
||||
)
|
||||
me {
|
||||
...TargetLayout_MeFragment
|
||||
}
|
||||
...TargetLayout_IsCDNEnabledFragment
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -204,12 +189,7 @@ function OperationInsightsContent(props: {
|
|||
return <QueryError organizationId={props.organizationId} error={query.error} />;
|
||||
}
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const currentProject = query.data?.project;
|
||||
const currentTarget = query.data?.target;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
const isCDNEnabled = query.data;
|
||||
const hasCollectedOperations = query.data?.hasCollectedOperations === true;
|
||||
|
||||
return (
|
||||
|
|
@ -218,18 +198,13 @@ function OperationInsightsContent(props: {
|
|||
projectId={props.projectId}
|
||||
targetId={props.targetId}
|
||||
page={Page.Insights}
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
currentProject={currentProject ?? null}
|
||||
me={me ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
isCDNEnabled={isCDNEnabled ?? null}
|
||||
>
|
||||
{currentOrganization && currentProject && currentTarget ? (
|
||||
{currentOrganization ? (
|
||||
hasCollectedOperations ? (
|
||||
<OperationView
|
||||
organizationCleanId={currentOrganization.cleanId}
|
||||
projectCleanId={currentProject.cleanId}
|
||||
targetCleanId={currentTarget.cleanId}
|
||||
organizationCleanId={props.organizationId}
|
||||
projectCleanId={props.projectId}
|
||||
targetCleanId={props.targetId}
|
||||
dataRetentionInDays={currentOrganization.rateLimit.retentionInDays}
|
||||
operationHash={props.operationHash}
|
||||
operationName={props.operationName}
|
||||
|
|
|
|||
|
|
@ -98,33 +98,18 @@ function OperationsView({
|
|||
|
||||
const TargetOperationsPageQuery = graphql(`
|
||||
query TargetOperationsPageQuery($organizationId: ID!, $projectId: ID!, $targetId: ID!) {
|
||||
organizations {
|
||||
...TargetLayout_OrganizationConnectionFragment
|
||||
}
|
||||
organization(selector: { organization: $organizationId }) {
|
||||
organization {
|
||||
...TargetLayout_CurrentOrganizationFragment
|
||||
id
|
||||
cleanId
|
||||
rateLimit {
|
||||
retentionInDays
|
||||
}
|
||||
}
|
||||
}
|
||||
project(selector: { organization: $organizationId, project: $projectId }) {
|
||||
...TargetLayout_CurrentProjectFragment
|
||||
cleanId
|
||||
}
|
||||
target(selector: { organization: $organizationId, project: $projectId, target: $targetId }) {
|
||||
id
|
||||
cleanId
|
||||
}
|
||||
hasCollectedOperations(
|
||||
selector: { organization: $organizationId, project: $projectId, target: $targetId }
|
||||
)
|
||||
me {
|
||||
...TargetLayout_MeFragment
|
||||
}
|
||||
...TargetLayout_IsCDNEnabledFragment
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -146,12 +131,7 @@ function TargetOperationsPageContent(props: {
|
|||
return <QueryError organizationId={props.organizationId} error={query.error} />;
|
||||
}
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const currentProject = query.data?.project;
|
||||
const currentTarget = query.data?.target;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
const isCDNEnabled = query.data;
|
||||
const hasCollectedOperations = query.data?.hasCollectedOperations === true;
|
||||
|
||||
return (
|
||||
|
|
@ -160,18 +140,13 @@ function TargetOperationsPageContent(props: {
|
|||
projectId={props.projectId}
|
||||
targetId={props.targetId}
|
||||
page={Page.Insights}
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
currentProject={currentProject ?? null}
|
||||
me={me ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
isCDNEnabled={isCDNEnabled ?? null}
|
||||
>
|
||||
{currentOrganization && currentProject && currentTarget ? (
|
||||
{currentOrganization ? (
|
||||
hasCollectedOperations ? (
|
||||
<OperationsView
|
||||
organizationCleanId={currentOrganization.cleanId}
|
||||
projectCleanId={currentProject.cleanId}
|
||||
targetCleanId={currentTarget.cleanId}
|
||||
organizationCleanId={props.organizationId}
|
||||
projectCleanId={props.projectId}
|
||||
targetCleanId={props.targetId}
|
||||
dataRetentionInDays={currentOrganization.rateLimit.retentionInDays}
|
||||
/>
|
||||
) : (
|
||||
|
|
|
|||
|
|
@ -822,21 +822,15 @@ function Save(props: {
|
|||
|
||||
const TargetLaboratoryPageQuery = graphql(`
|
||||
query TargetLaboratoryPageQuery($organizationId: ID!, $projectId: ID!, $targetId: ID!) {
|
||||
organizations {
|
||||
...TargetLayout_OrganizationConnectionFragment
|
||||
}
|
||||
organization(selector: { organization: $organizationId }) {
|
||||
organization {
|
||||
...TargetLayout_CurrentOrganizationFragment
|
||||
id
|
||||
me {
|
||||
id
|
||||
...CanAccessTarget_MemberFragment
|
||||
}
|
||||
}
|
||||
}
|
||||
project(selector: { organization: $organizationId, project: $projectId }) {
|
||||
...TargetLayout_CurrentProjectFragment
|
||||
}
|
||||
target(selector: { organization: $organizationId, project: $projectId, target: $targetId }) {
|
||||
id
|
||||
graphqlEndpointUrl
|
||||
|
|
@ -845,11 +839,6 @@ const TargetLaboratoryPageQuery = graphql(`
|
|||
sdl
|
||||
}
|
||||
}
|
||||
me {
|
||||
id
|
||||
...TargetLayout_MeFragment
|
||||
}
|
||||
...TargetLayout_IsCDNEnabledFragment
|
||||
...Laboratory_IsCDNEnabledFragment
|
||||
}
|
||||
`);
|
||||
|
|
@ -870,11 +859,7 @@ function LaboratoryPageContent(props: {
|
|||
const router = useRouter();
|
||||
const [isConnectLabModalOpen, toggleConnectLabModal] = useToggle();
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const currentProject = query.data?.project;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
const isCDNEnabled = query.data;
|
||||
|
||||
const operationCollectionsPlugin = useOperationCollectionsPlugin({
|
||||
canEdit: canAccessTarget(TargetAccessScope.Settings, currentOrganization?.me ?? null),
|
||||
|
|
@ -959,11 +944,6 @@ function LaboratoryPageContent(props: {
|
|||
projectId={props.projectId}
|
||||
targetId={props.targetId}
|
||||
page={Page.Laboratory}
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
currentProject={currentProject ?? null}
|
||||
me={me ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
isCDNEnabled={isCDNEnabled ?? null}
|
||||
>
|
||||
<div className="flex py-6">
|
||||
<div className="flex-1">
|
||||
|
|
|
|||
|
|
@ -1027,14 +1027,10 @@ function TargetDelete(props: { organizationId: string; projectId: string; target
|
|||
|
||||
const TargetSettingsPageQuery = graphql(`
|
||||
query TargetSettingsPageQuery($organizationId: ID!, $projectId: ID!, $targetId: ID!) {
|
||||
organizations {
|
||||
...TargetLayout_OrganizationConnectionFragment
|
||||
}
|
||||
organization(selector: { organization: $organizationId }) {
|
||||
organization {
|
||||
id
|
||||
cleanId
|
||||
...TargetLayout_CurrentOrganizationFragment
|
||||
...TargetSettingsPage_OrganizationFragment
|
||||
me {
|
||||
...CDNAccessTokens_MeFragment
|
||||
|
|
@ -1045,7 +1041,6 @@ const TargetSettingsPageQuery = graphql(`
|
|||
id
|
||||
cleanId
|
||||
type
|
||||
...TargetLayout_CurrentProjectFragment
|
||||
}
|
||||
target(selector: { organization: $organizationId, project: $projectId, target: $targetId }) {
|
||||
id
|
||||
|
|
@ -1054,10 +1049,6 @@ const TargetSettingsPageQuery = graphql(`
|
|||
graphqlEndpointUrl
|
||||
...TargetSettingsPage_TargetFragment
|
||||
}
|
||||
me {
|
||||
...TargetLayout_MeFragment
|
||||
}
|
||||
...TargetLayout_IsCDNEnabledFragment
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -1075,12 +1066,9 @@ function TargetSettingsContent(props: {
|
|||
},
|
||||
});
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const currentProject = query.data?.project;
|
||||
const currentTarget = query.data?.target;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
const isCDNEnabled = query.data;
|
||||
const organizationForSettings = useFragment(
|
||||
TargetSettingsPage_OrganizationFragment,
|
||||
currentOrganization,
|
||||
|
|
@ -1103,11 +1091,6 @@ function TargetSettingsContent(props: {
|
|||
projectId={props.projectId}
|
||||
organizationId={props.organizationId}
|
||||
page={Page.Settings}
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
currentProject={currentProject ?? null}
|
||||
me={me ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
isCDNEnabled={isCDNEnabled ?? null}
|
||||
>
|
||||
<div className="py-6">
|
||||
<Title>Settings</Title>
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ function SchemaBlock({ schema, scrollToMe }: { schema: CompositeSchema; scrollTo
|
|||
|
||||
const Schemas_ProjectFragment = graphql(`
|
||||
fragment Schemas_ProjectFragment on Project {
|
||||
id
|
||||
type
|
||||
}
|
||||
`);
|
||||
|
|
@ -128,6 +129,7 @@ function Schemas({
|
|||
|
||||
const SchemaView_OrganizationFragment = graphql(`
|
||||
fragment SchemaView_OrganizationFragment on Organization {
|
||||
id
|
||||
cleanId
|
||||
me {
|
||||
...CanAccessTarget_MemberFragment
|
||||
|
|
@ -137,6 +139,7 @@ const SchemaView_OrganizationFragment = graphql(`
|
|||
|
||||
const SchemaView_ProjectFragment = graphql(`
|
||||
fragment SchemaView_ProjectFragment on Project {
|
||||
id
|
||||
cleanId
|
||||
type
|
||||
registryModel
|
||||
|
|
@ -268,26 +271,17 @@ function SchemaView(props: {
|
|||
|
||||
const TargetSchemaPageQuery = graphql(`
|
||||
query TargetSchemaPageQuery($organizationId: ID!, $projectId: ID!, $targetId: ID!) {
|
||||
organizations {
|
||||
...TargetLayout_OrganizationConnectionFragment
|
||||
}
|
||||
organization(selector: { organization: $organizationId }) {
|
||||
organization {
|
||||
...TargetLayout_CurrentOrganizationFragment
|
||||
...SchemaView_OrganizationFragment
|
||||
}
|
||||
}
|
||||
project(selector: { organization: $organizationId, project: $projectId }) {
|
||||
...TargetLayout_CurrentProjectFragment
|
||||
...SchemaView_ProjectFragment
|
||||
}
|
||||
target(selector: { organization: $organizationId, project: $projectId, target: $targetId }) {
|
||||
...SchemaView_TargetFragment
|
||||
}
|
||||
me {
|
||||
...TargetLayout_MeFragment
|
||||
}
|
||||
...TargetLayout_IsCDNEnabledFragment
|
||||
}
|
||||
`);
|
||||
|
||||
|
|
@ -306,12 +300,9 @@ function TargetSchemaPage(props: { organizationId: string; projectId: string; ta
|
|||
return <QueryError organizationId={props.organizationId} error={query.error} />;
|
||||
}
|
||||
|
||||
const me = query.data?.me;
|
||||
const currentOrganization = query.data?.organization?.organization;
|
||||
const currentProject = query.data?.project;
|
||||
const organizationConnection = query.data?.organizations;
|
||||
const target = query.data?.target;
|
||||
const isCDNEnabled = query.data;
|
||||
|
||||
// TODO(router) check if it works
|
||||
const serviceNameFromHash = router.latestLocation.hash?.replace('service-', '') ?? null;
|
||||
|
|
@ -322,11 +313,6 @@ function TargetSchemaPage(props: { organizationId: string; projectId: string; ta
|
|||
projectId={props.projectId}
|
||||
organizationId={props.organizationId}
|
||||
page={Page.Schema}
|
||||
currentOrganization={currentOrganization ?? null}
|
||||
currentProject={currentProject ?? null}
|
||||
me={me ?? null}
|
||||
organizations={organizationConnection ?? null}
|
||||
isCDNEnabled={isCDNEnabled ?? null}
|
||||
>
|
||||
<div className="flex flex-row items-center justify-between py-6">
|
||||
<div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue