feat: Add resource ID to pages (#6584)

This commit is contained in:
jdolle 2025-03-19 05:37:49 -07:00 committed by GitHub
parent cbf8b935f0
commit d1e6ab094b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 49 additions and 2 deletions

View file

@ -0,0 +1,5 @@
---
'hive': patch
---
Add readonly resource ID to settings pages

View file

@ -4,7 +4,7 @@ import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { useClipboard } from '@/lib/hooks';
export function InputCopy(props: { value: string }) {
export function InputCopy(props: { value: string; className?: string }) {
const [isCopied, setIsCopied] = useState(false);
const copyToClipboard = useClipboard();
@ -31,7 +31,7 @@ export function InputCopy(props: { value: string }) {
type="text"
value={props.value}
readOnly
className="bg-secondary truncate text-white"
className={`bg-secondary truncate text-white ${props.className}`}
onFocus={ev => ev.target.select()}
/>
</div>

View file

@ -0,0 +1,27 @@
import { ReactElement } from 'react';
import { InfoCircledIcon } from '@radix-ui/react-icons';
import { InputCopy } from './input-copy';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './tooltip';
/** Renders readonly properties for resources. Used on settings pages. */
export function ResourceDetails(props: { id: string }): ReactElement {
return (
<div className="flex items-center">
<div className="border-input text-muted-foreground h-10 whitespace-nowrap rounded-md rounded-r-none border-y border-l bg-gray-900 px-3 py-2 text-sm">
Resource ID
</div>
<InputCopy value={props.id} className="rounded-l-none" />
<TooltipProvider>
<Tooltip>
<TooltipTrigger>
<InfoCircledIcon className="ml-2 size-4" />
</TooltipTrigger>
<TooltipContent className="max-w-sm text-pretty">
This UUID can be used in API calls or CLI commands to Hive instead of passing the full
resource path. I.e. "org/project/target".
</TooltipContent>
</Tooltip>
</TooltipProvider>
</div>
);
}

View file

@ -30,6 +30,7 @@ import { Input } from '@/components/ui/input';
import { Meta } from '@/components/ui/meta';
import { NavLayout, PageLayout, PageLayoutContent } from '@/components/ui/page-content-layout';
import { QueryError } from '@/components/ui/query-error';
import { ResourceDetails } from '@/components/ui/resource-details';
import { useToast } from '@/components/ui/use-toast';
import { TransferOrganizationOwnershipModal } from '@/components/v2/modals';
import { env } from '@/env/frontend';
@ -263,6 +264,7 @@ const SettingsPageRenderer = (props: {
return (
<div className="flex flex-col gap-y-4">
<ResourceDetails id={organization.id} />
{organization.viewerCanModifySlug && (
<Form {...slugForm}>
<form onSubmit={slugForm.handleSubmit(onSlugFormSubmit)}>

View file

@ -30,6 +30,7 @@ import { Input } from '@/components/ui/input';
import { Meta } from '@/components/ui/meta';
import { Subtitle, Title } from '@/components/ui/page';
import { QueryError } from '@/components/ui/query-error';
import { ResourceDetails } from '@/components/ui/resource-details';
import { useToast } from '@/components/ui/use-toast';
import { env } from '@/env/frontend';
import { graphql, useFragment } from '@/gql';
@ -319,6 +320,7 @@ const ProjectSettingsPage_OrganizationFragment = graphql(`
const ProjectSettingsPage_ProjectFragment = graphql(`
fragment ProjectSettingsPage_ProjectFragment on Project {
id
slug
type
isProjectNameInGitHubCheckEnabled
@ -399,6 +401,7 @@ function ProjectSettingsContent(props: { organizationSlug: string; projectSlug:
<div className="flex flex-col gap-y-4">
{project && organization ? (
<>
<ResourceDetails id={project.id} />
<ProjectSettingsPage_SlugForm
organizationSlug={props.organizationSlug}
projectSlug={props.projectSlug}

View file

@ -35,6 +35,7 @@ import {
} from '@/components/ui/page-content-layout';
import { QueryError } from '@/components/ui/query-error';
import { RadioGroup, RadioGroupItem } from '@/components/ui/radio-group';
import { ResourceDetails } from '@/components/ui/resource-details';
import { Spinner } from '@/components/ui/spinner';
import { TimeAgo } from '@/components/ui/time-ago';
import { useToast } from '@/components/ui/use-toast';
@ -1169,6 +1170,14 @@ const TargetSettingsPageQuery = graphql(`
}
`);
function TargetInfo(props: { targetId: string }) {
return (
<div>
<ResourceDetails id={props.targetId} />
</div>
);
}
function TargetSettingsContent(props: {
organizationSlug: string;
projectSlug: string;
@ -1313,6 +1322,7 @@ function TargetSettingsContent(props: {
<div className="space-y-12">
{resolvedPage.key === 'general' ? (
<>
<TargetInfo targetId={currentTarget.id} />
<TargetSlug
targetSlug={props.targetSlug}
projectSlug={props.projectSlug}