mirror of
https://github.com/graphql-hive/console
synced 2026-04-21 14:37:17 +00:00
clean up sub page nav button/link usage and various ui colors (#7641)
This commit is contained in:
parent
1bb6656dee
commit
068189f95e
13 changed files with 89 additions and 83 deletions
|
|
@ -0,0 +1,32 @@
|
|||
import { Button } from '@/components/ui/button';
|
||||
import { cn } from '@/lib/utils';
|
||||
|
||||
type SubPageNavigationLinkProps = {
|
||||
dataCy?: string;
|
||||
isActive: boolean;
|
||||
onClick: () => void;
|
||||
title: string;
|
||||
};
|
||||
|
||||
export function SubPageNavigationLink({
|
||||
dataCy,
|
||||
isActive,
|
||||
onClick,
|
||||
title,
|
||||
}: SubPageNavigationLinkProps) {
|
||||
return (
|
||||
<Button
|
||||
data-cy={dataCy}
|
||||
variant="ghost"
|
||||
className={cn(
|
||||
isActive
|
||||
? 'text-neutral-12 bg-neutral-5 hover:bg-neutral-5 dark:bg-neutral-3 dark:hover:bg-neutral-3'
|
||||
: 'text-neutral-11 hover:bg-transparent hover:underline',
|
||||
'justify-start',
|
||||
)}
|
||||
onClick={onClick}
|
||||
>
|
||||
{title}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
|
|
@ -101,7 +101,7 @@ export function SchemaExplorerUsageStats(props: {
|
|||
<tr key={op.hash}>
|
||||
<td className="px-2 pl-0 text-left">
|
||||
<NextLink
|
||||
className="text-neutral-2 hover:text-neutral-2 hover:underline hover:underline-offset-2"
|
||||
className="text-orange-800 hover:text-orange-800 hover:underline hover:underline-offset-2 dark:text-orange-500 dark:hover:text-orange-500"
|
||||
to="/$organizationSlug/$projectSlug/$targetSlug/insights/$operationName/$operationHash"
|
||||
params={{
|
||||
organizationSlug: props.organizationSlug,
|
||||
|
|
@ -146,7 +146,7 @@ export function SchemaExplorerUsageStats(props: {
|
|||
{usage.usedByClients.map(clientName => (
|
||||
<li key={clientName} className="font-bold">
|
||||
<NextLink
|
||||
className="text-neutral-2 hover:text-neutral-2 hover:underline hover:underline-offset-2"
|
||||
className="text-orange-800 hover:text-orange-800 hover:underline hover:underline-offset-2 dark:text-orange-500 dark:hover:text-orange-500"
|
||||
to="/$organizationSlug/$projectSlug/$targetSlug/insights/client/$name"
|
||||
params={{
|
||||
organizationSlug: props.organizationSlug,
|
||||
|
|
|
|||
|
|
@ -289,16 +289,25 @@ export function SchemaVariantFilter(props: {
|
|||
return (
|
||||
<TooltipProvider>
|
||||
<Tabs defaultValue={props.variant}>
|
||||
<TabsList>
|
||||
<TabsList className="bg-neutral-5">
|
||||
{variants.map(variant => (
|
||||
<Tooltip key={variant.value}>
|
||||
<TooltipTrigger asChild>
|
||||
{props.variant === variant.value ? (
|
||||
<div>
|
||||
<TabsTrigger value={variant.value}>{variant.label}</TabsTrigger>
|
||||
<TabsTrigger
|
||||
className="dark:data-[state=active]:bg-neutral-7 data-[state=active]:text-neutral-12"
|
||||
value={variant.value}
|
||||
>
|
||||
{variant.label}
|
||||
</TabsTrigger>
|
||||
</div>
|
||||
) : (
|
||||
<TabsTrigger value={variant.value} asChild>
|
||||
<TabsTrigger
|
||||
className="text-neutral-9 hover:text-neutral-11"
|
||||
value={variant.value}
|
||||
asChild
|
||||
>
|
||||
<Link
|
||||
to={variant.pathname}
|
||||
params={{
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ function SubgraphChip(props: {
|
|||
service: props.text,
|
||||
}}
|
||||
style={{ backgroundColor: stringToHslColor(props.text) }}
|
||||
className="my-[2px] ml-[6px] inline-block h-[22px] max-w-[100px] cursor-pointer items-center justify-between truncate rounded-[16px] py-0 pl-[8px] pr-[6px] text-[10px] font-normal normal-case leading-loose text-[#4f4f4f] drop-shadow-md"
|
||||
className="my-[2px] ml-[6px] inline-block h-[22px] max-w-[100px] cursor-pointer items-center justify-between truncate rounded-[16px] py-0 pl-[8px] pr-[6px] text-[10px] font-normal normal-case leading-loose text-[#4f4f4f]"
|
||||
>
|
||||
{props.text}
|
||||
<PackageIcon size={10} className="ml-1 inline-block" />
|
||||
|
|
|
|||
|
|
@ -235,7 +235,7 @@ function ChangeItem(
|
|||
<div>
|
||||
<span className="text-neutral-10">{labelize(change.message)}</span>
|
||||
{change.isSafeBasedOnUsage && (
|
||||
<span className="cursor-pointer text-yellow-500">
|
||||
<span className="cursor-pointer text-yellow-700 dark:text-yellow-500">
|
||||
{' '}
|
||||
<CheckIcon className="inline size-3" /> Safe based on usage data
|
||||
</span>
|
||||
|
|
@ -358,7 +358,7 @@ function ChangeItem(
|
|||
<TableRow key={hash}>
|
||||
<TableCell className="font-medium">
|
||||
<Popover>
|
||||
<PopoverTrigger className="text-neutral-2 hover:text-neutral-2 hover:underline hover:underline-offset-4">
|
||||
<PopoverTrigger className="text-orange-800 hover:text-orange-800 hover:underline-offset-4 dark:text-orange-500 dark:hover:text-orange-500">
|
||||
{hash.substring(0, 4)}_{name}
|
||||
</PopoverTrigger>
|
||||
<PopoverContent side="right">
|
||||
|
|
|
|||
|
|
@ -1,16 +1,15 @@
|
|||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { useQuery, UseQueryExecute } from 'urql';
|
||||
import { OrganizationLayout, Page } from '@/components/layouts/organization';
|
||||
import { SubPageNavigationLink } from '@/components/navigation/sub-page-navigation-link';
|
||||
import { OrganizationInvitations } from '@/components/organization/members/invitations';
|
||||
import { OrganizationMembers } from '@/components/organization/members/list';
|
||||
import { OrganizationMemberRoles } from '@/components/organization/members/roles';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Meta } from '@/components/ui/meta';
|
||||
import { NavLayout, PageLayout, PageLayoutContent } from '@/components/ui/page-content-layout';
|
||||
import { QueryError } from '@/components/ui/query-error';
|
||||
import { FragmentType, graphql, useFragment } from '@/gql';
|
||||
import { useRedirect } from '@/lib/access/common';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { organizationMembersRoute } from '../router';
|
||||
|
||||
const OrganizationMembersPage_OrganizationFragment = graphql(`
|
||||
|
|
@ -72,23 +71,14 @@ function PageContent(props: {
|
|||
return (
|
||||
<PageLayout>
|
||||
<NavLayout>
|
||||
{filteredSubPages.map(subPage => {
|
||||
return (
|
||||
<Button
|
||||
key={subPage.key}
|
||||
variant="ghost"
|
||||
className={cn(
|
||||
props.page === subPage.key
|
||||
? 'bg-neutral-4 hover:bg-neutral-4 dark:bg-neutral-3 dark:hover:bg-neutral-3'
|
||||
: 'hover:bg-transparent hover:underline',
|
||||
'justify-start',
|
||||
)}
|
||||
onClick={() => props.onPageChange(subPage.key)}
|
||||
>
|
||||
{subPage.title}
|
||||
</Button>
|
||||
);
|
||||
})}
|
||||
{filteredSubPages.map(subPage => (
|
||||
<SubPageNavigationLink
|
||||
key={subPage.key}
|
||||
isActive={props.page === subPage.key}
|
||||
onClick={() => props.onPageChange(subPage.key)}
|
||||
title={subPage.title}
|
||||
/>
|
||||
))}
|
||||
</NavLayout>
|
||||
<PageLayoutContent>
|
||||
{props.page === 'list' ? (
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { useForm } from 'react-hook-form';
|
|||
import { useMutation, useQuery } from 'urql';
|
||||
import { z } from 'zod';
|
||||
import { OrganizationLayout, Page } from '@/components/layouts/organization';
|
||||
import { SubPageNavigationLink } from '@/components/navigation/sub-page-navigation-link';
|
||||
import { AccessTokensSubPage } from '@/components/organization/settings/access-tokens/access-tokens-sub-page';
|
||||
import { OIDCIntegrationSection } from '@/components/organization/settings/oidc-integration-section';
|
||||
import { PersonalAccessTokensSubPage } from '@/components/organization/settings/personal-access-tokens/personal-access-tokens-sub-page';
|
||||
|
|
@ -39,7 +40,6 @@ import { env } from '@/env/frontend';
|
|||
import { FragmentType, graphql, useFragment } from '@/gql';
|
||||
import { useRedirect } from '@/lib/access/common';
|
||||
import { useToggle } from '@/lib/hooks';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useRouter } from '@tanstack/react-router';
|
||||
|
||||
|
|
@ -715,10 +715,9 @@ function SettingsPageContent(props: {
|
|||
<NavLayout>
|
||||
{subPages.map(subPage => {
|
||||
return (
|
||||
<Button
|
||||
<SubPageNavigationLink
|
||||
key={subPage.key}
|
||||
data-cy={`target-settings-${subPage.key}-link`}
|
||||
variant="ghost"
|
||||
isActive={resolvedPage.key === subPage.key}
|
||||
onClick={() => {
|
||||
void router.navigate({
|
||||
search: {
|
||||
|
|
@ -726,15 +725,8 @@ function SettingsPageContent(props: {
|
|||
},
|
||||
});
|
||||
}}
|
||||
className={cn(
|
||||
resolvedPage.key === subPage.key
|
||||
? 'bg-neutral-3 hover:bg-neutral-3'
|
||||
: 'hover:bg-transparent hover:underline',
|
||||
'w-full justify-start text-left',
|
||||
)}
|
||||
>
|
||||
{subPage.title}
|
||||
</Button>
|
||||
title={subPage.title}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</NavLayout>
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import { useForm } from 'react-hook-form';
|
|||
import { useMutation, useQuery } from 'urql';
|
||||
import { z } from 'zod';
|
||||
import { Page, ProjectLayout } from '@/components/layouts/project';
|
||||
import { SubPageNavigationLink } from '@/components/navigation/sub-page-navigation-link';
|
||||
import { PolicySettings } from '@/components/policy/policy-settings';
|
||||
import { ProjectAccessTokensSubPage } from '@/components/project/settings/access-tokens/project-access-tokens-sub-page';
|
||||
import { CompositionSettings } from '@/components/project/settings/composition';
|
||||
|
|
@ -38,7 +39,6 @@ import { ProjectType } from '@/gql/graphql';
|
|||
import { useRedirect } from '@/lib/access/common';
|
||||
import { getDocsUrl } from '@/lib/docs-url';
|
||||
import { useNotifications, useToggle } from '@/lib/hooks';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { useRouter } from '@tanstack/react-router';
|
||||
|
||||
|
|
@ -589,9 +589,9 @@ function ProjectSettingsContent(props: {
|
|||
<PageLayout>
|
||||
<NavLayout>
|
||||
{subPages.map(subPage => (
|
||||
<Button
|
||||
<SubPageNavigationLink
|
||||
key={subPage.key}
|
||||
variant="ghost"
|
||||
isActive={resolvedPage.key === subPage.key}
|
||||
onClick={() => {
|
||||
void router.navigate({
|
||||
search: {
|
||||
|
|
@ -599,15 +599,8 @@ function ProjectSettingsContent(props: {
|
|||
},
|
||||
});
|
||||
}}
|
||||
className={cn(
|
||||
resolvedPage.key === subPage.key
|
||||
? 'bg-neutral-3 hover:bg-neutral-3'
|
||||
: 'hover:bg-transparent hover:underline',
|
||||
'w-full justify-start text-left',
|
||||
)}
|
||||
>
|
||||
{subPage.title}
|
||||
</Button>
|
||||
title={subPage.title}
|
||||
/>
|
||||
))}
|
||||
</NavLayout>
|
||||
<PageLayoutContent>
|
||||
|
|
|
|||
|
|
@ -480,7 +480,7 @@ function DefaultSchemaView(props: {
|
|||
return (
|
||||
<>
|
||||
<Tabs value={selectedView} onValueChange={value => setSelectedView(value)}>
|
||||
<TabsList className="bg-neutral-3 border-neutral-3 w-full justify-start rounded-none border-x border-b">
|
||||
<TabsList className="bg-neutral-5 dark:bg-neutral-3 border-neutral-5 dark:border-neutral-3 w-full justify-start rounded-none border-x border-b">
|
||||
{items.map(item => (
|
||||
<TabsTrigger key={item.value} value={item.value} disabled={item.isDisabled}>
|
||||
{item.icon}
|
||||
|
|
@ -489,7 +489,7 @@ function DefaultSchemaView(props: {
|
|||
))}
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
<div className="border-neutral-3 min-h-[850px] rounded-md rounded-t-none border border-t-0">
|
||||
<div className="dark:border-neutral-3 border-neutral-5 grow rounded-md rounded-t-none border border-t-0">
|
||||
{selectedView === 'details' && (
|
||||
<div className="my-4 px-4">
|
||||
{!schemaCheck.schemaPolicyWarnings?.edges?.length &&
|
||||
|
|
@ -693,7 +693,7 @@ function ContractCheckView(props: {
|
|||
))}
|
||||
</TabsList>
|
||||
</Tabs>
|
||||
<div className="border-neutral-3 min-h-[850px] rounded-md rounded-t-none border border-t-0">
|
||||
<div className="dark:border-neutral-3 border-neutral-5 grow rounded-md rounded-t-none border border-t-0">
|
||||
{selectedView === 'details' && (
|
||||
<div className="my-4 px-4">
|
||||
{contractCheck.schemaCompositionErrors && (
|
||||
|
|
@ -874,8 +874,11 @@ function SchemaChecksView(props: {
|
|||
value={selectedItem}
|
||||
onValueChange={value => setSelectedItem(value)}
|
||||
>
|
||||
<TabsList className="w-full justify-start rounded-b-none px-2 py-0">
|
||||
<TabsTrigger value="default" className="mt-1 py-2 data-[state=active]:rounded-b-none">
|
||||
<TabsList className="w-full justify-start rounded-b-none bg-transparent px-2 py-0">
|
||||
<TabsTrigger
|
||||
value="default"
|
||||
className="data-[state=active]:bg-neutral-5 dark:data-[state=active]:bg-neutral-3 border-neutral-5 dark:border-neutral-3 mt-1 rounded-b-none border py-2"
|
||||
>
|
||||
<span>Default Graph</span>
|
||||
<TooltipProvider>
|
||||
<Tooltip>
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ const Navigation = (
|
|||
<span className="overflow-hidden truncate">{edge.node.meta.author}</span>
|
||||
</div>
|
||||
) : null}
|
||||
<div className="mb-1.5 mt-2.5 flex align-middle text-xs font-medium text-[#c4c4c4]">
|
||||
<div className="text-neutral-10 mb-1.5 mt-2.5 flex align-middle text-xs font-medium">
|
||||
<div
|
||||
className={cn(
|
||||
edge.node.__typename === 'FailedSchemaCheck' ? 'text-red-500' : null,
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ const ProposalsListPage = (props: {
|
|||
</span>
|
||||
<span className="text-neutral-10">{proposal.stage}</span>
|
||||
</div>
|
||||
<div className="mb-1.5 mt-2 flex flex-col gap-x-1 align-middle text-xs font-medium text-[#c4c4c4] md:flex-row">
|
||||
<div className="text-neutral-10 mb-1.5 mt-2 flex flex-col gap-x-1 align-middle text-xs font-medium md:flex-row">
|
||||
<div className="truncate">
|
||||
proposed <TimeAgo date={proposal.updatedAt} />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import { useMutation, useQuery } from 'urql';
|
|||
import * as Yup from 'yup';
|
||||
import { z } from 'zod';
|
||||
import { Page, TargetLayout } from '@/components/layouts/target';
|
||||
import { SubPageNavigationLink } from '@/components/navigation/sub-page-navigation-link';
|
||||
import { SchemaEditor } from '@/components/schema-editor';
|
||||
import { CDNAccessTokens } from '@/components/target/settings/cdn-access-tokens';
|
||||
import { CreateAccessTokenModal } from '@/components/target/settings/registry-access-token';
|
||||
|
|
@ -53,7 +54,6 @@ import {
|
|||
import { useRedirect } from '@/lib/access/common';
|
||||
import { subDays } from '@/lib/date-time';
|
||||
import { useToggle } from '@/lib/hooks';
|
||||
import { cn } from '@/lib/utils';
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { RadioGroupIndicator } from '@radix-ui/react-radio-group';
|
||||
import { Link, useRouter } from '@tanstack/react-router';
|
||||
|
|
@ -1865,10 +1865,10 @@ function TargetSettingsContent(props: {
|
|||
<NavLayout>
|
||||
{subPages.map(subPage => {
|
||||
return (
|
||||
<Button
|
||||
<SubPageNavigationLink
|
||||
key={subPage.key}
|
||||
data-cy={`target-settings-${subPage.key}-link`}
|
||||
variant="ghost"
|
||||
dataCy={`target-settings-${subPage.key}-link`}
|
||||
isActive={resolvedPage.key === subPage.key}
|
||||
onClick={() => {
|
||||
void router.navigate({
|
||||
search: {
|
||||
|
|
@ -1876,15 +1876,8 @@ function TargetSettingsContent(props: {
|
|||
},
|
||||
});
|
||||
}}
|
||||
className={cn(
|
||||
resolvedPage.key === subPage.key
|
||||
? 'bg-neutral-3 hover:bg-neutral-3'
|
||||
: 'hover:bg-transparent hover:underline',
|
||||
'w-full justify-start text-left',
|
||||
)}
|
||||
>
|
||||
{subPage.title}
|
||||
</Button>
|
||||
title={subPage.title}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</NavLayout>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useState } from 'react';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { SubPageNavigationLink } from '@/components/navigation/sub-page-navigation-link';
|
||||
import { NavLayout, PageLayout, PageLayoutContent } from '@/components/ui/page-content-layout';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
|
|
@ -28,18 +28,12 @@ const Template: StoryObj<typeof PageLayout> = {
|
|||
<NavLayout>
|
||||
{subPages.map(subPage => {
|
||||
return (
|
||||
<Button
|
||||
<SubPageNavigationLink
|
||||
key={subPage.key}
|
||||
variant="ghost"
|
||||
isActive={page === subPage.key}
|
||||
onClick={() => setPage(subPage.key)}
|
||||
className={
|
||||
page === subPage.key
|
||||
? 'bg-neutral-3 hover:bg-neutral-3'
|
||||
: 'hover:bg-transparent hover:underline'
|
||||
}
|
||||
>
|
||||
{subPage.title}
|
||||
</Button>
|
||||
title={subPage.title}
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</NavLayout>
|
||||
|
|
|
|||
Loading…
Reference in a new issue