Skip to content

Commit 7513b0e

Browse files
committed
Allow imports from utils for atoms
1 parent a4f9fa6 commit 7513b0e

4 files changed

Lines changed: 15 additions & 15 deletions

File tree

packages/agentflow/.eslintrc.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,8 +119,8 @@ module.exports = {
119119
{
120120
target: './src/atoms',
121121
from: './src/core',
122-
except: ['./types', './theme'],
123-
message: 'Atoms can only import from core/types and core/theme, not utilities or business logic.'
122+
except: ['./types', './theme', './utils'],
123+
message: 'Atoms can only import from core/types, core/theme, and core/utils.'
124124
},
125125
// core/ cannot import from anything (leaf node)
126126
{

packages/agentflow/ARCHITECTURE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ atoms/
4242
- No API calls
4343
- Stateless or minimal local state
4444
- Imported by features, never the reverse
45-
- **Forbidden**: Importing from `features/` or `infrastructure/` (except types from `core/types` for prop definitions and design tokens from `core/theme`)
45+
- **Forbidden**: Importing from `features/` or `infrastructure/` (except types from `core/types` for prop definitions, design tokens from `core/theme`, and utilities from `core/utils`)
4646

4747
**Goal:** 100% visual consistency.
4848

packages/agentflow/src/features/node-editor/AsyncInput.test.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jest.mock('@tabler/icons-react', () => ({
2020
}))
2121

2222
jest.mock('./CreateCredentialDialog', () => ({
23-
CreateCredentialDialog: ({ open, onCreated, onClose }: any) =>
23+
CreateCredentialDialog: ({ open, onCreated, onClose }: { open: boolean; onCreated: (id: string) => void; onClose: () => void }) =>
2424
open ? (
2525
<div data-testid='create-credential-dialog'>
2626
<button onClick={() => onCreated('new-cred-id')}>Create</button>

packages/agentflow/src/features/node-editor/CreateCredentialDialog.tsx

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useCallback, useEffect, useMemo, useState } from 'react'
1+
import { useCallback, useEffect, useState } from 'react'
22

33
import {
44
Alert,
@@ -46,10 +46,10 @@ export function CreateCredentialDialog({ open, credentialNames, onClose, onCreat
4646
const [submitting, setSubmitting] = useState(false)
4747
const [error, setError] = useState<string | null>(null)
4848

49-
// Stabilize credentialNames so the effect doesn't re-fire on every render
50-
// when the parent passes an inline array (e.g. credentialNames={['openAIApi']}).
49+
// Stable string key for credentialNames — a new array reference on every render
50+
// (e.g. inline credentialNames={['openAIApi']}) would otherwise restart the effect.
51+
// Using the joined string as the dependency ensures value-based comparison.
5152
const credentialNamesKey = credentialNames.join('\0')
52-
const stableCredentialNames = useMemo(() => credentialNames, [credentialNamesKey])
5353

5454
const selectSchema = useCallback((schema: ComponentCredentialSchema) => {
5555
setSelectedSchema(schema)
@@ -77,18 +77,18 @@ export function CreateCredentialDialog({ open, credentialNames, onClose, onCreat
7777
setCredentialName('')
7878
setFormValues({})
7979

80+
// Reconstruct names from the stable key to avoid depending on the array reference
81+
const names = credentialNamesKey.split('\0')
82+
8083
try {
81-
if (stableCredentialNames.length === 1) {
82-
const schema = await credentialsApi.getComponentCredentialSchema(stableCredentialNames[0])
84+
if (names.length === 1) {
85+
const schema = await credentialsApi.getComponentCredentialSchema(names[0])
8386
if (!cancelled) {
8487
setSchemas([schema])
8588
selectSchema(schema)
8689
}
8790
} else {
88-
// Fetch each schema individually
89-
const results = await Promise.all(
90-
stableCredentialNames.map((name) => credentialsApi.getComponentCredentialSchema(name))
91-
)
91+
const results = await Promise.all(names.map((name) => credentialsApi.getComponentCredentialSchema(name)))
9292
if (!cancelled) {
9393
setSchemas(results)
9494
}
@@ -109,7 +109,7 @@ export function CreateCredentialDialog({ open, credentialNames, onClose, onCreat
109109
return () => {
110110
cancelled = true
111111
}
112-
}, [open, stableCredentialNames, credentialsApi, selectSchema])
112+
}, [open, credentialNamesKey, credentialsApi, selectSchema])
113113

114114
const handleFieldChange = useCallback((fieldName: string, value: unknown) => {
115115
setFormValues((prev) => ({ ...prev, [fieldName]: value }))

0 commit comments

Comments
 (0)