Skip to content

Commit e273477

Browse files
committed
Show catalog descriptions, a single credential, and actual Search access
1 parent e453d01 commit e273477

21 files changed

Lines changed: 445 additions & 302 deletions

File tree

‎apps/sim/platform/app/(shell)/_components/session/integration-changes.tsx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import type { IntegrationsData, OrganizationIntegration } from '@/platform/lib/i
55

66
type AccountEdits = Pick<
77
OrganizationIntegration,
8-
'accounts' | 'connectableMethod' | 'connectionCandidate'
8+
'account' | 'connectableMethod' | 'connectionCandidate'
99
>
1010

1111
function useEdits() {
@@ -37,7 +37,7 @@ export function useOrganizationIntegrations(data: IntegrationsData | null) {
3737
setAccounts((current) => ({
3838
...current,
3939
[item.providerId]: {
40-
accounts: item.accounts,
40+
account: item.account,
4141
connectableMethod: item.connectableMethod,
4242
connectionCandidate: item.connectionCandidate,
4343
},
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
.identity {
2+
display: grid;
3+
min-inline-size: 0;
4+
gap: var(--ui-stack-gap);
5+
}
6+
.credential {
7+
display: flex;
8+
align-items: center;
9+
justify-content: space-between;
10+
gap: var(--ui-row-gap);
11+
}
12+
.muted {
13+
color: var(--ui-secondary);
14+
}

apps/sim/platform/app/(shell)/integrations/_components/credential-actions/credential-actions.tsx renamed to apps/sim/platform/app/(shell)/integrations/_components/connected-credential/connected-credential.tsx

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,39 @@
11
'use client'
22

33
import { useState } from 'react'
4+
import styles from '@/platform/app/(shell)/integrations/_components/connected-credential/connected-credential.module.css'
45
import { ActionMenu, Modal } from '@/platform/design-system/components'
56
import type { IntegrationAccount } from '@/platform/lib/integrations/model'
67

7-
interface CredentialActionsProps {
8+
interface ConnectedCredentialProps {
89
account: IntegrationAccount
10+
status?: string
911
canAuthorize: boolean
1012
onReconnect: () => void
1113
onDisconnect: () => void
1214
}
1315

14-
export function CredentialActions({
16+
export function ConnectedCredential({
1517
account,
18+
status,
1619
canAuthorize,
1720
onReconnect,
1821
onDisconnect,
19-
}: CredentialActionsProps) {
22+
}: ConnectedCredentialProps) {
2023
const [confirming, setConfirming] = useState(false)
2124
return (
22-
<>
25+
<section aria-label='Connected credential' className={styles.credential}>
26+
<div className={styles.identity}>
27+
<h2 className={styles.muted} data-type='T050'>
28+
Connected credential
29+
</h2>
30+
<p data-type='T059'>{account.label}</p>
31+
{status && (
32+
<p className={styles.muted} data-type='T050'>
33+
{status}
34+
</p>
35+
)}
36+
</div>
2337
<ActionMenu
2438
label={`Manage ${account.label}`}
2539
icon='I108'
@@ -58,6 +72,6 @@ export function CredentialActions({
5872
onConfirm={onDisconnect}
5973
/>
6074
)}
61-
</>
75+
</section>
6276
)
6377
}
Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,24 @@
11
.section,
2-
.scopes,
3-
.scope {
2+
.heading,
3+
.group,
4+
.items {
45
display: grid;
56
min-inline-size: 0;
67
}
78
.section {
89
gap: var(--ui-section-gap);
910
}
10-
.header {
11-
display: flex;
12-
flex-wrap: wrap;
13-
align-items: center;
14-
justify-content: space-between;
11+
.heading {
12+
gap: var(--ui-stack-gap);
13+
}
14+
.group {
1515
gap: var(--ui-row-gap);
1616
}
17-
.scopes {
17+
.items {
1818
gap: var(--ui-list-gap);
19-
margin-block-start: var(--ui-row-gap);
20-
}
21-
.scope {
22-
gap: var(--ui-stack-gap);
2319
overflow-wrap: anywhere;
20+
}
21+
.items,
22+
.heading p {
2423
color: var(--ui-secondary);
2524
}
Lines changed: 51 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,66 @@
1-
'use client'
2-
3-
import { useState } from 'react'
41
import styles from '@/platform/app/(shell)/integrations/_components/connection-access/connection-access.module.css'
52
import {
63
SCOPE_GROUPS,
74
scopeGroup,
85
} from '@/platform/app/(shell)/integrations/_components/connection-access/scope-groups'
9-
import { Button, Disclosure } from '@/platform/design-system/components'
6+
import { CountedLabel } from '@/platform/design-system/components/overflow-text/counted-label'
107
import type { OrganizationIntegration } from '@/platform/lib/integrations/model'
118

9+
interface AccessGroupProps {
10+
title: string
11+
items: readonly { id: string; label: string }[]
12+
}
13+
14+
function AccessGroup({ title, items }: AccessGroupProps) {
15+
if (!items.length) return null
16+
return (
17+
<div className={styles.group}>
18+
<h3 data-type='T059'>
19+
<CountedLabel label={title} count={items.length} />
20+
</h3>
21+
<ul className={styles.items} aria-label={title}>
22+
{items.map(({ id, label }) => (
23+
<li data-type='T060' key={id}>
24+
{label}
25+
</li>
26+
))}
27+
</ul>
28+
</div>
29+
)
30+
}
31+
1232
interface ConnectionAccessProps {
1333
integration: OrganizationIntegration
1434
}
1535

1636
export function ConnectionAccess({ integration }: ConnectionAccessProps) {
17-
const [showIds, setShowIds] = useState(false)
18-
const scopes = integration.requestedScopes
19-
if (!scopes?.length) return null
37+
const { searchReads, searchResource, requestedScopes, availability, accessDescription } =
38+
integration
2039
return (
21-
<section className={styles.section} aria-label='Requested permissions'>
22-
<header className={styles.header}>
23-
<h2 data-type='T093'>Requested permissions</h2>
24-
<Button
25-
size='compact'
26-
variant='quiet'
27-
render={<button type='button' aria-expanded={showIds} />}
28-
onClick={() => setShowIds(!showIds)}
29-
>
30-
{showIds ? 'Hide scope IDs' : 'Show scope IDs'}
31-
</Button>
32-
</header>
33-
{SCOPE_GROUPS.map((group) => {
34-
const entries = scopes.filter(({ id }) => scopeGroup(id) === group)
35-
if (!entries.length) return null
36-
return (
37-
<Disclosure key={group} label={group} initiallyOpen>
38-
<ul className={styles.scopes} aria-label={group}>
39-
{entries.map(({ id, label }) => (
40-
<li key={id} className={styles.scope}>
41-
<span data-type='T060'>{label}</span>
42-
{showIds && label !== id && <span data-type='T050'>{id}</span>}
43-
</li>
44-
))}
45-
</ul>
46-
</Disclosure>
47-
)
48-
})}
49-
</section>
40+
<>
41+
{searchResource &&
42+
availability === 'ready' &&
43+
(searchReads.length > 0 || !requestedScopes?.length) && (
44+
<section className={styles.section} aria-label='Search access'>
45+
<header className={styles.heading}>
46+
<h2 data-type='T093'>Search access</h2>
47+
<p data-type='T060'>{accessDescription}</p>
48+
</header>
49+
<AccessGroup title='Read-only tools' items={searchReads} />
50+
</section>
51+
)}
52+
{requestedScopes && requestedScopes.length > 0 && (
53+
<section className={styles.section} aria-label='Requested permissions'>
54+
<h2 data-type='T093'>Requested permissions</h2>
55+
{SCOPE_GROUPS.map((group) => (
56+
<AccessGroup
57+
key={group}
58+
title={group}
59+
items={requestedScopes.filter(({ id }) => scopeGroup(id) === group)}
60+
/>
61+
))}
62+
</section>
63+
)}
64+
</>
5065
)
5166
}

‎apps/sim/platform/app/(shell)/integrations/_components/integration-details/integration-details.module.css‎

Lines changed: 0 additions & 12 deletions
This file was deleted.

0 commit comments

Comments
 (0)