Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ and this project adheres to

### Fixed

- Allow credentials (raw JSON, HTTP, OAuth) on common adaptor jobs
[#4513](https://github.com/OpenFn/lightning/pull/4513)
- Migrate form error display from `phx-feedback-for` to `used_input?/1` so
validation errors only appear on fields the user has interacted with
[#4472](https://github.com/OpenFn/lightning/pull/4472)
Expand Down
42 changes: 15 additions & 27 deletions assets/js/collaborative-editor/components/ConfigureAdaptorModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -277,13 +277,6 @@ export function ConfigureAdaptorModal({
onCredentialChange,
]);

// Check if the adaptor requires credentials
const adaptorNeedsCredentials = useMemo(() => {
const adaptorName = extractAdaptorName(currentAdaptor);
// Common adaptor doesn't require credentials
return adaptorName !== 'common';
}, [currentAdaptor]);

// Filter credentials into sections
const credentialSections = useMemo(() => {
const adaptorName = extractAdaptorName(currentAdaptor);
Expand Down Expand Up @@ -442,7 +435,10 @@ export function ConfigureAdaptorModal({
const handleCreateCredential = () => {
const adaptorName = extractAdaptorName(currentAdaptor);
if (adaptorName) {
onOpenCredentialModal(adaptorName);
// Adaptors like "common" have no credential schema file, so default
// to "raw" (Raw JSON) which is the most flexible credential type.
const schema = adaptorName === 'common' ? 'raw' : adaptorName;
onOpenCredentialModal(schema);
}
};

Expand Down Expand Up @@ -590,27 +586,19 @@ export function ConfigureAdaptorModal({
/>
</Tooltip>
</span>
{adaptorNeedsCredentials && (
<button
type="button"
aria-label="Create new credential"
className="text-primary-600 hover:text-primary-700 text-sm font-medium underline focus:outline-none"
onClick={handleCreateCredential}
>
New Credential
</button>
)}
<button
type="button"
aria-label="Create new credential"
className="text-primary-600 hover:text-primary-700 text-sm font-medium underline focus:outline-none"
onClick={handleCreateCredential}
>
New Credential
</button>
</div>

{!adaptorNeedsCredentials ? (
<div className="border border-gray-200 rounded-md p-6 text-center bg-gray-50">
<p className="text-gray-600 text-sm">
This adaptor does not require credentials.
</p>
</div>
) : credentialSections.schemaMatched.length === 0 &&
credentialSections.universal.length === 0 &&
credentialSections.keychain.length === 0 ? (
{credentialSections.schemaMatched.length === 0 &&
credentialSections.universal.length === 0 &&
credentialSections.keychain.length === 0 ? (
<div className="border border-gray-200 rounded-md p-6 text-center">
<p className="text-gray-500 mb-3">
No credentials found in this project
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -742,35 +742,32 @@ describe('ConfigureAdaptorModal', () => {
expect(radioButtons.length).toBe(3);
});

it("shows informative message for adaptors that don't need credentials", () => {
it('shows universal and keychain credentials for common adaptor', () => {
renderWithProviders(
<ConfigureAdaptorModal
{...defaultProps}
currentAdaptor="@openfn/language-common"
/>
);

// Should show message that adaptor doesn't need credentials
// Should NOT show message that adaptor doesn't need credentials
expect(
screen.getByText('This adaptor does not require credentials.')
).toBeInTheDocument();

// Should NOT show credential list or New Credential button
expect(screen.queryByText('HTTP API Key')).not.toBeInTheDocument();
expect(screen.queryByText('Keychain Salesforce')).not.toBeInTheDocument();
expect(
screen.queryByText('Salesforce Production')
screen.queryByText('This adaptor does not require credentials.')
).not.toBeInTheDocument();

// New Credential button should be hidden
// Should show universal credentials (http, raw, oauth) and keychain
expect(screen.getByText('HTTP API Key')).toBeInTheDocument();
expect(screen.getByText('Keychain Salesforce')).toBeInTheDocument();

// Should NOT show schema-specific credentials (no schema matches "common")
expect(
screen.queryByRole('button', { name: /new credential/i })
screen.queryByText('Salesforce Production')
).not.toBeInTheDocument();

// Should NOT show "Back to matching credentials" link (no matching credentials to go back to)
// New Credential button should be available
expect(
screen.queryByText(/back to matching credentials/i)
).not.toBeInTheDocument();
screen.getByRole('button', { name: /new credential/i })
).toBeInTheDocument();
});

it('allows manual toggle between matching and other credentials', async () => {
Expand Down