Files
Alaister YoungandAlaister Young ca2b50a0a7 chore(ui-patterns): collapse the admonition shim into ui-patterns/Admonition (#48377)
Follow-up to #48344: collapses the two resolution paths for the
Admonition module into one.

`src/admonition.tsx` was a back-compat shim re-exporting
`src/Admonition/`. Two ways to resolve one module is exactly what
produced the macOS self-import bug fixed in #48344, and the local
typecheck errors that #48374 worked around. This removes the shim and
standardizes on the PascalCase subpath, matching every other export in
the package.

**Changed:**

- Codemodded all 246 `ui-patterns/admonition` imports to
`ui-patterns/Admonition` (240 `.tsx`, 5 `.mdx`, 1 `.ts` across studio,
docs, www, design-system, and lite-studio)
- Pointed the 5 internal `'../admonition'` imports back at the
`'../Admonition'` directory

**Removed:**

- `packages/ui-patterns/src/admonition.tsx`, and its `./admonition`
entry in the exports map (regenerated with `pnpm gen:exports`)

## To test

- `grep -r "ui-patterns/admonition" --include='*.ts*'` → no hits
- `pnpm test:case-hazards` → passes
- `pnpm typecheck` → all 15 tasks green
- `pnpm --filter studio run lint:ratchet` → passes
- `pnpm --filter ui-patterns vitest run src/Admonition` → 11 tests pass

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

* **Bug Fixes**
* Standardized Admonition component imports across the application and
documentation.
* Improved compatibility with case-sensitive environments by using the
canonical component path.
  * Removed the legacy Admonition import entry point.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-07-29 00:48:56 +08:00

108 lines
4.5 KiB
TypeScript

import { PermissionAction } from '@supabase/shared-types/out/constants'
import { Card } from 'ui'
import { Admonition } from 'ui-patterns/Admonition'
import { DESCRIPTIONS, LABELS, OPTION_ORDER } from './AnalyticsBucketDetails.constants'
import { CopyEnvButton } from './CopyEnvButton'
import { DecryptedReadOnlyInput } from './DecryptedReadOnlyInput'
import { UpdateCatalogTokenDialog } from './UpdateCatalogTokenDialog'
import { useAnalyticsBucketWrapperInstance } from './useAnalyticsBucketWrapperInstance'
import { INTEGRATIONS } from '@/components/interfaces/Integrations/Landing/Integrations.constants'
import { WrapperMeta } from '@/components/interfaces/Integrations/Wrappers/Wrappers.types'
import { convertKVStringArrayToJson } from '@/components/interfaces/Integrations/Wrappers/Wrappers.utils'
import {
ScaffoldHeader,
ScaffoldSection,
ScaffoldSectionDescription,
ScaffoldSectionTitle,
} from '@/components/layouts/Scaffold'
import { InlineLink } from '@/components/ui/InlineLink'
import { useAPIKeys } from '@/data/api-keys/api-keys-query'
import { useVaultSecretDecryptedValueQuery } from '@/data/vault/vault-secret-decrypted-value-query'
import { useAsyncCheckPermissions } from '@/hooks/misc/useCheckPermissions'
import { useSelectedProjectQuery } from '@/hooks/misc/useSelectedProject'
import { DOCS_URL } from '@/lib/constants'
export const SimpleConfigurationDetails = ({ bucketName }: { bucketName?: string }) => {
const { data: project } = useSelectedProjectQuery()
const { can: canReadAPIKeys } = useAsyncCheckPermissions(PermissionAction.SECRETS_READ, '*')
const integration = INTEGRATIONS.find((i) => i.id === 'iceberg_wrapper' && i.type === 'wrapper')
const wrapperMeta = (integration?.type === 'wrapper' && integration.meta) as WrapperMeta
/** The wrapper instance is the wrapper that is installed for this Analytics bucket. */
const { data: wrapperInstance } = useAnalyticsBucketWrapperInstance({ bucketId: bucketName })
const wrapperValues = convertKVStringArrayToJson(wrapperInstance?.server_options ?? [])
const { data: decryptedToken, isSuccess: isSuccessVaultDecrypt } =
useVaultSecretDecryptedValueQuery(
{
projectRef: project?.ref,
connectionString: project?.connectionString,
id: wrapperValues?.vault_token,
},
{ enabled: canReadAPIKeys }
)
const { data: apiKeysData, isSuccess: isSuccessApiKeys } = useAPIKeys(
{ projectRef: project?.ref, reveal: true },
{ enabled: canReadAPIKeys }
)
const isTokenValid = apiKeysData?.allSecretKeys.some((x) => x.api_key === decryptedToken)
if (!wrapperInstance) return null
return (
<ScaffoldSection isFullWidth>
<ScaffoldHeader className="flex flex-row justify-between items-end gap-x-8 pt-0">
<div>
<ScaffoldSectionTitle>Connection details</ScaffoldSectionTitle>
<ScaffoldSectionDescription>
Connect to this bucket from an Iceberg client.{' '}
<InlineLink
href={`${DOCS_URL}/guides/storage/analytics/connecting-to-analytics-bucket`}
>
Learn more
</InlineLink>
</ScaffoldSectionDescription>
</div>
<CopyEnvButton
serverOptions={wrapperMeta.server.options.filter(
(option) => !option.hidden && wrapperValues[option.name]
)}
values={wrapperValues}
/>
</ScaffoldHeader>
{isSuccessApiKeys && isSuccessVaultDecrypt && !isTokenValid && (
<Admonition type="warning" title="Catalog token is no longer valid" className="mb-4">
<p>
The Iceberg wrapper's catalog token doesn't match with any of your project's API keys,
and hence authorization will fail when connecting to your bucket. Update the catalog
token to use any of your project's API keys.
</p>
{canReadAPIKeys && <UpdateCatalogTokenDialog vaultTokenId={wrapperValues?.vault_token} />}
</Admonition>
)}
<Card>
{wrapperMeta.server.options
.filter((option) => !option.hidden && wrapperValues[option.name])
.sort((a, b) => OPTION_ORDER.indexOf(a.name) - OPTION_ORDER.indexOf(b.name))
.map((option) => {
return (
<DecryptedReadOnlyInput
key={option.name}
label={LABELS[option.name]}
value={wrapperValues[option.name]}
secureEntry={option.secureEntry}
descriptionText={DESCRIPTIONS[option.name]}
/>
)
})}
</Card>
</ScaffoldSection>
)
}