diff --git a/apps/sim/app/workspace/[workspaceId]/settings/[section]/settings.tsx b/apps/sim/app/workspace/[workspaceId]/settings/[section]/settings.tsx
index 20f6e9d3545..b4fd13563dd 100644
--- a/apps/sim/app/workspace/[workspaceId]/settings/[section]/settings.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/settings/[section]/settings.tsx
@@ -13,13 +13,13 @@ import { ApiKeysSkeleton } from '@/app/workspace/[workspaceId]/settings/componen
import { BYOKSkeleton } from '@/app/workspace/[workspaceId]/settings/components/byok/byok-skeleton'
import { CopilotSkeleton } from '@/app/workspace/[workspaceId]/settings/components/copilot/copilot-skeleton'
import { CredentialSetsSkeleton } from '@/app/workspace/[workspaceId]/settings/components/credential-sets/credential-sets-skeleton'
-import { CredentialsSkeleton } from '@/app/workspace/[workspaceId]/settings/components/credentials/credential-skeleton'
import { CustomToolsSkeleton } from '@/app/workspace/[workspaceId]/settings/components/custom-tools/custom-tool-skeleton'
import { GeneralSkeleton } from '@/app/workspace/[workspaceId]/settings/components/general/general-skeleton'
import { InboxSkeleton } from '@/app/workspace/[workspaceId]/settings/components/inbox/inbox-skeleton'
import { IntegrationsSkeleton } from '@/app/workspace/[workspaceId]/settings/components/integrations/integrations-skeleton'
import { McpSkeleton } from '@/app/workspace/[workspaceId]/settings/components/mcp/mcp-skeleton'
import { RecentlyDeletedSkeleton } from '@/app/workspace/[workspaceId]/settings/components/recently-deleted/recently-deleted-skeleton'
+import { SecretsSkeleton } from '@/app/workspace/[workspaceId]/settings/components/secrets/secrets-skeleton'
import { SkillsSkeleton } from '@/app/workspace/[workspaceId]/settings/components/skills/skill-skeleton'
import { WorkflowMcpServersSkeleton } from '@/app/workspace/[workspaceId]/settings/components/workflow-mcp-servers/workflow-mcp-servers-skeleton'
import type { SettingsSection } from '@/app/workspace/[workspaceId]/settings/navigation'
@@ -59,12 +59,12 @@ const Integrations = dynamic(
),
{ loading: () => }
)
-const Credentials = dynamic(
+const Secrets = dynamic(
() =>
- import('@/app/workspace/[workspaceId]/settings/components/credentials/credentials').then(
- (m) => m.Credentials
+ import('@/app/workspace/[workspaceId]/settings/components/secrets/secrets').then(
+ (m) => m.Secrets
),
- { loading: () => }
+ { loading: () => }
)
// const TemplateProfile = dynamic(
// () =>
@@ -225,7 +225,7 @@ export function SettingsPage({ section }: SettingsPageProps) {
{label}
{effectiveSection === 'general' && }
{effectiveSection === 'integrations' && }
- {effectiveSection === 'secrets' && }
+ {effectiveSection === 'secrets' && }
{/* {effectiveSection === 'template-profile' && } */}
{effectiveSection === 'credential-sets' && }
{effectiveSection === 'access-control' && }
diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/credentials/credentials.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/credentials/credentials.tsx
deleted file mode 100644
index 237f5c2114d..00000000000
--- a/apps/sim/app/workspace/[workspaceId]/settings/components/credentials/credentials.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import { CredentialsManager } from '@/app/workspace/[workspaceId]/settings/components/credentials/credentials-manager'
-
-export function Credentials() {
- return (
-
-
-
- )
-}
diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/integrations/credential-skeleton.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/integrations/credential-skeleton.tsx
new file mode 100644
index 00000000000..b367a297a66
--- /dev/null
+++ b/apps/sim/app/workspace/[workspaceId]/settings/components/integrations/credential-skeleton.tsx
@@ -0,0 +1,22 @@
+import { Skeleton } from '@/components/emcn'
+
+/**
+ * Skeleton for a single integration credential row.
+ */
+export function CredentialSkeleton() {
+ return (
+
+ )
+}
diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/integrations/integrations-manager.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/integrations/integrations-manager.tsx
index ab3c2c50e2b..27bb15a58b6 100644
--- a/apps/sim/app/workspace/[workspaceId]/settings/components/integrations/integrations-manager.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/settings/components/integrations/integrations-manager.tsx
@@ -35,7 +35,7 @@ import {
import { getCanonicalScopesForProvider, getServiceConfigByProviderId } from '@/lib/oauth'
import { getScopeDescription } from '@/lib/oauth/utils'
import { getUserColor } from '@/lib/workspaces/colors'
-import { CredentialSkeleton } from '@/app/workspace/[workspaceId]/settings/components/credentials/credential-skeleton'
+import { CredentialSkeleton } from '@/app/workspace/[workspaceId]/settings/components/integrations/credential-skeleton'
import {
useCreateCredentialDraft,
useCreateWorkspaceCredential,
@@ -59,12 +59,15 @@ import { useSettingsDirtyStore } from '@/stores/settings/dirty/store'
const logger = createLogger('IntegrationsManager')
-const roleOptions = [
+const ROLE_OPTIONS = [
{ value: 'member', label: 'Member' },
{ value: 'admin', label: 'Admin' },
] as const
-const roleComboOptions = roleOptions.map((option) => ({ value: option.value, label: option.label }))
+const roleComboOptions = ROLE_OPTIONS.map((option) => ({
+ value: option.value,
+ label: option.label,
+}))
export function IntegrationsManager() {
const params = useParams()
@@ -201,10 +204,7 @@ export function IntegrationsManager() {
() => members.filter((member) => member.status === 'active'),
[members]
)
- const adminMemberCount = useMemo(
- () => activeMembers.filter((member) => member.role === 'admin').length,
- [activeMembers]
- )
+ const adminMemberCount = activeMembers.filter((member) => member.role === 'admin').length
const workspaceUserOptions = useMemo(() => {
const activeMemberUserIds = new Set(activeMembers.map((member) => member.userId))
@@ -246,15 +246,12 @@ export function IntegrationsManager() {
)
}, [credentials, createDisplayName])
- const isDescriptionDirty = useMemo(() => {
- if (!selectedCredential) return false
- return selectedDescriptionDraft !== (selectedCredential.description || '')
- }, [selectedCredential, selectedDescriptionDraft])
-
- const isDisplayNameDirty = useMemo(() => {
- if (!selectedCredential) return false
- return selectedDisplayNameDraft !== selectedCredential.displayName
- }, [selectedCredential, selectedDisplayNameDraft])
+ const isDescriptionDirty = selectedCredential
+ ? selectedDescriptionDraft !== (selectedCredential.description || '')
+ : false
+ const isDisplayNameDirty = selectedCredential
+ ? selectedDisplayNameDraft !== selectedCredential.displayName
+ : false
const isDetailsDirty = isDescriptionDirty || isDisplayNameDirty
@@ -1310,7 +1307,10 @@ export function IntegrationsManager() {
{activeMembers.map((member) => (
@@ -1324,7 +1324,7 @@ export function IntegrationsManager() {
-
+
{member.userName || member.userEmail || member.userId}
@@ -1336,7 +1336,7 @@ export function IntegrationsManager() {
option.value === member.role)?.label || ''
+ ROLE_OPTIONS.find((option) => option.value === member.role)?.label || ''
}
selectedValue={member.role}
onChange={(value) =>
@@ -1348,7 +1348,7 @@ export function IntegrationsManager() {
}
size='sm'
/>
- {isSelectedAdmin ? (
+ {isSelectedAdmin && (
handleRemoveMember(member.userId)}
@@ -1357,8 +1357,6 @@ export function IntegrationsManager() {
>
Remove
- ) : (
-
)}
))}
@@ -1380,7 +1378,7 @@ export function IntegrationsManager() {
option.value === memberRole)?.label || ''
+ ROLE_OPTIONS.find((option) => option.value === memberRole)?.label || ''
}
selectedValue={memberRole}
onChange={(value) => setMemberRole(value as WorkspaceCredentialRole)}
@@ -1520,9 +1518,6 @@ export function IntegrationsManager() {
- handleSelectCredential(credential)}>
- Details
-
{credential.role === 'admin' && (
)}
+ handleSelectCredential(credential)}>
+ Details
+
)
@@ -1549,7 +1547,10 @@ export function IntegrationsManager() {
{filteredAvailableIntegrations.length > 0 && (
Available integrations
diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/integrations/integrations-skeleton.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/integrations/integrations-skeleton.tsx
index 223c274568d..7936901af50 100644
--- a/apps/sim/app/workspace/[workspaceId]/settings/components/integrations/integrations-skeleton.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/settings/components/integrations/integrations-skeleton.tsx
@@ -1,5 +1,5 @@
import { Skeleton } from '@/components/emcn'
-import { CredentialSkeleton } from '@/app/workspace/[workspaceId]/settings/components/credentials/credential-skeleton'
+import { CredentialSkeleton } from '@/app/workspace/[workspaceId]/settings/components/integrations/credential-skeleton'
/**
* Skeleton for the Integrations section shown during dynamic import loading.
diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/credentials/credentials-manager.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/secrets/secrets-manager.tsx
similarity index 98%
rename from apps/sim/app/workspace/[workspaceId]/settings/components/credentials/credentials-manager.tsx
rename to apps/sim/app/workspace/[workspaceId]/settings/components/secrets/secrets-manager.tsx
index fd04a8e7b3a..bbe2a290b25 100644
--- a/apps/sim/app/workspace/[workspaceId]/settings/components/credentials/credentials-manager.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/settings/components/secrets/secrets-manager.tsx
@@ -355,7 +355,7 @@ function NewWorkspaceVariableRow({
)
}
-export function CredentialsManager() {
+export function SecretsManager() {
const params = useParams()
const router = useRouter()
const workspaceId = (params?.workspaceId as string) || ''
@@ -474,10 +474,7 @@ export function CredentialsManager() {
[members]
)
- const adminMemberCount = useMemo(
- () => activeMembers.filter((member) => member.role === 'admin').length,
- [activeMembers]
- )
+ const adminMemberCount = activeMembers.filter((member) => member.role === 'admin').length
const isSelectedAdmin = selectedCredential?.role === 'admin'
@@ -1232,7 +1229,7 @@ export function CredentialsManager() {
aria-label='Copy value'
>
{copyIdSuccess ? (
-
+
) : (
)}
@@ -1287,7 +1284,10 @@ export function CredentialsManager() {
{activeMembers.map((member) => (
@@ -1342,10 +1342,20 @@ export function CredentialsManager() {
>
) : (
- <>
- {member.role}
-
- >
+ ({
+ value: option.value,
+ label: option.label,
+ }))}
+ value={
+ ROLE_OPTIONS.find((option) => option.value === member.role)?.label ||
+ ''
+ }
+ selectedValue={member.role}
+ placeholder='Role'
+ disabled
+ size='sm'
+ />
)}
))}
diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/credentials/credential-skeleton.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/secrets/secrets-skeleton.tsx
similarity index 50%
rename from apps/sim/app/workspace/[workspaceId]/settings/components/credentials/credential-skeleton.tsx
rename to apps/sim/app/workspace/[workspaceId]/settings/components/secrets/secrets-skeleton.tsx
index c6812a3d2de..11fc54def9f 100644
--- a/apps/sim/app/workspace/[workspaceId]/settings/components/credentials/credential-skeleton.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/settings/components/secrets/secrets-skeleton.tsx
@@ -4,30 +4,9 @@ const GRID_COLS = 'grid grid-cols-[minmax(0,1fr)_8px_minmax(0,1fr)_auto_auto] it
const COL_SPAN_ALL = 'col-span-5'
/**
- * Skeleton for a single integration credential row.
+ * Skeleton for a single secret row matching the secrets grid layout.
*/
-export function CredentialSkeleton() {
- return (
-
- )
-}
-
-/**
- * Skeleton for a single secret row matching the credentials grid layout.
- */
-function CredentialRowSkeleton() {
+function SecretRowSkeleton() {
return (
@@ -40,9 +19,9 @@ function CredentialRowSkeleton() {
}
/**
- * Skeleton for the Credentials (Secrets) page shown during dynamic import loading.
+ * Skeleton for the Secrets page shown during dynamic import loading.
*/
-export function CredentialsSkeleton() {
+export function SecretsSkeleton() {
return (
@@ -54,14 +33,14 @@ export function CredentialsSkeleton() {
diff --git a/apps/sim/app/workspace/[workspaceId]/settings/components/secrets/secrets.tsx b/apps/sim/app/workspace/[workspaceId]/settings/components/secrets/secrets.tsx
new file mode 100644
index 00000000000..7ee98cee9c4
--- /dev/null
+++ b/apps/sim/app/workspace/[workspaceId]/settings/components/secrets/secrets.tsx
@@ -0,0 +1,9 @@
+import { SecretsManager } from '@/app/workspace/[workspaceId]/settings/components/secrets/secrets-manager'
+
+export function Secrets() {
+ return (
+
+
+
+ )
+}
diff --git a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-sidebar/settings-sidebar.tsx b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-sidebar/settings-sidebar.tsx
index 947ce42a100..917e753861e 100644
--- a/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-sidebar/settings-sidebar.tsx
+++ b/apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/settings-sidebar/settings-sidebar.tsx
@@ -214,7 +214,7 @@ export function SettingsSidebar({
break
case 'secrets':
prefetchWorkspaceCredentials(queryClient, workspaceId)
- void import('@/app/workspace/[workspaceId]/settings/components/credentials/credentials')
+ void import('@/app/workspace/[workspaceId]/settings/components/secrets/secrets')
break
case 'subscription':
prefetchSubscriptionData(queryClient)