Skip to content
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,8 @@ export const useFormikValidationFix = (value: any) => {
} else {
validateForm();
}
}, [memoizedValue, validateForm]);
// validateForm is a stable function from Formik context and doesn't need to be in deps.
// Including it can cause infinite re-render loops when field arrays change.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [memoizedValue]);
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import * as React from 'react';
import { Content, ContentVariants } from '@patternfly/react-core';
import type { FormikHelpers, FormikValues } from 'formik';
import { Formik } from 'formik';
import * as _ from 'lodash';
import { useTranslation, Trans } from 'react-i18next';
import { Link } from 'react-router-dom-v5-compat';
import {
Expand All @@ -24,8 +24,10 @@ import {
getRolesWithMultipleSubjects,
getRolesToUpdate,
} from './project-access-form-submit-utils';
import { getUserRoleBindings, Roles } from './project-access-form-utils';
import { Verb, UserRoleBinding } from './project-access-form-utils-types';
import type { Roles } from './project-access-form-utils';
import { getUserRoleBindings } from './project-access-form-utils';
import type { UserRoleBinding } from './project-access-form-utils-types';
import { Verb } from './project-access-form-utils-types';
import { validationSchema } from './project-access-form-validation-utils';
import ProjectAccessForm from './ProjectAccessForm';

Expand All @@ -43,21 +45,31 @@ const ProjectAccess: React.FC<ProjectAccessProps> = ({
fullFormView,
}) => {
const { t } = useTranslation();
if ((!roleBindings.loaded && _.isEmpty(roleBindings.loadError)) || !roles.loaded) {
return <LoadingBox />;
}

const userRoleBindings: UserRoleBinding[] = getUserRoleBindings(
roleBindings.data,
Object.keys(roles.data),
namespace,
const userRoleBindings: UserRoleBinding[] = React.useMemo(
() =>
roleBindings?.loaded
? getUserRoleBindings(roleBindings.data, Object.keys(roles.data), namespace)
: [],
[roleBindings, roles.data, namespace],
);

const memoizedRoleBindings = React.useMemo(() => ({ projectAccess: userRoleBindings }), [
userRoleBindings,
]);

const rbacURL = getDocumentationURL(documentationURLs.usingRBAC);

const initialValues = {
projectAccess: roleBindings.loaded && userRoleBindings,
};
const initialValues = React.useMemo(
() => ({
projectAccess: roleBindings?.loaded && userRoleBindings,
}),
[roleBindings?.loaded, userRoleBindings],
);

if ((!roleBindings?.loaded && !roleBindings?.loadError) || !roles.loaded) {
return <LoadingBox />;
}

const handleSubmit = (values, actions) => {
let newRoles = getNewRoles(initialValues.projectAccess, values.projectAccess);
Expand Down Expand Up @@ -110,8 +122,9 @@ const ProjectAccess: React.FC<ProjectAccessProps> = ({
});
};

const handleReset = (values, actions) => {
actions.resetForm({ status: { success: null }, values: initialValues });
const handleReset = (_values: FormikValues, actions: FormikHelpers<FormikValues>) => {
actions.setStatus({ success: null });
actions.setValues(initialValues);
};

const projectAccessForm = (
Expand Down Expand Up @@ -156,7 +169,7 @@ const ProjectAccess: React.FC<ProjectAccessProps> = ({
<ProjectAccessForm
{...formikProps}
roles={roles.data}
roleBindings={initialValues}
roleBindings={memoizedRoleBindings}
onCancel={fullFormView ? history.goBack : null}
/>
)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const ProjectAccessForm: React.FC<ProjectAccessFormProps> = ({
roles,
roleBindings,
values,
initialValues,
onCancel,
}) => {
const { t } = useTranslation();
Expand All @@ -67,7 +68,7 @@ const ProjectAccessForm: React.FC<ProjectAccessFormProps> = ({
React.useEffect(() => {
!_.isEqual(
ignoreRoleBindingName(roleBindings.projectAccess),
ignoreRoleBindingName(values.projectAccess),
ignoreRoleBindingName(initialValues.projectAccess),
)
? setIsStaleInfo(true)
: setIsStaleInfo(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ describe('Project Access', () => {
roleBindings: {
data: [],
loaded: false,
loadError: {},
loadError: undefined,
},
roles: {
data: defaultAccessRoles,
Expand Down