{
content={t('Project.messages.share.header')}
/>
@@ -244,17 +262,17 @@ const ProjectForm = (props: Props) => {
content={t('Project.messages.archive.header')}
/>
)}
- { canDeleteProject(props.item.id) && (
+ { canDeleteProject(item.id) && (
@@ -351,19 +369,4 @@ const ProjectForm = (props: Props) => {
>
);
};
-const Project: any = withReactRouterEditPage(ProjectForm, {
- id: 'projectId',
- onInitialize: (id) => (
- ProjectsService
- .fetchOne(id)
- .then(({ data }) => data.project)
- ),
- onSave: (project) => (
- ProjectsService
- .save(project)
- .then(({ data }) => data.project)
- ),
- required: ['name']
-});
-
export default Project;
diff --git a/client/src/pages/ProjectModel.js b/client/src/pages/ProjectModel.js
index 87999c66..b9db85ec 100644
--- a/client/src/pages/ProjectModel.js
+++ b/client/src/pages/ProjectModel.js
@@ -39,7 +39,7 @@ import ProjectModelsUtils from '../utils/ProjectModels';
import ProjectsService from '../services/Projects';
import styles from './ProjectModel.module.css';
import useParams from '../hooks/ParsedParams';
-import withReactRouterEditPage from '../hooks/ReactRouterEditPage';
+import useReactRouterEditPage from '../hooks/useReactRouterEditPage';
const INVERSE_RELATIONSHIP_KEY = 'inverse_project_model_relationships';
const RELATIONSHIP_KEY = 'project_model_relationships';
@@ -48,7 +48,7 @@ type Props = EditContainerProps & {
item: ProjectModelType
};
-const ProjectModelForm = (props: Props) => {
+const ProjectModel = (props: Props) => {
const [accessModal, setAccessModal] = useState(false);
const [shareModal, setShareModal] = useState(false);
@@ -58,6 +58,24 @@ const ProjectModelForm = (props: Props) => {
const { setReloadProjectModels } = useContext(ProjectContext);
+ const editPageProps = useReactRouterEditPage({
+ id: 'projectModelId',
+ onInitialize: (id) => (
+ ProjectModelsService
+ .fetchOne(id)
+ .then(({ data }) => data.project_model)
+ ),
+ onSave: (projectModel) => (
+ ProjectModelsService
+ .save(projectModel)
+ .then(({ data }) => data.project_model)
+ ),
+ required: ['model_class', 'name'],
+ resolveValidationError: ProjectModelsUtils.resolveValidationError
+ });
+
+ const { item, onSetState } = editPageProps;
+
/**
* Returns the model name for the passed relationship based on context.
*
@@ -92,9 +110,9 @@ const ProjectModelForm = (props: Props) => {
*/
const onSaveRelationship = useCallback((relationship) => {
const association = relationship.inverse ? INVERSE_RELATIONSHIP_KEY : RELATIONSHIP_KEY;
- props.onSaveChildAssociation(association, relationship);
- props.onSaveChildAssociation('all_project_model_relationships', relationship);
- }, []);
+ editPageProps.onSaveChildAssociation(association, relationship);
+ editPageProps.onSaveChildAssociation('all_project_model_relationships', relationship);
+ }, [editPageProps.onSaveChildAssociation]);
/**
* Deletes the passed relationship from the appropriate collection.
@@ -103,9 +121,9 @@ const ProjectModelForm = (props: Props) => {
*/
const onDeleteRelationship = useCallback((relationship) => {
const association = relationship.inverse ? INVERSE_RELATIONSHIP_KEY : RELATIONSHIP_KEY;
- props.onDeleteChildAssociation(association, relationship);
- props.onDeleteChildAssociation('all_project_model_relationships', relationship);
- }, []);
+ editPageProps.onDeleteChildAssociation(association, relationship);
+ editPageProps.onDeleteChildAssociation('all_project_model_relationships', relationship);
+ }, [editPageProps.onDeleteChildAssociation]);
/**
* If we've saved the record, reload project models.
@@ -120,8 +138,8 @@ const ProjectModelForm = (props: Props) => {
* For a new record, set the foreign key ID based on the route parameters.
*/
useEffect(() => {
- if (!props.item.id && projectId) {
- props.onSetState({ project_id: projectId });
+ if (!item.id && projectId) {
+ onSetState({ project_id: projectId });
}
}, []);
@@ -133,12 +151,13 @@ const ProjectModelForm = (props: Props) => {
label: t('ProjectModel.labels.all'),
url: `/projects/${projectId}/project_models`
}}
- name={props.item.name}
+ name={item.name}
/>
{
name={t('ProjectModel.tabs.details')}
>
{
location: 'top'
}}
defaults={{
- table_name: props.item.model_class
+ table_name: item.model_class
}}
excludeColumns={['table_name', 'uuid']}
- items={props.item.user_defined_fields}
- onDelete={props.onDeleteChildAssociation.bind(this, 'user_defined_fields')}
- onSave={props.onSaveChildAssociation.bind(this, 'user_defined_fields')}
+ items={item.user_defined_fields}
+ onDelete={editPageProps.onDeleteChildAssociation.bind(this, 'user_defined_fields')}
+ onSave={editPageProps.onSaveChildAssociation.bind(this, 'user_defined_fields')}
/>
{
label: t('Common.columns.uuid'),
hidden: true
}]}
- items={props.item.all_project_model_relationships}
+ items={item.all_project_model_relationships}
modal={{
component: ProjectModelRelationshipModal
}}
@@ -266,7 +285,7 @@ const ProjectModelForm = (props: Props) => {
size='1rem'
/>
- { t('ProjectModel.accesses.message', { name: props.item.name }) }
+ { t('ProjectModel.accesses.message', { name: item.name }) }
{
label: t('ProjectModel.accesses.columns.name'),
resolve: (projectModelAccess) => projectModelAccess.project?.name
}]}
- items={props.item.project_model_accesses}
- onDelete={props.onDeleteChildAssociation.bind(this, 'project_model_accesses')}
- onSave={props.onSaveChildAssociation.bind(this, 'project_model_accesses')}
+ items={item.project_model_accesses}
+ onDelete={editPageProps.onDeleteChildAssociation.bind(this, 'project_model_accesses')}
+ onSave={editPageProps.onSaveChildAssociation.bind(this, 'project_model_accesses')}
/>
{ accessModal && (
{
onLoad={(params) => ProjectsService.fetchAll({
...params,
discoverable: true,
- project_id: props.item.project_id,
+ project_id: item.project_id,
sort_by: 'name'
})}
onSave={(projects) => {
- const find = (project) => _.findWhere(props.item.project_model_accesses, { project_id: project.id });
+ const find = (project) => _.findWhere(item.project_model_accesses, { project_id: project.id });
const create = (project) => ({ uid: uuid(), project_id: project.id, project });
- props.onMultiAddChildAssociations(
+ editPageProps.onMultiAddChildAssociations(
'project_model_accesses',
_.map(projects, (project) => find(project) || create(project))
);
@@ -310,7 +329,7 @@ const ProjectModelForm = (props: Props) => {
setAccessModal(false);
}}
renderItem={(project) => project.name}
- selectedItems={_.pluck(props.item.project_model_accesses, 'project')}
+ selectedItems={_.pluck(item.project_model_accesses, 'project')}
title={t('ProjectModel.accesses.title')}
width='60%'
/>
@@ -332,7 +351,7 @@ const ProjectModelForm = (props: Props) => {
size='1rem'
/>
- { t('ProjectModel.shares.message', { name: props.item.name }) }
+ { t('ProjectModel.shares.message', { name: item.name }) }
{
label: t('ProjectModel.shares.columns.modelName'),
resolve: (projectModelShare) => projectModelShare.project_model_access?.project_model?.name
}]}
- items={props.item.project_model_shares}
- onDelete={props.onDeleteChildAssociation.bind(this, 'project_model_shares')}
- onSave={props.onSaveChildAssociation.bind(this, 'project_model_shares')}
+ items={item.project_model_shares}
+ onDelete={editPageProps.onDeleteChildAssociation.bind(this, 'project_model_shares')}
+ onSave={editPageProps.onSaveChildAssociation.bind(this, 'project_model_shares')}
/>
{ shareModal && (
{
onClose={() => setShareModal(false)}
onLoad={(params) => ProjectModelAccessesService.fetchAll({
...params,
- project_id: props.item.project_id,
- model_class: props.item.model_class,
+ project_id: item.project_id,
+ model_class: item.model_class,
sort_by: [
'core_data_connector_projects.name',
'core_data_connector_project_models.name'
]
})}
onSave={(projectModelAccesses) => {
- const find = (projectModelAccess) => _.findWhere(props.item.project_model_shares, {
+ const find = (projectModelAccess) => _.findWhere(item.project_model_shares, {
project_model_access_id: projectModelAccess.id
});
@@ -382,7 +401,7 @@ const ProjectModelForm = (props: Props) => {
project_model_access: projectModelAccess
});
- props.onMultiAddChildAssociations(
+ editPageProps.onMultiAddChildAssociations(
'project_model_shares',
_.map(
projectModelAccesses,
@@ -398,7 +417,7 @@ const ProjectModelForm = (props: Props) => {
subheader={projectModelAccess.project_model.name}
/>
)}
- selectedItems={_.pluck(props.item.project_model_shares, 'project_model_access')}
+ selectedItems={_.pluck(item.project_model_shares, 'project_model_access')}
title={t('ProjectModel.shares.title')}
width='60%'
/>
@@ -410,20 +429,4 @@ const ProjectModelForm = (props: Props) => {
);
};
-const ProjectModel = withReactRouterEditPage(ProjectModelForm, {
- id: 'projectModelId',
- onInitialize: (id) => (
- ProjectModelsService
- .fetchOne(id)
- .then(({ data }) => data.project_model)
- ),
- onSave: (projectModel) => (
- ProjectModelsService
- .save(projectModel)
- .then(({ data }) => data.project_model)
- ),
- required: ['model_class', 'name'],
- resolveValidationError: ProjectModelsUtils.resolveValidationError.bind(this)
-});
-
export default ProjectModel;
diff --git a/client/src/pages/User.js b/client/src/pages/User.js
index 22d6370e..c87563f0 100644
--- a/client/src/pages/User.js
+++ b/client/src/pages/User.js
@@ -13,17 +13,40 @@ import UserPassword from '../components/UserPassword';
import UserUtils from '../utils/User';
import UsersService from '../services/Users';
import { useTranslation } from 'react-i18next';
-import withReactRouterEditPage from '../hooks/ReactRouterEditPage';
+import useReactRouterEditPage from '../hooks/useReactRouterEditPage';
type Props = EditContainerProps & {
item: UserType,
isNew?: boolean
};
-const UserFormComponent = (props: Props) => {
+const User = (props: Props) => {
const { t } = useTranslation();
const { canEditUsers, isSSO } = usePermissions();
- const isNew = props.isNew || !props.item.id;
+
+ const editPageProps = useReactRouterEditPage({
+ id: 'userId',
+ onInitialize: (id) => (
+ UsersService
+ .fetchOne(id)
+ .then(({ data }) => data.user)
+ ),
+ onSave: (user) => (
+ UsersService
+ .save(user)
+ .then(({ data }) => data.user)
+ ),
+ required: ['name', 'email', 'role'],
+ validate: (user) => {
+ if (user.id && (user.password || user.password_confirmation)) {
+ return UserUtils.validatePassword(user);
+ }
+ return null;
+ }
+ });
+
+ const { item } = editPageProps;
+ const isNew = props.isNew || !item.id;
if (!canEditUsers()) {
return ;
@@ -36,22 +59,25 @@ const UserFormComponent = (props: Props) => {
label: t('User.labels.allUsers'),
url: '/users'
}}
- name={isNew ? t('User.labels.inviteUser') : props.item.name}
+ name={isNew ? t('User.labels.inviteUser') : item.name}
/>
{ !isNew && !isSSO() && (
)}
@@ -60,25 +86,4 @@ const UserFormComponent = (props: Props) => {
);
};
-const User: AbstractComponent = withReactRouterEditPage(UserFormComponent, {
- id: 'userId',
- onInitialize: (id) => (
- UsersService
- .fetchOne(id)
- .then(({ data }) => data.user)
- ),
- onSave: (user) => (
- UsersService
- .save(user)
- .then(({ data }) => data.user)
- ),
- required: ['name', 'email', 'role'],
- validate: (user) => {
- if (user.id && (user.password || user.password_confirmation)) {
- return UserUtils.validatePassword(user);
- }
- return null;
- }
-});
-
export default User;
diff --git a/client/src/pages/UserProject.js b/client/src/pages/UserProject.js
index 916ae76f..c9cc0680 100644
--- a/client/src/pages/UserProject.js
+++ b/client/src/pages/UserProject.js
@@ -25,14 +25,14 @@ import UserProjectsService from '../services/UserProjects';
import UsersService from '../services/Users';
import useParams from '../hooks/ParsedParams';
import Validation from '../utils/Validation';
-import withReactRouterEditPage from '../hooks/ReactRouterEditPage';
+import useReactRouterEditPage from '../hooks/useReactRouterEditPage';
import { AuthenticationContext } from '../context/Authentication';
type Props = EditContainerProps & {
item: UserProjectType
};
-const UserProjectForm = (props: Props) => {
+const UserProject = (props: Props) => {
const params = useParams();
const { t } = useTranslation();
const {
@@ -42,19 +42,37 @@ const UserProjectForm = (props: Props) => {
} = usePermissions();
const { provider } = useContext(AuthenticationContext);
+ const editPageProps = useReactRouterEditPage({
+ id: 'userProjectId',
+ onInitialize: (id) => (
+ UserProjectsService
+ .fetchOne(id)
+ .then(({ data }) => data.user_project)
+ ),
+ onSave: (userProject) => (
+ UserProjectsService
+ .save(userProject)
+ .then(({ data }) => data.user_project)
+ ),
+ required: ['project_id', 'role'],
+ resolveValidationError: Validation.resolveUpdateError
+ });
+
+ const { item, onSetState } = editPageProps;
+
/**
* Memo-izes whether we're on a new record.
*
* @type {boolean}
*/
- const isNew = useMemo(() => !props.item.id, [props.item.id]);
+ const isNew = useMemo(() => !item.id, [item.id]);
/**
* Memo-izes if the current user is an owner of the current project.
*
* @type {boolean}
*/
- const isOwner = useMemo(() => isOwnerPermission(props.item.project_id), [isOwnerPermission, props.item.project_id]);
+ const isOwner = useMemo(() => isOwnerPermission(item.project_id), [isOwnerPermission, item.project_id]);
/**
* Callback fired when the project search is executed.
@@ -74,11 +92,11 @@ const UserProjectForm = (props: Props) => {
* For a new record, set the foreign key ID based on the route parameters.
*/
useEffect(() => {
- if (!props.item.id) {
+ if (!item.id) {
if (params.projectId) {
- props.onSetState({ project_id: params.projectId });
+ onSetState({ project_id: params.projectId });
} else if (params.userId) {
- props.onSetState({ user_id: params.userId });
+ onSetState({ user_id: params.userId });
}
}
}, []);
@@ -123,7 +141,7 @@ const UserProjectForm = (props: Props) => {
label: t('UserProject.labels.allUsers'),
url: `/projects/${params.projectId}/user_projects`
}}
- name={props.item.user?.name}
+ name={item.user?.name}
/>
)}
{ params.userId && (
@@ -132,36 +150,37 @@ const UserProjectForm = (props: Props) => {
label: t('UserProject.labels.allProjects'),
url: `/users/${params.userId}/user_projects`
}}
- name={props.item.project?.name}
+ name={item.project?.name}
/>
)}
{ canEditUsers() && params.userId && (
Project.toDropdown(project)}
- searchQuery={props.item.project?.name}
- value={props.item.project_id}
+ searchQuery={item.project?.name}
+ value={item.project_id}
/>
)}
{ canEditUsers() && params.projectId && (
@@ -169,28 +188,29 @@ const UserProjectForm = (props: Props) => {
collectionName='users'
modal={modal}
onSearch={onUserSearch}
- onSelection={props.onAssociationInputChange.bind(this, 'user_id', 'user')}
+ onSelection={editPageProps.onAssociationInputChange.bind(this, 'user_id', 'user')}
renderOption={(user) => User.toDropdown(user)}
- searchQuery={props.item.user?.name}
- value={props.item.user_id}
+ searchQuery={item.user?.name}
+ value={item.user_id}
/>
)}
{ !canEditUsers() && isOwner && isNew && (
)}
@@ -199,20 +219,4 @@ const UserProjectForm = (props: Props) => {
);
};
-const UserProject: AbstractComponent = withReactRouterEditPage(UserProjectForm, {
- id: 'userProjectId',
- onInitialize: (id) => (
- UserProjectsService
- .fetchOne(id)
- .then(({ data }) => data.user_project)
- ),
- onSave: (userProject) => (
- UserProjectsService
- .save(userProject)
- .then(({ data }) => data.user_project)
- ),
- required: ['project_id', 'role'],
- resolveValidationError: Validation.resolveUpdateError.bind(this)
-});
-
export default UserProject;
diff --git a/client/src/pages/WebAuthority.js b/client/src/pages/WebAuthority.js
index 3f5a4f26..ecd32955 100644
--- a/client/src/pages/WebAuthority.js
+++ b/client/src/pages/WebAuthority.js
@@ -18,44 +18,63 @@ import Validation from '../utils/Validation';
import type { WebAuthority as WebAuthorityType } from '../types/WebAuthority';
import WebAuthoritiesService from '../services/WebAuthorities';
import WebAuthorityUtils from '../utils/WebAuthorities';
-import withReactRouterEditPage from '../hooks/ReactRouterEditPage';
+import useReactRouterEditPage from '../hooks/useReactRouterEditPage';
type Props = EditContainerProps & {
item: WebAuthorityType
};
-const WebAuthorityPage = (props: Props) => {
+const WebAuthority = (props: Props) => {
const { projectId } = useParams();
const { t } = useTranslation();
const { canEditProjectSettings } = usePermissions();
+ const editPageProps = useReactRouterEditPage({
+ id: 'webAuthorityId',
+ onInitialize: (id) => (
+ WebAuthoritiesService
+ .fetchOne(id)
+ .then(({ data }) => data.web_authority)
+ ),
+ onSave: (authority) => (
+ WebAuthoritiesService
+ .save(authority)
+ .then(({ data }) => data.web_authority)
+ ),
+ required: ['source_type'],
+ resolveValidationError: Validation.resolveUpdateError,
+ validate: WebAuthorityUtils.validate
+ });
+
+ const { item, onSetState } = editPageProps;
+
/**
* Sets the passed value/key in the access JSON.
*
* @type {(function(*, *): void)|*}
*/
const onChange = useCallback((key, value) => {
- props.onSetState({
+ onSetState({
access: {
- ...props.item.access || {},
+ ...item.access || {},
[key]: value
}
});
- }, [props.onSetState, props.item.access]);
+ }, [onSetState, item.access]);
/**
* Clear "access" on source_type change
*/
useEffect(() => {
- props.onSetState({ access: {} });
- }, [props.item.source_type]);
+ onSetState({ access: {} });
+ }, [item.source_type]);
/**
* Set the project_id on the state for new records.
*/
useEffect(() => {
- if (!props.item.id && projectId) {
- props.onSetState({ project_id: projectId });
+ if (!item.id && projectId) {
+ onSetState({ project_id: projectId });
}
}, []);
@@ -71,46 +90,47 @@ const WebAuthorityPage = (props: Props) => {
label: t('WebAuthority.labels.all'),
url: `/projects/${projectId}/web_authorities`
}}
- name={WebAuthorityUtils.getSourceView(props.item)}
+ name={WebAuthorityUtils.getSourceView(item)}
/>
- { props.item.source_type === WebAuthorityUtils.SourceTypes.atom && (
+ { item.source_type === WebAuthorityUtils.SourceTypes.atom && (
)}
- { props.item.source_type === WebAuthorityUtils.SourceTypes.geonames && (
+ { item.source_type === WebAuthorityUtils.SourceTypes.geonames && (
)}
- { props.item.source_type === WebAuthorityUtils.SourceTypes.dpla && (
+ { item.source_type === WebAuthorityUtils.SourceTypes.dpla && (
)}
@@ -120,21 +140,4 @@ const WebAuthorityPage = (props: Props) => {
);
};
-const WebAuthority = withReactRouterEditPage(WebAuthorityPage, {
- id: 'webAuthorityId',
- onInitialize: (id) => (
- WebAuthoritiesService
- .fetchOne(id)
- .then(({ data }) => data.web_authority)
- ),
- onSave: (authority) => (
- WebAuthoritiesService
- .save(authority)
- .then(({ data }) => data.web_authority)
- ),
- required: ['source_type'],
- resolveValidationError: Validation.resolveUpdateError.bind(this),
- validate: WebAuthorityUtils.validate.bind(this)
-});
-
export default WebAuthority;
diff --git a/client/yarn.lock b/client/yarn.lock
index e574ea0e..529be76b 100644
--- a/client/yarn.lock
+++ b/client/yarn.lock
@@ -1099,18 +1099,18 @@
flow-remove-types "^2.158.0"
rollup-pluginutils "^2.8.2"
-"@clerk/react@^6.0.1":
- version "6.0.1"
- resolved "https://registry.yarnpkg.com/@clerk/react/-/react-6.0.1.tgz#75cc83f6c58f201d4492bdbaa24e22f9e1a3190e"
- integrity sha512-zq6vfH7Yiul4PPxUmyl/iW6CZbIzxfHvhXLxZK9zbqHQEy9xDlIQirhWIiHucBqMWTJruudY5KCV5WBe2xmfww==
+"@clerk/react@^6.3.0":
+ version "6.3.0"
+ resolved "https://registry.yarnpkg.com/@clerk/react/-/react-6.3.0.tgz#af146c18fe777e904dc84dc99ee555ccb7a13ccb"
+ integrity sha512-etqEqdP5WlVn1Bb1NF2Drgvn3UzBSXmrkKtluObTQeqOoCsTO0uFv40oDi7QBs9WQWY1tvavI5aIHzY+uHKcdw==
dependencies:
- "@clerk/shared" "^4.0.0"
+ "@clerk/shared" "^4.7.0"
tslib "2.8.1"
-"@clerk/shared@^4.0.0":
- version "4.0.0"
- resolved "https://registry.yarnpkg.com/@clerk/shared/-/shared-4.0.0.tgz#077f3e7bd17b290fddb5e7c3710f3a7227f13291"
- integrity sha512-Z3QhVud7FM9SBgSGxyUdC+nDg6vro+5zJ5gDO1To3FDzRLWKW4xIGd5y8UBqWZMMMHWaSDiZvYlUynb+gs8PnQ==
+"@clerk/shared@^4.7.0":
+ version "4.7.0"
+ resolved "https://registry.yarnpkg.com/@clerk/shared/-/shared-4.7.0.tgz#b442a734d937fcc6d89441e0df4e741a103ac4bd"
+ integrity sha512-pm2dpxHS2teY87jmpatprG2uBAuuXuHHWvuezL3a5pRoUiIWXgWlLvwRZRgKXwDeIkIT9UCAIQBkcjueSEzqHA==
dependencies:
"@tanstack/query-core" "5.90.16"
dequal "2.0.3"