+ );
+ }
+ return null;
+}
diff --git a/src/client/controllers/type-editor/relationship-type.tsx b/src/client/controllers/type-editor/relationship-type.tsx
new file mode 100644
index 0000000000..e04265a076
--- /dev/null
+++ b/src/client/controllers/type-editor/relationship-type.tsx
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023 Shivam Awasthi
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+import {extractChildProps, extractLayoutProps} from '../../helpers/props';
+import {AppContainer} from 'react-hot-loader';
+import Layout from '../../containers/layout';
+import React from 'react';
+import ReactDOM from 'react-dom';
+import RelationshipTypeEditor from '../../components/forms/type-editor/relationship-type';
+
+
+const propsTarget = document.getElementById('props');
+const props = propsTarget ? JSON.parse(propsTarget.innerHTML) : {};
+
+ReactDOM.hydrate(
+
+
+
+
+ ,
+ document.getElementById('target')
+);
+
+
+/*
+ * As we are not exporting a component,
+ * we cannot use the react-hot-loader module wrapper,
+ * but instead directly use webpack Hot Module Replacement API
+ */
+
+if (module.hot) {
+ module.hot.accept();
+}
+
diff --git a/src/server/helpers/middleware.ts b/src/server/helpers/middleware.ts
index 0349ec2bfe..3cc31ea731 100644
--- a/src/server/helpers/middleware.ts
+++ b/src/server/helpers/middleware.ts
@@ -71,6 +71,8 @@ export const loadSeriesOrderingTypes =
makeLoader('SeriesOrderingType', 'seriesOrderingTypes');
export const loadRelationshipTypes =
makeLoader('RelationshipType', 'relationshipTypes', null, ['attributeTypes']);
+export const loadParentRelationshipTypes =
+ makeLoader('RelationshipType', 'parentTypes');
export const loadGenders =
makeLoader('Gender', 'genders', (a, b) => a.id > b.id);
diff --git a/src/server/routes.js b/src/server/routes.js
index 999b1e1fa1..3974439375 100644
--- a/src/server/routes.js
+++ b/src/server/routes.js
@@ -31,6 +31,7 @@ import indexRouter from './routes/index';
import mergeRouter from './routes/merge';
import publisherRouter from './routes/entity/publisher';
import registerRouter from './routes/register';
+import relationshipTypeRouter from './routes/type-editor/relationship-type';
import reviewsRouter from './routes/reviews';
import revisionRouter from './routes/revision';
import revisionsRouter from './routes/revisions';
@@ -56,6 +57,7 @@ function initRootRoutes(app) {
app.use('/external-service', externalServiceRouter);
app.use('/admin-panel', adminPanelRouter);
app.use('/admin-logs', adminLogsRouter);
+ app.use('/relationship-type', relationshipTypeRouter);
}
function initEditionGroupRoutes(app) {
diff --git a/src/server/routes/type-editor/relationship-type.tsx b/src/server/routes/type-editor/relationship-type.tsx
new file mode 100644
index 0000000000..18154f8a2e
--- /dev/null
+++ b/src/server/routes/type-editor/relationship-type.tsx
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2023 Shivam Awasthi
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+import * as auth from '../../helpers/auth';
+import * as middleware from '../../helpers/middleware';
+import * as propHelpers from '../../../client/helpers/props';
+import {escapeProps, generateProps} from '../../helpers/props';
+import Layout from '../../../client/containers/layout';
+import React from 'react';
+import ReactDOMServer from 'react-dom/server';
+import RelationshipTypeEditor from '../../../client/components/forms/type-editor/relationship-type';
+import express from 'express';
+import target from '../../templates/target';
+
+
+const router = express.Router();
+
+router.get('/create', auth.isAuthenticated, middleware.loadParentRelationshipTypes, (req, res) => {
+ const {parentTypes} = res.locals;
+ const props = generateProps(req, res, {
+ parentTypes
+ });
+ const script = '/js/relationship-type/create.js';
+ const markup = ReactDOMServer.renderToString(
+
+
+
+ );
+ res.send(target({
+ markup,
+ props: escapeProps(props),
+ script
+ }));
+});
+
+export default router;
diff --git a/src/server/routes/type-editor/relationship-types.tsx b/src/server/routes/type-editor/relationship-types.tsx
new file mode 100644
index 0000000000..aa6e5a2303
--- /dev/null
+++ b/src/server/routes/type-editor/relationship-types.tsx
@@ -0,0 +1,90 @@
+// /*
+// * Copyright (C) 2023 Shivam Awasthi
+// *
+// * This program is free software; you can redistribute it and/or modify
+// * it under the terms of the GNU General Public License as published by
+// * the Free Software Foundation; either version 2 of the License, or
+// * (at your option) any later version.
+// *
+// * This program is distributed in the hope that it will be useful,
+// * but WITHOUT ANY WARRANTY; without even the implied warranty of
+// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// * GNU General Public License for more details.
+// *
+// * You should have received a copy of the GNU General Public License along
+// * with this program; if not, write to the Free Software Foundation, Inc.,
+// * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+// */
+
+// import * as propHelpers from '../../../client/helpers/props';
+// import {escapeProps, generateProps} from '../../helpers/props';
+// import {getIntFromQueryParams, parseQuery} from '../../helpers/utils';
+// import Layout from '../../../client/containers/layout';
+// import React from 'react';
+// import ReactDOMServer from 'react-dom/server';
+// import express from 'express';
+// import {getNextEnabledAndResultsArray} from '../../../common/helpers/utils';
+// import {getOrderedAdminLogs} from '../../helpers/adminLogs';
+// import target from '../../templates/target';
+// import RelationshipTypesPage from '../../../client/components/pages/relationshipTypes';
+
+
+// const router = express.Router();
+
+// router.get('/', async (req, res, next) => {
+// const {orm} = req.app.locals;
+// const query = parseQuery(req.url);
+// const size = getIntFromQueryParams(query, 'size', 20);
+// const from = getIntFromQueryParams(query, 'from');
+
+// function render(results, nextEnabled) {
+// const props = generateProps(req, res, {
+// from,
+// nextEnabled,
+// results,
+// size
+// });
+
+// const markup = ReactDOMServer.renderToString(
+//
+//
+//
+// );
+
+// res.send(target({
+// markup,
+// props: escapeProps(props),
+// script: '/js/relationshipTypes.js',
+// title: 'Relationship Types'
+// }));
+// }
+
+// try {
+// // fetch 1 more relationship type than required to check nextEnabled
+// const orderedRelationshipTypes = await getOrderedRelationshipTypes(from, size + 1, orm);
+// const {newResultsArray, nextEnabled} = getNextEnabledAndResultsArray(orderedRelationshipTypes, size);
+// return render(newResultsArray, nextEnabled);
+// }
+// catch (err) {
+// return next(err);
+// }
+// });
+
+
+// // eslint-disable-next-line consistent-return
+// router.get('/admin-logs', async (req, res, next) => {
+// const {orm} = req.app.locals;
+// const query = parseQuery(req.url);
+// const size = getIntFromQueryParams(query, 'size', 20);
+// const from = getIntFromQueryParams(query, 'from');
+
+// try {
+// const orderedLogs = await getOrderedAdminLogs(from, size, orm);
+// res.json(orderedLogs);
+// }
+// catch (err) {
+// return next(err);
+// }
+// });
+
+// export default router;
diff --git a/webpack.client.js b/webpack.client.js
index 9bcfc4e5ac..3a19173e05 100644
--- a/webpack.client.js
+++ b/webpack.client.js
@@ -41,7 +41,8 @@ const clientConfig = {
'entity-editor': ['./entity-editor/controller.js'],
'unified-form':['./unified-form/controller.js'],
'entity-merge': ['./entity-editor/entity-merge.tsx'],
- style: './stylesheets/style.scss'
+ style: './stylesheets/style.scss',
+ 'relationship-type/create': ['./controllers/type-editor/relationship-type.tsx']
},
externals: {
moment: 'moment'
From a675445f37f07bb3c79f93ad7bc5610c43ec0028 Mon Sep 17 00:00:00 2001
From: the-good-boy
Date: Mon, 31 Jul 2023 20:35:39 +0530
Subject: [PATCH 02/24] feat(RelationshipTypes): Add a Relationship Types page
---
.../pages/parts/relationship-types-tree.tsx | 104 ++++++++++++++++++
.../components/pages/relationshipTypes.tsx | 43 ++++++++
src/client/controllers/relationshipTypes.tsx | 49 +++++++++
src/server/helpers/typeRouteUtils.ts | 104 ++++++++++++++++++
src/server/routes.js | 2 +
src/server/routes/relationship-types.tsx | 49 +++++++++
.../routes/type-editor/relationship-types.tsx | 90 ---------------
webpack.client.js | 1 +
8 files changed, 352 insertions(+), 90 deletions(-)
create mode 100644 src/client/components/pages/parts/relationship-types-tree.tsx
create mode 100644 src/client/components/pages/relationshipTypes.tsx
create mode 100644 src/client/controllers/relationshipTypes.tsx
create mode 100644 src/server/helpers/typeRouteUtils.ts
create mode 100644 src/server/routes/relationship-types.tsx
delete mode 100644 src/server/routes/type-editor/relationship-types.tsx
diff --git a/src/client/components/pages/parts/relationship-types-tree.tsx b/src/client/components/pages/parts/relationship-types-tree.tsx
new file mode 100644
index 0000000000..db0a646422
--- /dev/null
+++ b/src/client/components/pages/parts/relationship-types-tree.tsx
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2023 Shivam Awasthi
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+import React, {useCallback, useState} from 'react';
+import {Button} from 'react-bootstrap';
+import {RelationshipTypeDataT} from '../../forms/type-editor/typeUtils';
+
+
+type RelationshipTypeTreePropsT = {
+ relationshipTypes: RelationshipTypeDataT[],
+ parentId?: number | null,
+ indentLevel?: number
+};
+
+function RelationshipTypeTree({relationshipTypes, parentId, indentLevel}: RelationshipTypeTreePropsT) {
+ const [expandedRelationshipTypeIds, setExpandedRelationshipTypeIds] = useState([]);
+
+ function toggleExpand(relTypeId) {
+ setExpandedRelationshipTypeIds((prevExpandedIds) => {
+ if (prevExpandedIds.includes(relTypeId)) {
+ return prevExpandedIds.filter((id) => id !== relTypeId);
+ }
+ return [...prevExpandedIds, relTypeId];
+ });
+ }
+
+ const handleClick = useCallback((event) => {
+ const relationshipTypeId = parseInt(event.target.value, 10);
+ toggleExpand(relationshipTypeId);
+ }, [expandedRelationshipTypeIds]);
+
+ const filteredRelationshipTypes = relationshipTypes.filter((relType) => relType.parentId === parentId);
+
+ return (
+
+ );
+}
+
+RelationshipTypeTree.defaultProps = {
+ indentLevel: 0,
+ parentId: null
+};
+
+export default RelationshipTypeTree;
diff --git a/src/client/components/pages/relationshipTypes.tsx b/src/client/components/pages/relationshipTypes.tsx
new file mode 100644
index 0000000000..d589261587
--- /dev/null
+++ b/src/client/components/pages/relationshipTypes.tsx
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2023 Shivam Awasthi
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+import {Card} from 'react-bootstrap';
+import React from 'react';
+import {RelationshipTypeDataT} from '../forms/type-editor/typeUtils';
+import RelationshipTypeTree from './parts/relationship-types-tree';
+
+
+type Props = {
+ relationshipTypes: RelationshipTypeDataT[]
+};
+
+function RelationshipTypesPage({relationshipTypes}: Props) {
+ return (
+
+
+ Relationship Types
+
+
+
+
+
+ );
+}
+
+export default RelationshipTypesPage;
diff --git a/src/client/controllers/relationshipTypes.tsx b/src/client/controllers/relationshipTypes.tsx
new file mode 100644
index 0000000000..fd01373c9d
--- /dev/null
+++ b/src/client/controllers/relationshipTypes.tsx
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 Shivam Awasthi
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+import {AppContainer} from 'react-hot-loader';
+import Layout from '../containers/layout';
+import React from 'react';
+import ReactDOM from 'react-dom';
+import RelationshipTypesPage from '../components/pages/relationshipTypes';
+import {extractLayoutProps} from '../helpers/props';
+
+
+const propsTarget = document.getElementById('props');
+const props = propsTarget ? JSON.parse(propsTarget.innerHTML) : {};
+const markup = (
+
+
+
+
+
+);
+
+ReactDOM.hydrate(markup, document.getElementById('target'));
+
+/*
+ * As we are not exporting a component,
+ * we cannot use the react-hot-loader module wrapper,
+ * but instead directly use webpack Hot Module Replacement API
+ */
+
+if (module.hot) {
+ module.hot.accept();
+}
diff --git a/src/server/helpers/typeRouteUtils.ts b/src/server/helpers/typeRouteUtils.ts
new file mode 100644
index 0000000000..42d77f9c8e
--- /dev/null
+++ b/src/server/helpers/typeRouteUtils.ts
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2023 Shivam Awasthi
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+function getChangedAttributeTypes(oldAttributes, newAttributes) {
+ const attributesCommon = oldAttributes.filter(value => newAttributes.includes(value));
+ const attributesToBeRemoved = oldAttributes.filter(value => !attributesCommon.includes(value));
+ const attributesToBeAdded = newAttributes.filter(value => !attributesCommon.includes(value));
+
+ return {attributesToBeAdded, attributesToBeRemoved};
+}
+
+/**
+ * A handler for create or edit actions on relationship types.
+ * @param {object} req - request object
+ * @param {object} res - response object
+ * @param {object} next - next object
+ * @returns {promise} res.send promise
+ * @description
+ * Creates a new reationship type or updates an existing relationship type
+ */
+export async function relationshipTypeCreateOrEditHandler(req, res, next) {
+ try {
+ const {RelationshipType, RelationshipTypeAttributeType, bookshelf} = req.app.locals.orm;
+ const trx = await bookshelf.transaction();
+ let newRelationshipType;
+ let method;
+ if (!req.params.id) {
+ newRelationshipType = await RelationshipType.forge();
+ method = 'insert';
+ }
+ else {
+ newRelationshipType = await RelationshipType.forge({id: parseInt(req.params.id, 10)}).fetch({
+ require: true
+ });
+ method = 'update';
+ }
+ const {
+ attributeTypes,
+ childOrder,
+ deprecated,
+ description,
+ label,
+ linkPhrase,
+ oldAttributeTypes,
+ parentId,
+ reverseLinkPhrase,
+ sourceEntityType,
+ targetEntityType
+ } = req.body;
+
+
+ newRelationshipType.set('description', description);
+ newRelationshipType.set('label', label);
+ newRelationshipType.set('deprecated', deprecated);
+ newRelationshipType.set('linkPhrase', linkPhrase);
+ newRelationshipType.set('reverseLinkPhrase', reverseLinkPhrase);
+ newRelationshipType.set('childOrder', childOrder);
+ newRelationshipType.set('parentId', parentId);
+ newRelationshipType.set('sourceEntityType', sourceEntityType);
+ newRelationshipType.set('targetEntityType', targetEntityType);
+
+ const relationshipType = await newRelationshipType.save(null, {method}, {transacting: trx});
+ // Attributes
+ const {attributesToBeAdded, attributesToBeRemoved} = getChangedAttributeTypes(oldAttributeTypes, attributeTypes);
+
+ attributesToBeRemoved.map(async attributeID => {
+ await new RelationshipTypeAttributeType()
+ .query((qb) => {
+ qb.where('relationship_type', newRelationshipType.id);
+ qb.where('attribute_type', attributeID);
+ }).destroy();
+ });
+
+ attributesToBeAdded.map(async attributeID => {
+ const newRelTypeAttrType = await new RelationshipTypeAttributeType();
+ newRelTypeAttrType.set('relationshipType', relationshipType.id);
+ newRelTypeAttrType.set('attributeType', attributeID);
+
+ await newRelTypeAttrType.save(null, {method: 'insert'}, {transacting: trx});
+ });
+
+ await trx.commit();
+
+ return res.send(relationshipType.toJSON());
+ }
+ catch (err) {
+ return next(err);
+ }
+}
diff --git a/src/server/routes.js b/src/server/routes.js
index 3974439375..a4c3d66981 100644
--- a/src/server/routes.js
+++ b/src/server/routes.js
@@ -32,6 +32,7 @@ import mergeRouter from './routes/merge';
import publisherRouter from './routes/entity/publisher';
import registerRouter from './routes/register';
import relationshipTypeRouter from './routes/type-editor/relationship-type';
+import relationshipTypesRouter from './routes/relationship-types';
import reviewsRouter from './routes/reviews';
import revisionRouter from './routes/revision';
import revisionsRouter from './routes/revisions';
@@ -58,6 +59,7 @@ function initRootRoutes(app) {
app.use('/admin-panel', adminPanelRouter);
app.use('/admin-logs', adminLogsRouter);
app.use('/relationship-type', relationshipTypeRouter);
+ app.use('/relationship-types', relationshipTypesRouter);
}
function initEditionGroupRoutes(app) {
diff --git a/src/server/routes/relationship-types.tsx b/src/server/routes/relationship-types.tsx
new file mode 100644
index 0000000000..01c4aaff3d
--- /dev/null
+++ b/src/server/routes/relationship-types.tsx
@@ -0,0 +1,49 @@
+/*
+ * Copyright (C) 2023 Shivam Awasthi
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+import * as middleware from '../helpers/middleware';
+import * as propHelpers from '../../client/helpers/props';
+import {escapeProps, generateProps} from '../helpers/props';
+import Layout from '../../client/containers/layout';
+import React from 'react';
+import ReactDOMServer from 'react-dom/server';
+import RelationshipTypesPage from '../../client/components/pages/relationshipTypes';
+import express from 'express';
+import target from '../templates/target';
+
+
+const router = express.Router();
+
+router.get('/', middleware.loadRelationshipTypes, (req, res) => {
+ const {relationshipTypes} = res.locals;
+ const props = generateProps(req, res, {
+ relationshipTypes
+ });
+ const markup = ReactDOMServer.renderToString(
+
+
+
+ );
+ res.send(target({
+ markup,
+ props: escapeProps(props),
+ script: '/js/relationshipTypes.js',
+ title: 'Relationship Types'
+ }));
+});
+
+export default router;
diff --git a/src/server/routes/type-editor/relationship-types.tsx b/src/server/routes/type-editor/relationship-types.tsx
deleted file mode 100644
index aa6e5a2303..0000000000
--- a/src/server/routes/type-editor/relationship-types.tsx
+++ /dev/null
@@ -1,90 +0,0 @@
-// /*
-// * Copyright (C) 2023 Shivam Awasthi
-// *
-// * This program is free software; you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation; either version 2 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License along
-// * with this program; if not, write to the Free Software Foundation, Inc.,
-// * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-// */
-
-// import * as propHelpers from '../../../client/helpers/props';
-// import {escapeProps, generateProps} from '../../helpers/props';
-// import {getIntFromQueryParams, parseQuery} from '../../helpers/utils';
-// import Layout from '../../../client/containers/layout';
-// import React from 'react';
-// import ReactDOMServer from 'react-dom/server';
-// import express from 'express';
-// import {getNextEnabledAndResultsArray} from '../../../common/helpers/utils';
-// import {getOrderedAdminLogs} from '../../helpers/adminLogs';
-// import target from '../../templates/target';
-// import RelationshipTypesPage from '../../../client/components/pages/relationshipTypes';
-
-
-// const router = express.Router();
-
-// router.get('/', async (req, res, next) => {
-// const {orm} = req.app.locals;
-// const query = parseQuery(req.url);
-// const size = getIntFromQueryParams(query, 'size', 20);
-// const from = getIntFromQueryParams(query, 'from');
-
-// function render(results, nextEnabled) {
-// const props = generateProps(req, res, {
-// from,
-// nextEnabled,
-// results,
-// size
-// });
-
-// const markup = ReactDOMServer.renderToString(
-//
-//
-//
-// );
-
-// res.send(target({
-// markup,
-// props: escapeProps(props),
-// script: '/js/relationshipTypes.js',
-// title: 'Relationship Types'
-// }));
-// }
-
-// try {
-// // fetch 1 more relationship type than required to check nextEnabled
-// const orderedRelationshipTypes = await getOrderedRelationshipTypes(from, size + 1, orm);
-// const {newResultsArray, nextEnabled} = getNextEnabledAndResultsArray(orderedRelationshipTypes, size);
-// return render(newResultsArray, nextEnabled);
-// }
-// catch (err) {
-// return next(err);
-// }
-// });
-
-
-// // eslint-disable-next-line consistent-return
-// router.get('/admin-logs', async (req, res, next) => {
-// const {orm} = req.app.locals;
-// const query = parseQuery(req.url);
-// const size = getIntFromQueryParams(query, 'size', 20);
-// const from = getIntFromQueryParams(query, 'from');
-
-// try {
-// const orderedLogs = await getOrderedAdminLogs(from, size, orm);
-// res.json(orderedLogs);
-// }
-// catch (err) {
-// return next(err);
-// }
-// });
-
-// export default router;
diff --git a/webpack.client.js b/webpack.client.js
index 3a19173e05..8cef258b61 100644
--- a/webpack.client.js
+++ b/webpack.client.js
@@ -30,6 +30,7 @@ const clientConfig = {
externalService: ['./controllers/externalService.js'],
index: ['./controllers/index.js'],
registrationDetails: ['./controllers/registrationDetails.js'],
+ relationshipTypes: ['./controllers/relationshipTypes.tsx'],
revision: ['./controllers/revision.js'],
revisions: ['./controllers/revisions.js'],
search: ['./controllers/search.js'],
From 1c49e91b565683c12067679facd34cdccbe00244 Mon Sep 17 00:00:00 2001
From: the-good-boy
Date: Mon, 31 Jul 2023 20:36:07 +0530
Subject: [PATCH 03/24] Privilege Dropdown improvements
---
src/client/containers/layout.js | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/client/containers/layout.js b/src/client/containers/layout.js
index 58386ca9d0..24da9048f7 100644
--- a/src/client/containers/layout.js
+++ b/src/client/containers/layout.js
@@ -23,7 +23,7 @@
import * as bootstrap from 'react-bootstrap';
import {
- faChartLine, faGripVertical, faLink, faListUl, faPlus, faQuestionCircle,
+ faChartLine, faGripVertical, faLink, faListUl, faNewspaper, faPlus, faQuestionCircle,
faSearch, faShieldHalved, faSignInAlt, faSignOutAlt, faTrophy, faUserCircle, faUserGear
} from '@fortawesome/free-solid-svg-icons';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
@@ -149,6 +149,17 @@ class Layout extends React.Component {
Admin Panel
+
+
+ Admin Logs
+
+
+
+ Relationship Type Editor
+
+
+ Relationship Types
+
Date: Mon, 31 Jul 2023 20:37:48 +0530
Subject: [PATCH 04/24] feat(RelationshipTypeEditor): Add Attribute Types and
other improvements
---
.../forms/type-editor/relationship-type.tsx | 100 ++++++++++++++++--
.../forms/type-editor/typeUtils.tsx | 16 ++-
src/server/helpers/middleware.ts | 10 ++
.../routes/type-editor/relationship-type.tsx | 49 ++++++++-
4 files changed, 159 insertions(+), 16 deletions(-)
diff --git a/src/client/components/forms/type-editor/relationship-type.tsx b/src/client/components/forms/type-editor/relationship-type.tsx
index 5897168688..ec131ca8ca 100644
--- a/src/client/components/forms/type-editor/relationship-type.tsx
+++ b/src/client/components/forms/type-editor/relationship-type.tsx
@@ -15,15 +15,17 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
-import {Button, Card, Col, Form, Modal, Row} from 'react-bootstrap';
+import {Alert, Button, Card, Col, Form, Modal, Row} from 'react-bootstrap';
import React, {ChangeEvent, FormEvent, useCallback, useState} from 'react';
import {RelationshipTypeDataT, RelationshipTypeEditorPropsT, defaultRelationshipTypeData, entityTypeOptions, renderSelectedParent} from './typeUtils';
import {faPencilAlt, faPlus, faTimes} from '@fortawesome/free-solid-svg-icons';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import ReactSelect from 'react-select';
+import classNames from 'classnames';
+import request from 'superagent';
-function RelationshipTypeEditor({relationshipTypeData, parentTypes}: RelationshipTypeEditorPropsT) {
+function RelationshipTypeEditor({relationshipTypeData, parentTypes, attributeTypes}: RelationshipTypeEditorPropsT) {
const [formData, setFormData] = useState(relationshipTypeData);
// State for the ParentType modal
@@ -31,6 +33,19 @@ function RelationshipTypeEditor({relationshipTypeData, parentTypes}: Relationshi
const [selectedParentType, setSelectedParentType] = useState(formData.parentId);
const [childOrder, setChildOrder] = useState(formData.childOrder);
+ const [showError, setShowError] = useState(false);
+
+ const handleAttributeTypesChange = useCallback(
+ (selectedOptions) => {
+ const selectedHouseTypeIds = selectedOptions.map((option) => option.id);
+ setFormData((prevFormData) => ({
+ ...prevFormData,
+ attributeTypes: selectedHouseTypeIds
+ }));
+ },
+ [formData.attributeTypes]
+ );
+
// Callback function for opening the modal
const handleAddParent = useCallback(() => {
setShowModal(true);
@@ -59,7 +74,7 @@ function RelationshipTypeEditor({relationshipTypeData, parentTypes}: Relationshi
setChildOrder(isNaN(value) ? 0 : value);
}, [formData, childOrder]);
- // Function to handle parent removal using useCallback
+ // Function to handle parent removal
const handleRemoveParent = useCallback(() => {
setFormData((prevFormData) => ({
...prevFormData,
@@ -76,10 +91,10 @@ function RelationshipTypeEditor({relationshipTypeData, parentTypes}: Relationshi
// Function to handle parent type and child order edit submission
const handleModalSubmit = useCallback(() => {
if (selectedParentType !== null) {
- setFormData({
- ...formData,
+ setFormData((prevFormData) => ({
+ ...prevFormData,
childOrder, parentId: selectedParentType
- });
+ }));
setShowModal(false);
}
}, [formData, childOrder, selectedParentType]);
@@ -106,6 +121,9 @@ function RelationshipTypeEditor({relationshipTypeData, parentTypes}: Relationshi
const getParentTypeValue = useCallback(option => option.id, []);
+ const getAttributeTypeOptionValue = useCallback(option => option.id, []);
+ const getAttributeTypeOptionLabel = useCallback(option => option.name, []);
+
// Callback function to format the option label to include both forwardStatement and reverseStatement
const formatParentTypeOptionLabel = useCallback(option => (
@@ -114,9 +132,14 @@ function RelationshipTypeEditor({relationshipTypeData, parentTypes}: Relationshi
- First and foremost, search for both the author and the title of the book to avoid creating duplicates.
- If a Work and an Edition containing it exist, the questions below will help you decide whether to create a new Edition.
- Otherwise, here is a step-by-step procedure:
-
-
-
-
Find or add a new {genEntityIconHTMLElement('Author')}Author
-
On the Author page, click on 'Add Work' to create a {genEntityIconHTMLElement('Work')}Work with a relationship to the Author
-
On the Work page, click 'Add Edition' to create an {genEntityIconHTMLElement('Edition')}Edition with a relationship to the Work.
-
-
A new {genEntityIconHTMLElement('EditionGroup')}Edition Group will be created automatically, but you can select an existing one
-
Create a new {genEntityIconHTMLElement('Publisher')}Publisher if you cannot find an existing one
-
-
-
To enter another format of the same book (see explanations below), go to the Edition Group and click the 'Add Edition' button. Repeat step 4.
-
-
-
When should I create a new Edition of a Work?
-
-
When it is published in a different format (e.g. paperback and e-book)
-
When there are substantial content (textual or editorial) changes
-
Translations will both be a new Work and a new Edition for it.
-
Add a relationship between the original and the translated Works
-
New cover or changed credits/attribution on the cover
-
When there's a new ISBN
-
-
-
When should I not create a new Edition of a Work?
-
-
Minimal changes as in proofreading errors
-
Minimal changes on the cover
-
Reprints of the same Edition. You can mention “Reprint – [date]” in the annotations.
-
When the edition uses the same ISBN (with rare exceptions)
-
-
-
When should two Editions be part of the same Edition Group?
- Edition Groups exist to group together all the variations of an edition (an identifiable set of works) in a given language.
- Here are examples of Editions that should be part of the same Edition Group:
-
-
-
Different formats of the same edition (paperback, hardcover and e-book by the same publisher)
-
Revised and updated editions
-
Reprints
-
Editions with different forewords/intros
-
Co-editions (same book published in different countries by different publishers)