This commit is contained in:
Stephen Zhou 2026-05-09 17:23:34 +08:00
parent e16988d8a9
commit bdd73d2846
No known key found for this signature in database
24 changed files with 105 additions and 105 deletions

View File

@ -139,7 +139,7 @@ function CreateInstanceForm() {
type="text" type="text"
placeholder={sourceApp?.name ?? t('createModal.namePlaceholder')} placeholder={sourceApp?.name ?? t('createModal.namePlaceholder')}
required required
className="flex h-8 items-center rounded-lg border-[0.5px] border-components-input-border-active bg-components-input-bg-normal px-3 text-[13px] font-medium text-text-secondary outline-hidden placeholder:text-text-quaternary" className="flex h-8 items-center rounded-lg border border-components-input-border-active bg-components-input-bg-normal px-3 system-sm-medium text-text-secondary outline-hidden placeholder:text-text-quaternary"
/> />
</div> </div>
@ -151,7 +151,7 @@ function CreateInstanceForm() {
id="instance-desc" id="instance-desc"
name="description" name="description"
placeholder={t('createModal.descriptionPlaceholder')} placeholder={t('createModal.descriptionPlaceholder')}
className="min-h-[80px] rounded-lg border-[0.5px] border-components-input-border-active bg-components-input-bg-normal px-3 py-2 text-[13px] text-text-secondary outline-hidden placeholder:text-text-quaternary" className="min-h-20 rounded-lg border border-components-input-border-active bg-components-input-bg-normal px-3 py-2 system-sm-regular text-text-secondary outline-hidden placeholder:text-text-quaternary"
/> />
</div> </div>
@ -176,7 +176,7 @@ export function CreateInstanceModal() {
open={open} open={open}
onOpenChange={next => !next && closeModal()} onOpenChange={next => !next && closeModal()}
> >
<DialogContent className="w-[520px] max-w-[90vw]"> <DialogContent className="w-130 max-w-[90vw]">
<DialogCloseButton /> <DialogCloseButton />
{open && <CreateInstanceForm />} {open && <CreateInstanceForm />}
</DialogContent> </DialogContent>

View File

@ -49,14 +49,14 @@ export function DeployDrawer() {
open={open} open={open}
onOpenChange={next => !next && closeDeployDrawer()} onOpenChange={next => !next && closeDeployDrawer()}
> >
<DialogContent className="w-[560px] max-w-[90vw]"> <DialogContent className="w-140 max-w-[90vw]">
<DialogCloseButton /> <DialogCloseButton />
{!drawerAppInstanceId {!drawerAppInstanceId
? <div className="p-4 text-text-tertiary">{t('deployDrawer.notFound')}</div> ? <div className="p-4 text-text-tertiary">{t('deployDrawer.notFound')}</div>
: (!releaseHistory || !environmentOptionsReply) : (!releaseHistory || !environmentOptionsReply)
? ( ? (
<div className="flex items-center gap-2 p-4 system-sm-regular text-text-tertiary"> <div className="flex items-center gap-2 p-4 system-sm-regular text-text-tertiary">
<span className="h-4 w-4 animate-spin rounded-full border-2 border-components-panel-border border-t-transparent" /> <span className="size-4 animate-spin rounded-full border-2 border-components-panel-border border-t-transparent" />
{t('createModal.loadingApps')} {t('createModal.loadingApps')}
</div> </div>
) )

View File

@ -53,7 +53,7 @@ export function DeploymentSelect({ value, onChange, options, placeholder }: Sele
> >
<SelectTrigger <SelectTrigger
className={cn( className={cn(
'h-8 min-w-0 border-[0.5px] border-components-input-border-active px-2 text-left system-sm-medium', 'h-8 min-w-0 border border-components-input-border-active px-2 text-left system-sm-medium',
!selectedOption && 'text-text-quaternary', !selectedOption && 'text-text-quaternary',
)} )}
> >

View File

@ -25,7 +25,7 @@ export function StatusBadge({ status, className }: {
return ( return (
<span className={cn(baseBadge, statusStyles[status], className)}> <span className={cn(baseBadge, statusStyles[status], className)}>
{status === 'deploying' && ( {status === 'deploying' && (
<span className="h-1.5 w-1.5 animate-pulse rounded-full bg-current" /> <span className="size-1.5 animate-pulse rounded-full bg-current" />
)} )}
{t(statusKey[status])} {t(statusKey[status])}
</span> </span>

View File

@ -8,7 +8,7 @@ export function AccessTab({ appInstanceId }: {
appInstanceId: string appInstanceId: string
}) { }) {
return ( return (
<div className="flex w-full max-w-[960px] flex-col gap-5 p-6"> <div className="flex w-full max-w-240 flex-col gap-5 p-6">
<AccessPermissionsSection appInstanceId={appInstanceId} /> <AccessPermissionsSection appInstanceId={appInstanceId} />
<AccessChannelsSection appInstanceId={appInstanceId} /> <AccessChannelsSection appInstanceId={appInstanceId} />
<DeveloperApiSection appInstanceId={appInstanceId} /> <DeveloperApiSection appInstanceId={appInstanceId} />

View File

@ -39,23 +39,23 @@ function ApiKeyRow({ appInstanceId, apiKey }: {
return ( return (
<div className="flex items-center gap-3 py-1.5"> <div className="flex items-center gap-3 py-1.5">
<div className="flex min-w-[140px] flex-col"> <div className="flex min-w-35 flex-col">
<span className="system-sm-medium text-text-primary">{apiKey.name || apiKey.id}</span> <span className="system-sm-medium text-text-primary">{apiKey.name || apiKey.id}</span>
<span className="system-xs-regular text-text-tertiary"> <span className="system-xs-regular text-text-tertiary">
{t('access.api.envPrefix', { env: environmentLabel })} {t('access.api.envPrefix', { env: environmentLabel })}
</span> </span>
</div> </div>
<div className="flex min-w-0 flex-1 items-center gap-1 rounded-lg border-[0.5px] border-components-input-border-active bg-components-input-bg-normal pr-1 pl-2"> <div className="flex min-w-0 flex-1 items-center gap-1 rounded-lg border border-components-input-border-active bg-components-input-bg-normal pr-1 pl-2">
<div className="min-w-0 flex-1 truncate font-mono text-[13px] font-medium text-text-secondary"> <div className="min-w-0 flex-1 truncate font-mono system-sm-medium text-text-secondary">
{displayValue} {displayValue}
</div> </div>
<button <button
type="button" type="button"
onClick={handleRevoke} onClick={handleRevoke}
aria-label={t('access.revoke')} aria-label={t('access.revoke')}
className="flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-text-tertiary hover:bg-state-destructive-hover hover:text-text-destructive" className="flex size-6 shrink-0 items-center justify-center rounded-md text-text-tertiary hover:bg-state-destructive-hover hover:text-text-destructive"
> >
<span className="i-ri-delete-bin-line h-3.5 w-3.5" /> <span className="i-ri-delete-bin-line size-3.5" />
</button> </button>
</div> </div>
</div> </div>
@ -131,12 +131,12 @@ export function ApiKeyGenerateMenu({ appInstanceId, environments, apiKeys }: {
disabled && 'cursor-not-allowed opacity-50', disabled && 'cursor-not-allowed opacity-50',
)} )}
> >
<span className="i-ri-add-line h-3.5 w-3.5" /> <span className="i-ri-add-line size-3.5" />
{t('access.api.newKey')} {t('access.api.newKey')}
<span className="i-ri-arrow-down-s-line h-3.5 w-3.5" /> <span className="i-ri-arrow-down-s-line size-3.5" />
</DropdownMenuTrigger> </DropdownMenuTrigger>
{open && !disabled && ( {open && !disabled && (
<DropdownMenuContent placement="bottom-end" sideOffset={4} popupClassName="w-[220px]"> <DropdownMenuContent placement="bottom-end" sideOffset={4} popupClassName="w-55">
{selectableEnvironments.map(env => ( {selectableEnvironments.map(env => (
<DropdownMenuItem <DropdownMenuItem
key={env.id} key={env.id}

View File

@ -115,7 +115,7 @@ export function AccessChannelsSection({
<CopyPill <CopyPill
label={t('access.cli.domain')} label={t('access.cli.domain')}
value={cliDomain} value={cliDomain}
className="min-w-[260px] flex-1" className="min-w-65 flex-1"
/> />
<a <a
href={cliDocsUrl} href={cliDocsUrl}
@ -123,7 +123,7 @@ export function AccessChannelsSection({
rel="noreferrer" rel="noreferrer"
className="inline-flex h-8 shrink-0 items-center gap-1.5 rounded-lg border border-components-button-secondary-border bg-components-button-secondary-bg px-3 system-sm-medium text-components-button-secondary-text hover:bg-components-button-secondary-bg-hover" className="inline-flex h-8 shrink-0 items-center gap-1.5 rounded-lg border border-components-button-secondary-border bg-components-button-secondary-bg px-3 system-sm-medium text-components-button-secondary-text hover:bg-components-button-secondary-bg-hover"
> >
<span className="i-ri-download-cloud-2-line h-3.5 w-3.5" /> <span className="i-ri-download-cloud-2-line size-3.5" />
{t('access.cli.install')} {t('access.cli.install')}
</a> </a>
<a <a
@ -132,7 +132,7 @@ export function AccessChannelsSection({
rel="noreferrer" rel="noreferrer"
className="inline-flex h-8 shrink-0 items-center gap-1.5 rounded-lg border border-components-button-secondary-border bg-components-button-secondary-bg px-3 system-sm-medium text-components-button-secondary-text hover:bg-components-button-secondary-bg-hover" className="inline-flex h-8 shrink-0 items-center gap-1.5 rounded-lg border border-components-button-secondary-border bg-components-button-secondary-bg px-3 system-sm-medium text-components-button-secondary-text hover:bg-components-button-secondary-bg-hover"
> >
<span className="i-ri-book-open-line h-3.5 w-3.5" /> <span className="i-ri-book-open-line size-3.5" />
{t('access.cli.docs')} {t('access.cli.docs')}
</a> </a>
</div> </div>

View File

@ -24,25 +24,25 @@ export function CopyPill({ label, value, prefix, className }: CopyPillProps) {
return ( return (
<div <div
className={cn( className={cn(
'flex h-8 items-center rounded-lg border-[0.5px] border-components-input-border-active bg-components-input-bg-normal pr-1 pl-1.5', 'flex h-8 items-center gap-1 rounded-lg border border-components-input-border-active bg-components-input-bg-normal pr-1 pl-1.5',
className, className,
)} )}
> >
<div className="mr-0.5 flex h-5 shrink-0 items-center rounded-md border border-divider-subtle px-1.5 text-[11px] font-medium text-text-tertiary"> <div className="flex h-5 shrink-0 items-center rounded-md border border-divider-subtle px-1.5 system-2xs-medium text-text-tertiary">
{label} {label}
</div> </div>
{prefix} {prefix}
<div className="min-w-0 flex-1 truncate px-1 font-mono text-[13px] font-medium text-text-secondary"> <div className="min-w-0 flex-1 truncate px-1 font-mono system-sm-medium text-text-secondary">
{value} {value}
</div> </div>
<div className="mx-1 h-[14px] w-px shrink-0 bg-divider-regular" /> <div className="h-3.5 w-px shrink-0 bg-divider-regular" />
<button <button
type="button" type="button"
onClick={() => copy(value)} onClick={() => copy(value)}
aria-label={t('access.copy')} aria-label={t('access.copy')}
className="flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary" className="flex size-6 shrink-0 items-center justify-center rounded-md text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary"
> >
<span className={cn(copied ? 'i-ri-check-line' : 'i-ri-file-copy-line', 'h-3.5 w-3.5')} /> <span className={cn(copied ? 'i-ri-check-line' : 'i-ri-file-copy-line', 'size-3.5')} />
</button> </button>
</div> </div>
) )
@ -58,10 +58,10 @@ type EndpointRowProps = {
export function EndpointRow({ envName, label, value, openLabel }: EndpointRowProps) { export function EndpointRow({ envName, label, value, openLabel }: EndpointRowProps) {
return ( return (
<div className="flex flex-wrap items-center gap-x-3 gap-y-1.5"> <div className="flex flex-wrap items-center gap-x-3 gap-y-1.5">
<span className="min-w-[140px] system-xs-regular text-text-tertiary"> <span className="min-w-35 system-xs-regular text-text-tertiary">
{envName} {envName}
</span> </span>
<CopyPill label={label} value={value} className="min-w-[260px] flex-1" /> <CopyPill label={label} value={value} className="min-w-65 flex-1" />
{openLabel && ( {openLabel && (
<a <a
href={value} href={value}
@ -69,7 +69,7 @@ export function EndpointRow({ envName, label, value, openLabel }: EndpointRowPro
rel="noreferrer" rel="noreferrer"
className="inline-flex h-8 shrink-0 items-center gap-1.5 rounded-lg border border-components-button-secondary-border bg-components-button-secondary-bg px-3 system-sm-medium text-components-button-secondary-text hover:bg-components-button-secondary-bg-hover" className="inline-flex h-8 shrink-0 items-center gap-1.5 rounded-lg border border-components-button-secondary-border bg-components-button-secondary-bg px-3 system-sm-medium text-components-button-secondary-text hover:bg-components-button-secondary-bg-hover"
> >
<span className="i-ri-external-link-line h-3.5 w-3.5" /> <span className="i-ri-external-link-line size-3.5" />
{openLabel} {openLabel}
</a> </a>
)} )}

View File

@ -69,9 +69,9 @@ function CreatedApiTokenCard({ appInstanceId }: {
type="button" type="button"
onClick={() => setCreatedApiToken(undefined)} onClick={() => setCreatedApiToken(undefined)}
aria-label={t('access.api.dismissToken')} aria-label={t('access.api.dismissToken')}
className="flex h-6 w-6 shrink-0 items-center justify-center rounded-md text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary" className="flex size-6 shrink-0 items-center justify-center rounded-md text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary"
> >
<span className="i-ri-close-line h-3.5 w-3.5" /> <span className="i-ri-close-line size-3.5" />
</button> </button>
</div> </div>
<CopyPill <CopyPill

View File

@ -50,15 +50,15 @@ function PermissionPicker({ value, disabled, onChange }: {
<DropdownMenuTrigger <DropdownMenuTrigger
disabled={disabled} disabled={disabled}
className={cn( className={cn(
'inline-flex h-8 min-w-[220px] items-center gap-2 rounded-lg border-[0.5px] border-components-input-border-active bg-components-input-bg-normal px-2.5 system-sm-regular text-text-secondary hover:bg-state-base-hover', 'inline-flex h-8 min-w-55 items-center gap-2 rounded-lg border border-components-input-border-active bg-components-input-bg-normal px-2.5 system-sm-regular text-text-secondary hover:bg-state-base-hover',
disabled && 'opacity-50', disabled && 'opacity-50',
)} )}
> >
<span className={cn(icon, 'h-4 w-4 shrink-0 text-text-tertiary')} /> <span className={cn(icon, 'size-4 shrink-0 text-text-tertiary')} />
<span className="flex-1 truncate text-left">{label}</span> <span className="flex-1 truncate text-left">{label}</span>
<span className="i-ri-arrow-down-s-line h-4 w-4 shrink-0 text-text-tertiary" /> <span className="i-ri-arrow-down-s-line size-4 shrink-0 text-text-tertiary" />
</DropdownMenuTrigger> </DropdownMenuTrigger>
<DropdownMenuContent placement="bottom-start" popupClassName="w-[340px] p-1"> <DropdownMenuContent placement="bottom-start" popupClassName="w-85 p-1">
{permissionOrder.map((kind) => { {permissionOrder.map((kind) => {
const itemIcon = permissionIcon[kind] const itemIcon = permissionIcon[kind]
const isSelected = kind === value const isSelected = kind === value
@ -68,7 +68,7 @@ function PermissionPicker({ value, disabled, onChange }: {
onSelect={() => onChange(kind)} onSelect={() => onChange(kind)}
className="mx-0 h-auto items-start gap-3 rounded-lg px-2.5 py-2" className="mx-0 h-auto items-start gap-3 rounded-lg px-2.5 py-2"
> >
<span className={cn(itemIcon, 'mt-0.5 h-4 w-4 shrink-0 text-text-tertiary')} /> <span className={cn(itemIcon, 'mt-0.5 size-4 shrink-0 text-text-tertiary')} />
<div className="flex min-w-0 flex-1 flex-col"> <div className="flex min-w-0 flex-1 flex-col">
<div className="flex min-w-0 items-center gap-2"> <div className="flex min-w-0 items-center gap-2">
<span className="truncate system-sm-medium text-text-primary"> <span className="truncate system-sm-medium text-text-primary">
@ -80,7 +80,7 @@ function PermissionPicker({ value, disabled, onChange }: {
</span> </span>
</div> </div>
{isSelected && ( {isSelected && (
<span className="mt-0.5 i-ri-check-line h-4 w-4 shrink-0 text-text-accent" /> <span className="mt-0.5 i-ri-check-line size-4 shrink-0 text-text-accent" />
)} )}
</DropdownMenuItem> </DropdownMenuItem>
) )
@ -149,7 +149,7 @@ function SubjectPill({ subject, disabled, onRemove }: {
return ( return (
<div className="inline-flex max-w-full items-center gap-1 rounded-full border border-divider-subtle bg-components-badge-white-to-dark px-2 py-1"> <div className="inline-flex max-w-full items-center gap-1 rounded-full border border-divider-subtle bg-components-badge-white-to-dark px-2 py-1">
<span className={cn(isGroup ? 'i-ri-group-line' : 'i-ri-user-line', 'h-3.5 w-3.5 shrink-0 text-text-tertiary')} /> <span className={cn(isGroup ? 'i-ri-group-line' : 'i-ri-user-line', 'size-3.5 shrink-0 text-text-tertiary')} />
<span className="truncate system-xs-medium text-text-secondary">{subject.name || subject.id}</span> <span className="truncate system-xs-medium text-text-secondary">{subject.name || subject.id}</span>
{isGroup && subject.memberCount != null && ( {isGroup && subject.memberCount != null && (
<span className="system-2xs-regular text-text-tertiary">{subject.memberCount}</span> <span className="system-2xs-regular text-text-tertiary">{subject.memberCount}</span>
@ -160,11 +160,11 @@ function SubjectPill({ subject, disabled, onRemove }: {
onClick={onRemove} onClick={onRemove}
aria-label={t('operation.remove', { ns: 'common' })} aria-label={t('operation.remove', { ns: 'common' })}
className={cn( className={cn(
'flex h-4 w-4 shrink-0 items-center justify-center rounded-full text-text-quaternary hover:text-text-secondary', 'flex size-4 shrink-0 items-center justify-center rounded-full text-text-quaternary hover:text-text-secondary',
disabled && 'cursor-not-allowed opacity-40', disabled && 'cursor-not-allowed opacity-40',
)} )}
> >
<span className="i-ri-close-circle-fill h-3.5 w-3.5" /> <span className="i-ri-close-circle-fill size-3.5" />
</button> </button>
</div> </div>
) )
@ -226,22 +226,22 @@ function SubjectPicker({
disabled && 'cursor-not-allowed opacity-50', disabled && 'cursor-not-allowed opacity-50',
)} )}
> >
<span className="i-ri-add-line h-3.5 w-3.5" /> <span className="i-ri-add-line size-3.5" />
{t('access.members.pickPlaceholder')} {t('access.members.pickPlaceholder')}
</button> </button>
)} )}
/> />
{open && ( {open && (
<PopoverContent placement="bottom-start" sideOffset={4} popupClassName="w-[360px] p-0"> <PopoverContent placement="bottom-start" sideOffset={4} popupClassName="w-90 p-0">
<div className="flex max-h-[420px] flex-col overflow-hidden rounded-xl border border-components-panel-border bg-components-panel-bg shadow-lg"> <div className="flex max-h-105 flex-col overflow-hidden rounded-xl border border-components-panel-border bg-components-panel-bg shadow-lg">
<div className="border-b border-divider-subtle p-2"> <div className="border-b border-divider-subtle p-2">
<div className="flex h-8 items-center gap-2 rounded-lg border-[0.5px] border-components-input-border-active bg-components-input-bg-normal px-2"> <div className="flex h-8 items-center gap-2 rounded-lg border border-components-input-border-active bg-components-input-bg-normal px-2">
<span className="i-ri-search-line h-4 w-4 shrink-0 text-text-tertiary" /> <span className="i-ri-search-line size-4 shrink-0 text-text-tertiary" />
<input <input
value={keyword} value={keyword}
onChange={e => setKeyword(e.target.value)} onChange={e => setKeyword(e.target.value)}
placeholder={t('access.members.searchPlaceholder')} placeholder={t('access.members.searchPlaceholder')}
className="min-w-0 flex-1 bg-transparent system-sm-regular text-text-primary outline-none placeholder:text-text-quaternary" className="min-w-0 flex-1 bg-transparent system-sm-regular text-text-primary outline-hidden placeholder:text-text-quaternary"
/> />
</div> </div>
</div> </div>
@ -249,7 +249,7 @@ function SubjectPicker({
{subjectsQuery.isLoading {subjectsQuery.isLoading
? ( ? (
<div className="flex h-16 items-center justify-center"> <div className="flex h-16 items-center justify-center">
<span className="h-4 w-4 animate-spin rounded-full border-2 border-components-panel-border border-t-transparent" /> <span className="size-4 animate-spin rounded-full border-2 border-components-panel-border border-t-transparent" />
</div> </div>
) )
: subjects.length === 0 : subjects.length === 0
@ -268,7 +268,7 @@ function SubjectPicker({
onClick={() => toggleSubject(subject)} onClick={() => toggleSubject(subject)}
className="flex w-full items-center gap-2 rounded-lg px-2 py-2 text-left hover:bg-state-base-hover" className="flex w-full items-center gap-2 rounded-lg px-2 py-2 text-left hover:bg-state-base-hover"
> >
<span className={cn(isGroup ? 'i-ri-group-line' : 'i-ri-user-line', 'h-4 w-4 shrink-0 text-text-tertiary')} /> <span className={cn(isGroup ? 'i-ri-group-line' : 'i-ri-user-line', 'size-4 shrink-0 text-text-tertiary')} />
<span className="min-w-0 flex-1 truncate system-sm-medium text-text-secondary"> <span className="min-w-0 flex-1 truncate system-sm-medium text-text-secondary">
{subject.name || subject.id} {subject.name || subject.id}
</span> </span>
@ -278,7 +278,7 @@ function SubjectPicker({
</span> </span>
)} )}
{isSelected && ( {isSelected && (
<span className="i-ri-check-line h-4 w-4 shrink-0 text-text-accent" /> <span className="i-ri-check-line size-4 shrink-0 text-text-accent" />
)} )}
</button> </button>
) )
@ -390,7 +390,7 @@ export function EnvironmentPermissionRow({
return ( return (
<div className="flex flex-col gap-1.5"> <div className="flex flex-col gap-1.5">
<div className="flex flex-wrap items-center gap-x-3 gap-y-1.5"> <div className="flex flex-wrap items-center gap-x-3 gap-y-1.5">
<span className="min-w-[140px] system-xs-regular text-text-tertiary"> <span className="min-w-35 system-xs-regular text-text-tertiary">
{environmentName(environment)} {environmentName(environment)}
</span> </span>
<PermissionPicker <PermissionPicker
@ -400,7 +400,7 @@ export function EnvironmentPermissionRow({
/> />
</div> </div>
{permissionKind === 'specific' && ( {permissionKind === 'specific' && (
<div className="flex flex-col gap-2 pl-0 sm:pl-[152px]"> <div className="flex flex-col gap-2 pl-0 sm:pl-38">
<div className="flex flex-wrap items-center gap-2"> <div className="flex flex-wrap items-center gap-2">
<SubjectPicker <SubjectPicker
appInstanceId={appInstanceId} appInstanceId={appInstanceId}

View File

@ -38,12 +38,12 @@ function NewDeploymentMenu({ appInstanceId, availableEnvs }: {
'hover:bg-components-button-primary-bg-hover', 'hover:bg-components-button-primary-bg-hover',
)} )}
> >
<span className="i-ri-rocket-line h-3.5 w-3.5" /> <span className="i-ri-rocket-line size-3.5" />
{t('deployTab.newDeployment')} {t('deployTab.newDeployment')}
<span className="i-ri-arrow-down-s-line h-3.5 w-3.5" /> <span className="i-ri-arrow-down-s-line size-3.5" />
</DropdownMenuTrigger> </DropdownMenuTrigger>
{open && ( {open && (
<DropdownMenuContent placement="bottom-end" sideOffset={4} popupClassName="w-[220px]"> <DropdownMenuContent placement="bottom-end" sideOffset={4} popupClassName="w-55">
<DropdownMenuItem <DropdownMenuItem
className="gap-2 px-3" className="gap-2 px-3"
onClick={() => { onClick={() => {
@ -99,7 +99,7 @@ export function DeployTab({ appInstanceId }: {
const availableEnvs = environmentOptions.filter(env => env.id && !deployedEnvIds.has(env.id)) const availableEnvs = environmentOptions.filter(env => env.id && !deployedEnvIds.has(env.id))
return ( return (
<div className="flex w-full max-w-[960px] flex-col gap-4 p-6"> <div className="flex w-full max-w-240 flex-col gap-4 p-6">
<div className="flex items-center justify-between"> <div className="flex items-center justify-between">
<div className="system-sm-semibold text-text-primary"> <div className="system-sm-semibold text-text-primary">
{t('deployTab.envCount')} {t('deployTab.envCount')}

View File

@ -95,12 +95,12 @@ function DeploymentRowActions({ appInstanceId, envId, row }: {
<DropdownMenu modal={false} open={menuOpen} onOpenChange={setMenuOpen}> <DropdownMenu modal={false} open={menuOpen} onOpenChange={setMenuOpen}>
<DropdownMenuTrigger <DropdownMenuTrigger
aria-label={t('deployTab.moreActions')} aria-label={t('deployTab.moreActions')}
className="flex h-7 w-7 items-center justify-center rounded-md text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary" className="flex size-7 items-center justify-center rounded-md text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary"
> >
<span className="i-ri-more-line h-4 w-4" /> <span className="i-ri-more-line size-4" />
</DropdownMenuTrigger> </DropdownMenuTrigger>
{menuOpen && ( {menuOpen && (
<DropdownMenuContent placement="bottom-end" sideOffset={4} popupClassName="w-[200px]"> <DropdownMenuContent placement="bottom-end" sideOffset={4} popupClassName="w-50">
<DropdownMenuItem <DropdownMenuItem
className="gap-2 px-3" className="gap-2 px-3"
onClick={handleRuntimeAction} onClick={handleRuntimeAction}
@ -130,7 +130,7 @@ function DeploymentEnvironmentRow({ appInstanceId, row, isExpanded, onToggle }:
const chevron = !isUndeployed && ( const chevron = !isUndeployed && (
<span <span
className={cn( className={cn(
'i-ri-arrow-down-s-line h-4 w-4 shrink-0 text-text-tertiary transition-transform', 'i-ri-arrow-down-s-line size-4 shrink-0 text-text-tertiary transition-transform',
isExpanded && 'rotate-180', isExpanded && 'rotate-180',
)} )}
/> />

View File

@ -16,7 +16,7 @@ export function DeploymentStatusSummary({ row }: {
if (isUndeployedDeploymentRow(row)) { if (isUndeployedDeploymentRow(row)) {
return ( return (
<span className="inline-flex items-center gap-1.5 system-sm-medium text-text-tertiary"> <span className="inline-flex items-center gap-1.5 system-sm-medium text-text-tertiary">
<span className="h-1.5 w-1.5 rounded-full bg-text-quaternary" /> <span className="size-1.5 rounded-full bg-text-quaternary" />
{t('status.notDeployed')} {t('status.notDeployed')}
</span> </span>
) )
@ -27,7 +27,7 @@ export function DeploymentStatusSummary({ row }: {
if (status === 'deploying') { if (status === 'deploying') {
return ( return (
<span className="inline-flex items-center gap-1.5 system-sm-medium text-util-colors-blue-blue-700"> <span className="inline-flex items-center gap-1.5 system-sm-medium text-util-colors-blue-blue-700">
<span className="i-ri-loader-4-line h-3.5 w-3.5 animate-spin" /> <span className="i-ri-loader-4-line size-3.5 animate-spin" />
{t('deployTab.status.deployingRelease', { release: releaseLabel(activeRelease(row)) })} {t('deployTab.status.deployingRelease', { release: releaseLabel(activeRelease(row)) })}
</span> </span>
) )
@ -37,7 +37,7 @@ export function DeploymentStatusSummary({ row }: {
const hasRunningRelease = !!activeRelease(row)?.id const hasRunningRelease = !!activeRelease(row)?.id
return ( return (
<span className="inline-flex items-center gap-1.5 system-sm-medium text-util-colors-warning-warning-700"> <span className="inline-flex items-center gap-1.5 system-sm-medium text-util-colors-warning-warning-700">
<span className="i-ri-alert-line h-3.5 w-3.5" /> <span className="i-ri-alert-line size-3.5" />
{t(hasRunningRelease ? 'deployTab.status.runningWithFailed' : 'deployTab.status.deployFailed')} {t(hasRunningRelease ? 'deployTab.status.runningWithFailed' : 'deployTab.status.deployFailed')}
</span> </span>
) )
@ -45,7 +45,7 @@ export function DeploymentStatusSummary({ row }: {
return ( return (
<span className="inline-flex items-center gap-1.5 system-sm-medium text-util-colors-green-green-700"> <span className="inline-flex items-center gap-1.5 system-sm-medium text-util-colors-green-green-700">
<span className="h-1.5 w-1.5 rounded-full bg-util-colors-green-green-500" /> <span className="size-1.5 rounded-full bg-util-colors-green-green-500" />
{t('status.ready')} {t('status.ready')}
</span> </span>
) )

View File

@ -129,7 +129,7 @@ export function DeploymentSidebar({
ref={sidebarRef} ref={sidebarRef}
className={cn( className={cn(
'flex shrink-0 flex-col border-r border-divider-burn bg-background-default-subtle transition-all', 'flex shrink-0 flex-col border-r border-divider-burn bg-background-default-subtle transition-all',
expand ? 'w-[216px]' : 'w-14', expand ? 'w-54' : 'w-14',
)} )}
> >
<div className={cn('shrink-0', expand ? 'p-2' : 'p-1')}> <div className={cn('shrink-0', expand ? 'p-2' : 'p-1')}>
@ -178,7 +178,7 @@ export function DeploymentSidebar({
/> />
{!isMobile && isHoveringSidebar && ( {!isMobile && isHoveringSidebar && (
<ToggleButton <ToggleButton
className="absolute top-[-3.5px] -right-3 z-20" className="absolute -top-1 -right-3 z-20"
expand={expand} expand={expand}
handleToggle={toggleSidebarMode} handleToggle={toggleSidebarMode}
/> />

View File

@ -35,7 +35,7 @@ export function InstanceDetail({ appInstanceId, children }: {
if (!resolvedAppInstanceId && overviewQuery.isLoading) { if (!resolvedAppInstanceId && overviewQuery.isLoading) {
return ( return (
<div className="flex h-full items-center justify-center bg-background-body"> <div className="flex h-full items-center justify-center bg-background-body">
<span className="h-6 w-6 animate-spin rounded-full border-2 border-components-panel-border border-t-transparent" /> <span className="size-6 animate-spin rounded-full border-2 border-components-panel-border border-t-transparent" />
</div> </div>
) )
} }
@ -45,7 +45,7 @@ export function InstanceDetail({ appInstanceId, children }: {
<div className="flex h-full flex-col items-center justify-center gap-3 bg-background-body"> <div className="flex h-full flex-col items-center justify-center gap-3 bg-background-body">
<div className="title-xl-semi-bold text-text-primary">{t('detail.notFound')}</div> <div className="title-xl-semi-bold text-text-primary">{t('detail.notFound')}</div>
<Button nativeButton={false} variant="secondary" render={<Link href="/deployments" />}> <Button nativeButton={false} variant="secondary" render={<Link href="/deployments" />}>
<span aria-hidden className="i-ri-arrow-left-line h-4 w-4" /> <span aria-hidden className="i-ri-arrow-left-line size-4" />
{t('detail.backToInstances')} {t('detail.backToInstances')}
</Button> </Button>
</div> </div>
@ -54,7 +54,7 @@ export function InstanceDetail({ appInstanceId, children }: {
return ( return (
<> <>
<div className="relative flex h-full overflow-hidden rounded-t-2xl shadow-[0_0_5px_rgba(0,0,0,0.05),0_0_2px_-1px_rgba(0,0,0,0.03)]"> <div className="relative flex h-full overflow-hidden rounded-t-2xl shadow-xs">
<DeploymentSidebar <DeploymentSidebar
app={app} app={app}
/> />

View File

@ -54,7 +54,7 @@ function AccessOverviewRow({ label, enabled, hint, meta }: AccessOverviewRowProp
)} )}
> >
<span className={cn( <span className={cn(
'h-1.5 w-1.5 rounded-full', 'size-1.5 rounded-full',
enabled ? 'bg-util-colors-green-green-500' : 'bg-text-quaternary', enabled ? 'bg-util-colors-green-green-500' : 'bg-text-quaternary',
)} )}
/> />
@ -147,14 +147,14 @@ function DeploymentStatusSection({ appInstanceId }: {
action={( action={(
<Button nativeButton={false} size="small" variant="secondary" render={<Link href={`/deployments/${appInstanceId}/deploy`} />}> <Button nativeButton={false} size="small" variant="secondary" render={<Link href={`/deployments/${appInstanceId}/deploy`} />}>
{t('overview.viewDeployments')} {t('overview.viewDeployments')}
<span className="i-ri-arrow-right-up-line h-3.5 w-3.5" /> <span className="i-ri-arrow-right-up-line size-3.5" />
</Button> </Button>
)} )}
> >
{deployments.length === 0 {deployments.length === 0
? ( ? (
<div className="flex flex-col items-center gap-3 rounded-lg border border-dashed border-components-panel-border bg-components-panel-bg-blur px-4 py-8 text-center"> <div className="flex flex-col items-center gap-3 rounded-lg border border-dashed border-components-panel-border bg-components-panel-bg-blur px-4 py-8 text-center">
<span className="i-ri-rocket-line h-5 w-5 text-text-quaternary" /> <span className="i-ri-rocket-line size-5 text-text-quaternary" />
<div className="system-sm-regular text-text-tertiary"> <div className="system-sm-regular text-text-tertiary">
{releaseRows.length === 0 {releaseRows.length === 0
? t(canCreateRelease ? 'overview.noReleaseYet' : 'overview.noReleaseSourceUnavailable') ? t(canCreateRelease ? 'overview.noReleaseYet' : 'overview.noReleaseSourceUnavailable')
@ -221,7 +221,7 @@ function AccessStatusSection({ appInstanceId }: {
action={( action={(
<Button nativeButton={false} size="small" variant="secondary" render={<Link href={`/deployments/${appInstanceId}/access`} />}> <Button nativeButton={false} size="small" variant="secondary" render={<Link href={`/deployments/${appInstanceId}/access`} />}>
{t('overview.configureAccess')} {t('overview.configureAccess')}
<span className="i-ri-arrow-right-up-line h-3.5 w-3.5" /> <span className="i-ri-arrow-right-up-line size-3.5" />
</Button> </Button>
)} )}
> >
@ -255,7 +255,7 @@ export function OverviewTab({ appInstanceId }: {
appInstanceId: string appInstanceId: string
}) { }) {
return ( return (
<div className="flex w-full max-w-[960px] flex-col gap-5 p-6"> <div className="flex w-full max-w-240 flex-col gap-5 p-6">
<BasicInfoSection appInstanceId={appInstanceId} /> <BasicInfoSection appInstanceId={appInstanceId} />
<DeploymentStatusSection appInstanceId={appInstanceId} /> <DeploymentStatusSection appInstanceId={appInstanceId} />
<AccessStatusSection appInstanceId={appInstanceId} /> <AccessStatusSection appInstanceId={appInstanceId} />

View File

@ -80,7 +80,7 @@ function DeleteInstanceButton({
</Button> </Button>
<AlertDialog open={showDeleteConfirm} onOpenChange={open => !open && setShowDeleteConfirm(false)}> <AlertDialog open={showDeleteConfirm} onOpenChange={open => !open && setShowDeleteConfirm(false)}>
<AlertDialogContent className="w-[520px]"> <AlertDialogContent className="w-130">
<div className="flex flex-col gap-3 px-6 pt-6 pb-2"> <div className="flex flex-col gap-3 px-6 pt-6 pb-2">
<AlertDialogTitle className="title-2xl-semi-bold text-text-primary"> <AlertDialogTitle className="title-2xl-semi-bold text-text-primary">
{t('settings.deleteConfirmTitle')} {t('settings.deleteConfirmTitle')}
@ -183,7 +183,7 @@ function SettingsForm({ app, settings }: SettingsFormProps) {
type="text" type="text"
value={name} value={name}
onChange={e => setName(e.target.value)} onChange={e => setName(e.target.value)}
className="flex h-8 items-center rounded-lg border-[0.5px] border-components-input-border-active bg-components-input-bg-normal px-3 text-[13px] font-medium text-text-secondary outline-hidden placeholder:text-text-quaternary" className="flex h-8 items-center rounded-lg border border-components-input-border-active bg-components-input-bg-normal px-3 system-sm-medium text-text-secondary outline-hidden placeholder:text-text-quaternary"
/> />
</div> </div>
<div className="flex flex-col gap-2"> <div className="flex flex-col gap-2">
@ -194,7 +194,7 @@ function SettingsForm({ app, settings }: SettingsFormProps) {
id="settings-desc" id="settings-desc"
value={description} value={description}
onChange={e => setDescription(e.target.value)} onChange={e => setDescription(e.target.value)}
className="min-h-[96px] rounded-lg border-[0.5px] border-components-input-border-active bg-components-input-bg-normal px-3 py-2 text-[13px] text-text-secondary outline-hidden placeholder:text-text-quaternary" className="min-h-24 rounded-lg border border-components-input-border-active bg-components-input-bg-normal px-3 py-2 system-sm-regular text-text-secondary outline-hidden placeholder:text-text-quaternary"
/> />
</div> </div>
<div className="flex justify-end gap-2"> <div className="flex justify-end gap-2">
@ -276,7 +276,7 @@ export function SettingsTab({ appInstanceId }: {
appInstanceId: string appInstanceId: string
}) { }) {
return ( return (
<div className="flex max-w-[640px] flex-col gap-5 p-6"> <div className="flex max-w-160 flex-col gap-5 p-6">
<SettingsFormSection appInstanceId={appInstanceId} /> <SettingsFormSection appInstanceId={appInstanceId} />
<DeleteInstanceControlSection appInstanceId={appInstanceId} /> <DeleteInstanceControlSection appInstanceId={appInstanceId} />
</div> </div>

View File

@ -57,12 +57,12 @@ function CreateReleaseControl({ appInstanceId, canCreateRelease }: {
disabled={!canCreateRelease} disabled={!canCreateRelease}
onClick={() => setIsCreating(true)} onClick={() => setIsCreating(true)}
> >
<span className="i-ri-add-line h-3.5 w-3.5" /> <span className="i-ri-add-line size-3.5" />
{t('versions.createRelease')} {t('versions.createRelease')}
</Button> </Button>
<Dialog open={isCreating} onOpenChange={setIsCreating}> <Dialog open={isCreating} onOpenChange={setIsCreating}>
<DialogContent className="w-[560px] overflow-hidden p-0"> <DialogContent className="w-140 overflow-hidden p-0">
<DialogCloseButton /> <DialogCloseButton />
<form <form
onSubmit={(event) => { onSubmit={(event) => {
@ -114,7 +114,7 @@ function CreateReleaseControl({ appInstanceId, canCreateRelease }: {
name="description" name="description"
placeholder={t('versions.releaseDescriptionPlaceholder')} placeholder={t('versions.releaseDescriptionPlaceholder')}
maxLength={512} maxLength={512}
className="min-h-[96px] w-full resize-none appearance-none rounded-md border border-transparent bg-components-input-bg-normal p-2 system-sm-regular text-components-input-text-filled caret-primary-600 outline-hidden placeholder:text-components-input-text-placeholder hover:border-components-input-border-hover hover:bg-components-input-bg-hover focus:border-components-input-border-active focus:bg-components-input-bg-active focus:shadow-xs" className="min-h-24 w-full resize-none appearance-none rounded-md border border-transparent bg-components-input-bg-normal p-2 system-sm-regular text-components-input-text-filled caret-primary-600 outline-hidden placeholder:text-components-input-text-placeholder hover:border-components-input-border-hover hover:bg-components-input-bg-hover focus:border-components-input-border-active focus:bg-components-input-bg-active focus:shadow-xs"
/> />
</div> </div>
</div> </div>
@ -135,7 +135,7 @@ function CreateReleaseControl({ appInstanceId, canCreateRelease }: {
<Button <Button
type="submit" type="submit"
variant="primary" variant="primary"
className="min-w-[88px]" className="min-w-22"
disabled={!canCreateRelease || createRelease.isPending} disabled={!canCreateRelease || createRelease.isPending}
> >
{createRelease.isPending ? t('versions.creating') : t('versions.create')} {createRelease.isPending ? t('versions.creating') : t('versions.create')}
@ -174,7 +174,7 @@ export function VersionsTab({ appInstanceId }: {
const canCreateRelease = overview?.instance?.canCreateRelease ?? true const canCreateRelease = overview?.instance?.canCreateRelease ?? true
return ( return (
<div className="flex w-full max-w-[960px] flex-col gap-4 p-6"> <div className="flex w-full max-w-240 flex-col gap-4 p-6">
<div className="flex items-center justify-between gap-3"> <div className="flex items-center justify-between gap-3">
<div className="system-sm-semibold text-text-primary"> <div className="system-sm-semibold text-text-primary">
{t('versions.releaseHistory')} {t('versions.releaseHistory')}

View File

@ -53,10 +53,10 @@ export function DeployReleaseMenu({ appInstanceId, releaseId }: {
)} )}
> >
{t('versions.deploy')} {t('versions.deploy')}
<span className="i-ri-arrow-down-s-line h-3.5 w-3.5" /> <span className="i-ri-arrow-down-s-line size-3.5" />
</DropdownMenuTrigger> </DropdownMenuTrigger>
{open && ( {open && (
<DropdownMenuContent placement="bottom-end" sideOffset={4} popupClassName="w-[220px]"> <DropdownMenuContent placement="bottom-end" sideOffset={4} popupClassName="w-55">
{environments.map((env) => { {environments.map((env) => {
const envId = env.id! const envId = env.id!
const row = deploymentRows.find(item => environmentId(item.environment) === envId) const row = deploymentRows.find(item => environmentId(item.environment) === envId)

View File

@ -28,10 +28,10 @@ export function DeployedToBadge({ item }: {
)} )}
> >
{item.state === 'deploying' {item.state === 'deploying'
? <span className="i-ri-loader-4-line h-3.5 w-3.5 animate-spin" /> ? <span className="i-ri-loader-4-line size-3.5 animate-spin" />
: item.state === 'failed' : item.state === 'failed'
? <span className="i-ri-alert-line h-3.5 w-3.5" /> ? <span className="i-ri-alert-line size-3.5" />
: <span className="h-1.5 w-1.5 rounded-full bg-current" />} : <span className="size-1.5 rounded-full bg-current" />}
{item.environmentName} {item.environmentName}
</span> </span>
)} )}

View File

@ -32,7 +32,7 @@ function getEnvironmentFilterOption(env: DeploymentEnvironmentOption & { id: str
return { return {
value: env.id, value: env.id,
text: env.name || env.id, text: env.name || env.id,
icon: <span className="i-ri-stack-line h-[14px] w-[14px]" />, icon: <span className="i-ri-stack-line size-[14px]" />,
disabled: env.deployable === false, disabled: env.deployable === false,
disabledReason: env.disabledReason, disabledReason: env.disabledReason,
} }
@ -53,13 +53,13 @@ export function EnvironmentFilter() {
{ {
value: 'all', value: 'all',
text: t('filter.allEnvs'), text: t('filter.allEnvs'),
icon: <span className="i-ri-apps-2-line h-[14px] w-[14px]" />, icon: <span className="i-ri-apps-2-line size-[14px]" />,
}, },
...environments.map(getEnvironmentFilterOption), ...environments.map(getEnvironmentFilterOption),
{ {
value: 'not-deployed', value: 'not-deployed',
text: t('filter.notDeployed'), text: t('filter.notDeployed'),
icon: <span className="i-ri-inbox-line h-[14px] w-[14px]" />, icon: <span className="i-ri-inbox-line size-[14px]" />,
}, },
] ]
const selectedOption = filterOptions.find(option => option.value === activeFilter) ?? filterOptions[0] const selectedOption = filterOptions.find(option => option.value === activeFilter) ?? filterOptions[0]
@ -68,25 +68,25 @@ export function EnvironmentFilter() {
<DropdownMenu modal={false} open={open} onOpenChange={setOpen}> <DropdownMenu modal={false} open={open} onOpenChange={setOpen}>
<DropdownMenuTrigger <DropdownMenuTrigger
className={cn( className={cn(
'flex h-8 cursor-pointer items-center gap-1 rounded-lg border-[0.5px] border-transparent bg-components-input-bg-normal px-2 text-left select-none', 'flex h-8 cursor-pointer items-center gap-1 rounded-lg border border-transparent bg-components-input-bg-normal px-2 text-left select-none',
open && 'shadow-xs', open && 'shadow-xs',
)} )}
> >
<div className="p-px text-text-tertiary"> <div className="p-px text-text-tertiary">
{selectedOption?.icon} {selectedOption?.icon}
</div> </div>
<div className="max-w-[160px] min-w-0 truncate text-[13px] leading-[18px] text-text-secondary"> <div className="max-w-40 min-w-0 truncate system-sm-regular text-text-secondary">
{selectedOption?.text} {selectedOption?.text}
</div> </div>
<div className="shrink-0 p-px"> <div className="shrink-0 p-px">
<span className={cn('i-ri-arrow-down-s-line h-3.5 w-3.5 text-text-tertiary transition-transform', open && 'rotate-180')} /> <span className={cn('i-ri-arrow-down-s-line size-3.5 text-text-tertiary transition-transform', open && 'rotate-180')} />
</div> </div>
</DropdownMenuTrigger> </DropdownMenuTrigger>
{open && ( {open && (
<DropdownMenuContent <DropdownMenuContent
placement="bottom-start" placement="bottom-start"
sideOffset={4} sideOffset={4}
popupClassName="w-[240px] rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg-blur shadow-lg backdrop-blur-[5px]" popupClassName="w-60 rounded-lg border border-components-panel-border bg-components-panel-bg-blur shadow-lg backdrop-blur-xs"
> >
<div className="max-h-72 overflow-auto p-1"> <div className="max-h-72 overflow-auto p-1">
{filterOptions.map(option => ( {filterOptions.map(option => (
@ -101,16 +101,16 @@ export function EnvironmentFilter() {
title={option.disabled ? option.disabledReason : undefined} title={option.disabled ? option.disabledReason : undefined}
aria-disabled={option.disabled} aria-disabled={option.disabled}
className={cn( className={cn(
'flex items-center gap-2 rounded-lg py-[6px] pr-2 pl-3 select-none', 'flex items-center gap-2 rounded-lg py-1.5 pr-2 pl-3 select-none',
option.disabled option.disabled
? 'cursor-not-allowed opacity-50' ? 'cursor-not-allowed opacity-50'
: 'cursor-pointer hover:bg-state-base-hover', : 'cursor-pointer hover:bg-state-base-hover',
)} )}
> >
<span className="shrink-0 text-text-tertiary">{option.icon}</span> <span className="shrink-0 text-text-tertiary">{option.icon}</span>
<span className="grow truncate text-sm leading-5 text-text-tertiary">{option.text}</span> <span className="grow truncate text-sm/5 text-text-tertiary">{option.text}</span>
{option.value === activeFilter && ( {option.value === activeFilter && (
<span className="i-custom-vender-line-general-check h-4 w-4 shrink-0 text-text-secondary" /> <span className="i-custom-vender-line-general-check size-4 shrink-0 text-text-secondary" />
)} )}
</DropdownMenuItem> </DropdownMenuItem>
))} ))}

View File

@ -27,7 +27,7 @@ function DeploymentsSearchInput() {
<Input <Input
showLeftIcon showLeftIcon
showClearIcon showClearIcon
wrapperClassName="w-[200px]" wrapperClassName="w-50"
placeholder={t('filter.searchPlaceholder')} placeholder={t('filter.searchPlaceholder')}
value={keywords} value={keywords}
onChange={e => handleKeywordsChange(e.target.value)} onChange={e => handleKeywordsChange(e.target.value)}
@ -72,7 +72,7 @@ function DeploymentsList() {
return ( return (
<div className="relative flex h-0 shrink-0 grow flex-col overflow-y-auto bg-background-body"> <div className="relative flex h-0 shrink-0 grow flex-col overflow-y-auto bg-background-body">
<DeploymentsListControls /> <DeploymentsListControls />
<div className="relative grid grow grid-cols-1 content-start gap-4 px-12 pt-2 2k:grid-cols-6 sm:grid-cols-1 md:grid-cols-2 xl:grid-cols-4 2xl:grid-cols-5"> <div className="relative grid grow grid-cols-1 content-start gap-4 px-12 pt-2 2k:grid-cols-6 md:grid-cols-2 xl:grid-cols-4 2xl:grid-cols-5">
<NewInstanceCard /> <NewInstanceCard />
{apps.map(app => ( {apps.map(app => (
<InstanceCard <InstanceCard

View File

@ -22,16 +22,16 @@ function NewInstanceAction({ icon, label, disabled, onClick }: NewInstanceAction
disabled={disabled} disabled={disabled}
title={disabled ? t('newInstance.comingSoon') : undefined} title={disabled ? t('newInstance.comingSoon') : undefined}
className={cn( className={cn(
'mb-1 flex w-full items-center rounded-lg px-6 py-[7px] text-left text-[13px] leading-[18px] font-medium text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary', 'mb-1 flex h-8 w-full items-center gap-2 rounded-lg px-6 text-left system-sm-medium text-text-tertiary hover:bg-state-base-hover hover:text-text-secondary',
disabled disabled
? 'cursor-not-allowed opacity-50 hover:bg-transparent hover:text-text-tertiary' ? 'cursor-not-allowed opacity-50 hover:bg-transparent hover:text-text-tertiary'
: 'cursor-pointer', : 'cursor-pointer',
)} )}
> >
<span aria-hidden className={cn('mr-2 h-4 w-4 shrink-0', icon)} /> <span aria-hidden className={cn('size-4 shrink-0', icon)} />
<span className="min-w-0 flex-1 truncate">{label}</span> <span className="min-w-0 flex-1 truncate">{label}</span>
{disabled && ( {disabled && (
<span className="ml-2 shrink-0 rounded-md bg-state-base-hover px-1.5 system-2xs-medium text-text-tertiary"> <span className="shrink-0 rounded-md bg-state-base-hover px-1.5 system-2xs-medium text-text-tertiary">
{t('newInstance.comingSoon')} {t('newInstance.comingSoon')}
</span> </span>
)} )}
@ -56,9 +56,9 @@ export function NewInstanceCard() {
const { t } = useTranslation('deployments') const { t } = useTranslation('deployments')
return ( return (
<div className="relative col-span-1 inline-flex h-[160px] flex-col justify-between rounded-xl border-[0.5px] border-components-card-border bg-components-card-bg"> <div className="relative col-span-1 inline-flex h-40 flex-col justify-between rounded-xl border border-components-card-border bg-components-card-bg">
<div className="grow rounded-t-xl p-2"> <div className="grow rounded-t-xl p-2">
<div className="px-6 pt-2 pb-1 text-xs leading-[18px] font-medium text-text-tertiary"> <div className="px-6 pt-2 pb-1 text-xs/[18px] font-medium text-text-tertiary">
{t('newInstance.title')} {t('newInstance.title')}
</div> </div>
<CreateFromStudioAction /> <CreateFromStudioAction />

View File

@ -94,8 +94,8 @@ export function DeploymentsNav() {
return ( return (
<Nav <Nav
isApp={false} isApp={false}
icon={<span aria-hidden className="i-ri-rocket-line h-4 w-4" />} icon={<span aria-hidden className="i-ri-rocket-line size-4" />}
activeIcon={<span aria-hidden className="i-ri-rocket-fill h-4 w-4" />} activeIcon={<span aria-hidden className="i-ri-rocket-fill size-4" />}
text={t('menus.deployments', { ns: 'common' })} text={t('menus.deployments', { ns: 'common' })}
activeSegment="deployments" activeSegment="deployments"
link="/deployments" link="/deployments"