Skip to content

Commit 1137130

Browse files
committed
fix(org): settle the first review round on the redesign
1 parent 2bbd8c6 commit 1137130

14 files changed

Lines changed: 59 additions & 19 deletions

File tree

‎apps/sim/hooks/queries/organization-accounts.ts‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,9 +258,6 @@ export function useUpdateOrganizationAccounts() {
258258
queryKey: slackSearchKeys.organizationManifests(organizationId),
259259
}),
260260
queryClient.invalidateQueries({ queryKey: slackSearchKeys.list(organizationId) }),
261-
queryClient.invalidateQueries({
262-
queryKey: organizationAccountsKeys.detail(organizationId),
263-
}),
264261
]),
265262
})
266263
}

‎apps/sim/hooks/queries/organization-home.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ const CALENDAR_STALE_TIME = 5 * 60 * 1000
1313

1414
/** Nested under the organization's accounts, so anything that changes a connection refreshes Home. */
1515
const organizationHomeKeys = {
16+
all: organizationAccountsKeys.details(),
1617
organization: (organizationId: string) =>
1718
[...organizationAccountsKeys.detail(organizationId), 'home'] as const,
1819
email: (organizationId: string) =>

‎apps/sim/lib/organizations/application/home-widgets.integration.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ import { GET as getCalendarRoute } from '@/app/api/organizations/[id]/home/calen
3434
import { GET as getEmailRoute } from '@/app/api/organizations/[id]/home/email/route'
3535

3636
vi.mock('@/lib/auth', () => authMock)
37+
vi.mock('@/connectors/gmail/mailbox', async (importOriginal) => ({
38+
...(await importOriginal<typeof import('@/connectors/gmail/mailbox')>()),
39+
getGmailMailboxEmail: async () => 'reader@example.com',
40+
}))
3741

3842
vi.hoisted(() => {
3943
Object.assign(process.env, {

‎apps/sim/lib/organizations/application/home-widgets.ts‎

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,17 +224,34 @@ async function readViewerAccounts<T>(
224224
)
225225
)
226226

227+
const isReadable = ({
228+
provider,
229+
providerId,
230+
status,
231+
credentialId,
232+
}: (typeof candidates)[number]) =>
233+
allowed.includes(provider) &&
234+
readable.get(providerId) === true &&
235+
status !== 'needs_reauth' &&
236+
ownedIds.has(credentialId)
237+
const toRead = new Set(
238+
candidates
239+
.filter(isReadable)
240+
.slice(0, HOME_WIDGET_ACCOUNT_LIMIT)
241+
.map((candidate) => candidate.credentialId)
242+
)
243+
227244
const results = await Promise.all(
228-
candidates.map(async (candidate, index) => {
245+
candidates.map(async (candidate) => {
229246
const { credentialId, displayName, provider, providerId, status, read } = candidate
230247
const settled = (state: HomeWidgetAccount['state'], rows: T[] = []) => ({
231248
account: { credentialId, displayName, state },
232249
rows: rows.map((row) => ({ ...row, credentialId })),
233250
})
234-
if (index >= HOME_WIDGET_ACCOUNT_LIMIT) return settled('not_read')
235251
if (!allowed.includes(provider) || !readable.get(providerId)) return settled('not_offered')
236252
if (status === 'needs_reauth') return settled('needs_reauth')
237253
if (!ownedIds.has(credentialId)) return settled('not_offered')
254+
if (!toRead.has(credentialId)) return settled('not_read')
238255
try {
239256
return settled('ready', await readWithToken({ context, credentialId, providerId }, read))
240257
} catch (error) {

‎apps/sim/lib/organizations/home/provider-reads.test.ts‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,13 @@ import {
2222
readOutlookCalendarDay,
2323
readOutlookMessages,
2424
} from '@/lib/organizations/home/provider-reads'
25+
import { gmailThreadUrl } from '@/connectors/gmail/mailbox'
2526

2627
vi.mock('@/lib/core/security/input-validation.server', () => inputValidationMock)
28+
vi.mock('@/connectors/gmail/mailbox', async (importOriginal) => ({
29+
...(await importOriginal<typeof import('@/connectors/gmail/mailbox')>()),
30+
getGmailMailboxEmail: async () => 'reader@example.com',
31+
}))
2732

2833
const { mockSecureFetchWithValidation: providerFetch } = inputValidationMockFns
2934
const signal = new AbortController().signal
@@ -112,7 +117,7 @@ describe('reading mail', () => {
112117
excerpt: 'Agreed',
113118
receivedAt: '2026-11-05T10:00:00.000Z',
114119
messageCount: 2,
115-
url: 'https://mail.google.com/mail/u/0/#inbox/thread-1',
120+
url: gmailThreadUrl('thread-1', 'reader@example.com'),
116121
},
117122
])
118123
})

‎apps/sim/lib/organizations/home/provider-reads.ts‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
HOME_EMAIL_THREAD_LIMIT,
1010
HOME_TEXT_LIMITS,
1111
} from '@/lib/organizations/home/limits'
12+
import { getGmailMailboxEmail, gmailThreadUrl } from '@/connectors/gmail/mailbox'
1213
import { gmailGetThreadV2Tool } from '@/tools/gmail/get_thread'
1314
import { gmailListThreadsV2Tool } from '@/tools/gmail/list_threads'
1415
import { listV2Tool as googleCalendarListTool } from '@/tools/google_calendar/list'
@@ -161,6 +162,7 @@ export async function readGmailThreads({
161162
signal
162163
)
163164
if (!list.success) throw new HomeProviderReadError('unavailable')
165+
const mailbox = await getGmailMailboxEmail(accessToken, { signal })
164166
const threads = await mapWithConcurrency(
165167
list.output.threads.slice(0, HOME_EMAIL_THREAD_LIMIT),
166168
GMAIL_THREAD_CONCURRENCY,
@@ -183,7 +185,7 @@ export async function readGmailThreads({
183185
excerpt: bounded(latest.snippet, HOME_TEXT_LIMITS.excerpt),
184186
receivedAt,
185187
...(messages.length > 1 ? { messageCount: messages.length } : {}),
186-
url: `https://mail.google.com/mail/u/0/#inbox/${encodeURIComponent(id)}`,
188+
url: gmailThreadUrl(id, mailbox),
187189
}
188190
}
189191
)

‎apps/sim/lib/postcss/platform-embed.cjs‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ function scopeSelector(selector) {
2121
)
2222
return [selector, followsHost]
2323
}
24-
if (selector.startsWith(SCOPE)) return [selector]
24+
if (selector.includes(SCOPE)) return [selector]
2525
return [`:where(${SCOPE}) ${selector}`]
2626
}
2727

‎apps/sim/platform/app/(shell)/integrations/_components/integration-list/integration-list.tsx‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,18 @@ import {
77
type OrganizationIntegration,
88
} from '@/platform/lib/integrations/model'
99

10-
const SECTIONS = ['Your accounts', 'Available to connect', 'Managed by your organization'] as const
10+
const SECTIONS = [
11+
'Your accounts',
12+
'Available to connect',
13+
'Managed by your organization',
14+
'Not available',
15+
] as const
1116
type Section = (typeof SECTIONS)[number]
1217

1318
function sectionFor(item: OrganizationIntegration): Section {
1419
if (item.accounts.length) return 'Your accounts'
1520
if (isConnectable(item)) return 'Available to connect'
16-
return 'Managed by your organization'
21+
return item.availability === 'managed' ? 'Managed by your organization' : 'Not available'
1722
}
1823

1924
interface IntegrationListProps {

‎apps/sim/platform/app/(shell)/integrations/_components/tool-permissions/tool-permissions.module.css‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
min-inline-size: 0;
2929
}
3030
.list {
31+
margin: 0;
32+
padding: 0;
33+
list-style: none;
3134
gap: var(--ui-list-gap);
3235
}
3336
.tool {

‎apps/sim/platform/design-system/components/avatar/avatar.tsx‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ export function PeoplePopover({ title, people }: PeoplePopoverProps) {
7272
<span className={styles.peopleHeading} data-type='T052'>
7373
{title}
7474
</span>
75-
{people.map((person) => (
76-
<PersonRow key={person.name} name={person.name} src={person.src} />
75+
{people.map((person, index) => (
76+
<PersonRow key={`${person.name}-${index}`} name={person.name} src={person.src} />
7777
))}
7878
</span>
7979
)
@@ -106,8 +106,8 @@ interface AvatarGroupProps {
106106
export function AvatarGroup({ people, label }: AvatarGroupProps) {
107107
return (
108108
<span className={styles.avatarGroup}>
109-
{people.slice(0, 2).map((person) => (
110-
<Tooltip key={person.name} label={person.name}>
109+
{people.slice(0, 2).map((person, index) => (
110+
<Tooltip key={`${person.name}-${index}`} label={person.name}>
111111
<Avatar name={person.name} src={person.src} />
112112
</Tooltip>
113113
))}

0 commit comments

Comments
 (0)