Skip to content
Closed
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
17 changes: 11 additions & 6 deletions src/views/credentials/Credentials.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, {
Fragment,
useMemo,
useRef,
useState,
useEffect,
Expand Down Expand Up @@ -112,9 +113,13 @@ export const Credentials = React.forwardRef(
const tokens = useTokens()
const styles = getStyles(tokens, isSmall)
const getNextDelay = getDelay(0, 100)
const initialValues = buildInitialValues(credentials)
const formSchema = buildFormSchema(credentials)
const loginFieldCount = credentials.length
const sortedCredentials = useMemo(
() => [...credentials].sort((a, b) => (a.display_order ?? Infinity) - (b.display_order ?? Infinity)),
[credentials],
)
const initialValues = buildInitialValues(sortedCredentials)
const formSchema = buildFormSchema(sortedCredentials)
const loginFieldCount = sortedCredentials.length
const showDisconnectOption =
currentMember &&
currentMember.is_managed_by_user &&
Expand Down Expand Up @@ -249,7 +254,7 @@ export const Credentials = React.forwardRef(
const inputRefs = useRef({})

useEffect(() => {
for (const field of credentials) {
for (const field of sortedCredentials) {

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The original code had the same pattern — credentials was used in this effect without being in the dependency array. This change only swapped the variable name; the dependency array behaviour is pre-existing.

if (errors[field.field_name]) {
inputRefs.current[field.field_name]?.focus()
break
Expand All @@ -258,7 +263,7 @@ export const Credentials = React.forwardRef(
}, [errors])

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above — pre-existing dependency array pattern, not introduced by this change.


function attemptConnect() {
const credentialsPayload = credentials.map((credential) => {
const credentialsPayload = sortedCredentials.map((credential) => {
return {
guid: credential.guid,
value: values[credential.field_name],
Expand Down Expand Up @@ -443,7 +448,7 @@ export const Credentials = React.forwardRef(
onSubmit={(e) => e.preventDefault()}
style={styles.form}
>
{credentials.map((field) => (
{sortedCredentials.map((field) => (
<SlideDown delay={getNextDelay()} key={field.guid}>
{field.field_type === CREDENTIAL_FIELD_TYPES.PASSWORD ? (
<div style={errors[field.field_name] ? styles.passwordInputError : {}}>
Expand Down
65 changes: 65 additions & 0 deletions src/views/credentials/__tests__/Credentials-test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,71 @@ describe('Credentials', () => {
expect(screen.getByText('Data access by')).toBeInTheDocument()
})
})
it('renders credentials in display_order regardless of API response order', async () => {
const reversedCredentialProps = {
...credentialProps,
credentials: [
{
guid: 'CRD-456',
label: 'Password',
field_name: 'password',
field_type: 1,
display_order: 2,
},
{
guid: 'CRD-123',
label: 'Username',
field_name: 'username',
field_type: 3,
display_order: 1,
},
],
}
const ref = React.createRef()
render(<Credentials {...reversedCredentialProps} ref={ref} />, {
preloadedState: initialStateCopy,
})

const usernameField = await screen.findByLabelText(/Enter your Username/i)
const passwordField = await screen.findByLabelText(/Password/i)
const passwordFollowsUsername =
usernameField.compareDocumentPosition(passwordField) &
Node.DOCUMENT_POSITION_FOLLOWING
expect(passwordFollowsUsername).toBeTruthy()
})

it('sorts credentials without display_order to the end', async () => {
const mixedCredentialProps = {
...credentialProps,
credentials: [
{
guid: 'CRD-789',
label: 'PIN',
field_name: 'pin',
field_type: 3,
},
{
guid: 'CRD-123',
label: 'Username',
field_name: 'username',
field_type: 3,
display_order: 1,
},
],
}
const ref = React.createRef()
render(<Credentials {...mixedCredentialProps} ref={ref} />, {
preloadedState: initialStateCopy,
})

const usernameField = await screen.findByLabelText(/Enter your Username/i)
const pinField = await screen.findByLabelText(/Enter your PIN/i)
const pinFollowsUsername =
usernameField.compareDocumentPosition(pinField) &
Node.DOCUMENT_POSITION_FOLLOWING
expect(pinFollowsUsername).toBeTruthy()
})

it('renders credentials and makes sure that the powered by MX footer is not present', () => {
const ref = React.createRef()
render(<Credentials {...credentialProps} ref={ref} />, { preloadedState: initialStateCopy })
Expand Down