Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat(UF) : Add frontend for unified form #850

Merged
merged 116 commits into from
Aug 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
116 commits
Select commit Hold shift + click to select a range
124c42a
feat(uf) :added basic page for unified form
tr1ten Jun 3, 2022
3339cdf
feat(uf): added submission section
tr1ten Jun 3, 2022
43542db
feat(uf): added identifier editor
tr1ten Jun 4, 2022
f390056
feat(uf): basic content tab done
tr1ten Jun 5, 2022
2dc4dcb
feat(uf): added navbar to switch tabs
tr1ten Jun 5, 2022
3338f0a
feat(uf): add details tab
tr1ten Jun 5, 2022
65c57b3
feat(uf): transform state to require format
tr1ten Jun 5, 2022
5efeef9
fix(uf): minor fix languagefield
tr1ten Jun 6, 2022
4cb0e43
feat(uf): use search-create for entity inputs
tr1ten Jun 7, 2022
bca94f5
refactor(uf): improve code readability
tr1ten Jun 9, 2022
fd3bd19
feat(uf): added very basic entity creation modal
tr1ten Jun 12, 2022
d5fa8fc
feat(uf): add all sections for work creation
tr1ten Jun 13, 2022
f80e527
feat(uf): add support for creating publishers
tr1ten Jun 13, 2022
c861681
fix(uf): fix minor issues
tr1ten Jun 14, 2022
8faca59
feat(uf): modal support for edition-group
tr1ten Jun 14, 2022
2dd85d2
feat(uf): correctly transform post data
tr1ten Jun 15, 2022
1045515
fix(uf): minor fixes
tr1ten Jun 15, 2022
6397039
feat(uf): auto fill sort name and language field
tr1ten Jun 16, 2022
12a8381
fix(uf): dropdown not going outside of accordion
tr1ten Jun 18, 2022
4ba5bb1
refactor: be consistent with variable naming
tr1ten Jun 18, 2022
cb8773e
feat(uf): left align entity section in modal
tr1ten Jun 18, 2022
8175eb1
Merge branch 'new-creation-form' into uf-frontend
tr1ten Jun 23, 2022
b8eab3e
feat(uf): add multi-publisher support in uf
tr1ten Jun 23, 2022
355475c
feat(uf): add author credits ui
tr1ten Jun 24, 2022
006f833
feat(uf): add author create modal
tr1ten Jun 24, 2022
b713616
feat(uf): create new author using AC editor
tr1ten Jun 24, 2022
fa22e69
fix(uf): fix validation issue with eg
tr1ten Jun 24, 2022
cff0f15
test(uf): only allow valid type for publishers
tr1ten Jun 25, 2022
aedf207
feat(uf): remove created edition-group on clear
tr1ten Jun 25, 2022
fb02947
fix onEditionGroupChange handler
tr1ten Jun 25, 2022
bb25e22
feat(uf): allow removing created publisher
tr1ten Jun 25, 2022
6b4667b
feat(uf): properly clear newly created author
tr1ten Jun 26, 2022
6530761
fix(uf): clearing issue on edition-group
tr1ten Jun 26, 2022
b81590e
feat(uf): clear all new publishers at once
tr1ten Jun 26, 2022
214da22
feat(uf): merge new publisher with old publishers
tr1ten Jun 26, 2022
bd8330f
minor improvements
tr1ten Jun 27, 2022
53c8bce
minor test fixes
tr1ten Jun 27, 2022
f086c0c
fix(uf): change book icon for uf
tr1ten Jun 27, 2022
ef5a35f
Merge remote-tracking branch 'origin/new-creation-form' into pr/850
MonkeyDo Jun 27, 2022
0368393
feat(uf): move submit section to tab section
tr1ten Jun 30, 2022
3506af4
render alias button inside row component
tr1ten Jun 30, 2022
6b913f9
feat(uf): exclude existing entities from summary
tr1ten Jul 1, 2022
2ce60ee
fix(uf): left align AC on edition group
tr1ten Jul 1, 2022
0483346
feat(uf): add alias editor to modal
tr1ten Jul 1, 2022
de7b598
feat(uf):add serparate identifier section in modal
tr1ten Jul 1, 2022
e08845d
feat(uf): move duplicate suggestions to end
tr1ten Jul 2, 2022
d757145
fix(uf): only send isUf prop when necessary
tr1ten Jul 2, 2022
d6ae32f
feat(uf): disable submit tab on invalid form
tr1ten Jul 2, 2022
96dfc3f
fix(uf): menu options get clipped by parent
tr1ten Jul 2, 2022
63a8340
feat(uf): move duplicate alert at bottom
tr1ten Jul 2, 2022
b4db5a2
feat(uf): remove empty fields in modal
tr1ten Jul 3, 2022
ddcdb21
feat(uf): improve detail-tab accordion
tr1ten Jul 3, 2022
d49246c
fix datefield overflow issue on details tab
tr1ten Jul 3, 2022
09e1c45
feat(uf): add spinner to submit button
tr1ten Jul 3, 2022
eb3b71d
refactor(uf): get rid of redundant code
tr1ten Jul 3, 2022
1a135ba
refactor(uf):improve typescipt on modal components
tr1ten Jul 3, 2022
f1eb61d
refactor(uf): improve typescript for all tabs
tr1ten Jul 3, 2022
9e77213
add js-doc for all uf components
tr1ten Jul 3, 2022
649d311
feat(uf): check for duplicates on modal open
tr1ten Jul 3, 2022
8901f92
allow creation of entity with existing name
tr1ten Jul 5, 2022
de66e5d
fix minor issue with AC and modal
tr1ten Jul 5, 2022
9d67e5c
disable search for less options in edition section
tr1ten Jul 5, 2022
046df6b
feat(uf): copy authors from AC to new work
tr1ten Jul 5, 2022
64f2b5b
remove accordion from details tab
tr1ten Jul 5, 2022
c4f4447
improve accordion on modal
tr1ten Jul 5, 2022
8515440
feat(uf): add wrapper for bootstrap accordion
tr1ten Jul 6, 2022
e77934c
feat(uf): add relationships on existing works
tr1ten Jul 8, 2022
8df9e4a
fix minor issues with adding relationships
tr1ten Jul 8, 2022
d8e410b
fix: don't reset AC state on edition dump
tr1ten Jul 8, 2022
0044c33
Merge branch 'new-creation-form' into uf-frontend
tr1ten Jul 11, 2022
a818536
fix: remove revision if no changes made to entity
tr1ten Jul 12, 2022
ee3d8c0
feat(uf): add validations to modal sections
tr1ten Jul 12, 2022
79dfe87
disable validations on entity creation modal
tr1ten Jul 13, 2022
20d1295
feat(uf): major improvements in form performance
tr1ten Jul 13, 2022
0904eff
feat(uf): performance improvements in modal
tr1ten Jul 13, 2022
848aec9
feat: improve modal rendering time
tr1ten Jul 14, 2022
5113d28
fix: minor issues
tr1ten Jul 15, 2022
af2d5a0
fix: authorSection autoselect and preview issue
tr1ten Jul 20, 2022
8b84a03
test: add test for single-accoridion, isbn-field.
tr1ten Jul 20, 2022
d2a7885
test: add tests content tab
tr1ten Jul 21, 2022
066bfd1
test: add test for common components
tr1ten Jul 21, 2022
240935d
test: add test for submit tab
tr1ten Jul 21, 2022
f9a6ae7
feat: add validation to tabs
tr1ten Jul 22, 2022
0c114d3
feat: add identifier count
tr1ten Jul 23, 2022
355d01e
test: add test for tab validators
tr1ten Jul 24, 2022
ef6dc47
feat(uf): show warning on duplicate new entities.
tr1ten Jul 24, 2022
f892bca
feat: Show dialogue box in summary section
tr1ten Jul 26, 2022
e9a5bc5
feat: add ability to copy work.
tr1ten Jul 26, 2022
6ba7956
fix: typos in uf components
tr1ten Jul 27, 2022
ef978e0
feat: series entity support in entity-create-modal
tr1ten Jul 29, 2022
dc6fa03
fix: adding entity to series
tr1ten Jul 29, 2022
55fb989
improve series section UI on modal.
tr1ten Jul 30, 2022
0a6d6cf
feat: add new entities in series search select.
tr1ten Jul 30, 2022
5433ef2
feat: copy language from namesection.
tr1ten Jul 30, 2022
cf46e11
test: validation-label & name-field component
tr1ten Jul 31, 2022
26148c1
refactor: clean code and add some comments
tr1ten Aug 3, 2022
860bcd0
chore: Remove postinstall NPM step
MonkeyDo Aug 4, 2022
c697610
fix: properly map relationship ids
tr1ten Aug 5, 2022
4209004
feat(uf): add items to exisiting series entity
tr1ten Aug 6, 2022
12b6717
feat: preserve ordering type for existing series
tr1ten Aug 7, 2022
88ef807
feat: remove series items when entity switch
tr1ten Aug 7, 2022
90322bb
feat: auto add other isbn checkbox
tr1ten Aug 8, 2022
8bcede1
test: add test for new-date-field component
tr1ten Aug 8, 2022
726f212
refactor: change navbar icon
tr1ten Aug 10, 2022
a683540
refactor: rename isUf to isUnifiedForm
tr1ten Aug 10, 2022
01de8f4
minor improvements in author-credits field
tr1ten Aug 10, 2022
91f100b
show info icon beside copy author checkbox.
tr1ten Aug 10, 2022
822b88d
refactor: rename actions and reducer variables
tr1ten Aug 10, 2022
8238bb3
refactor: improve code readability
tr1ten Aug 10, 2022
72b9076
Merge branch 'new-creation-form' into uf-frontend
tr1ten Aug 11, 2022
af56c9f
minor improvements in code readability
tr1ten Aug 11, 2022
3884d94
feat: improve isbn field, preview new isbn
tr1ten Aug 13, 2022
ac9fccb
refactor: reduce number of props passed to child
tr1ten Aug 13, 2022
597845d
show badge for identifiers count
tr1ten Aug 13, 2022
125eed7
improve summary section for series entity
tr1ten Aug 13, 2022
790c5ea
feat: add series editor on content tab itself.
tr1ten Aug 17, 2022
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: 17 additions & 0 deletions enzyme.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/* eslint-disable node/no-process-env */
/* Taken from: ListenBrainz */
import * as Enzyme from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';


Enzyme.configure({adapter: new Adapter()});

// In Node > v15 unhandled promise rejections will terminate the process
if (!process.env.LISTENING_TO_UNHANDLED_REJECTION) {
process.on('unhandledRejection', (err) => {
// eslint-disable-next-line no-console
console.log('Unhandled promise rejection:', err);
});
// Avoid memory leak by adding too many listeners
process.env.LISTENING_TO_UNHANDLED_REJECTION = 'true';
}
14 changes: 10 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@
"private": true,
"scripts": {
"clean": "./scripts/clean.sh",
"prepublishOnly": "npm run clean",
"postinstall": "npm run prepublishOnly",
"prepare": "npm run clean",
"build-server-js": "babel src --out-dir lib --source-maps --ignore src/api --extensions .js,.jsx,.ts,.tsx",
"build-api-js": "babel src --out-dir lib --ignore 'src/server','src/client' --extensions .js,.jsx,.ts,.tsx",
"build-scss": "./scripts/build-scss.sh",
Expand All @@ -18,14 +17,14 @@
"debug-watch-server": "cross-env DEBUG=bbsite NODE_ENV=development nodemon src/server/app.js --ext js,jsx,ts,tsx --watch src/server --exec 'babel-node --extensions .js,.jsx,.ts,.tsx'",
"lint": "eslint .",
"lint-errors": "eslint --quiet .",
"test": "npm run lint-errors && cross-env NODE_ENV=test mocha",
"test": "npm run lint-errors && cross-env NODE_ENV=test mocha -r jsdom-global/register",
"test-cov": "npx nyc --reporter=text npm run test",
"test-ci": "NODE_ENV=test mocha --reporter json --reporter-option output=test-results.json",
"jsdoc": "npx jsdoc -r src",
"dupreport": "npx jsinspect src/ || true"
},
"engines": {
"node": ">= 16.0.0"
"node": ">= 16.16.0"
},
"browserslist": "> 0.25%, not dead",
"dependencies": {
Expand Down Expand Up @@ -58,6 +57,7 @@
"lodash": "^4.17.21",
"log": "^6.0.0",
"log-node": "^8.0.3",
"mocha-chai-jest-snapshot": "^1.1.4",
"morgan": "^1.10.0",
"nodemailer": "^6.5.0",
"passport": "^0.5.2",
Expand Down Expand Up @@ -116,6 +116,8 @@
"clean-webpack-plugin": "^4.0.0",
"compression-webpack-plugin": "^9.2.0",
"css-loader": "^6.7.1",
"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.6",
"eslint": "^7.30.0",
"eslint-plugin-babel": "^5.3.1",
"eslint-plugin-import": "^2.22.1",
Expand All @@ -124,13 +126,17 @@
"eslint-webpack-plugin": "^2.4.1",
"faker": "^4.1.0",
"file-loader": "^6.2.0",
"jsdom": "20.0.0",
"jsdom-global": "3.0.2",
"mini-css-extract-plugin": "^2.5.3",
"mocha": "^9.1.3",
"nodemon": "^2.0.2",
"redux-mock-store": "^1.5.4",
"resolve-url-loader": "^5.0.0",
"rewire": "^5.0.0",
"sass": "^1.49.0",
"sass-loader": "^12.4.0",
"sinon": "^14.0.0",
"typescript": "^4.0.5",
"uuid": "^8.3.2",
"webpack": "^5.69.1",
Expand Down
20 changes: 11 additions & 9 deletions src/client/components/author-credit-display.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,17 @@ import {map as _map} from 'lodash';


function AuthorCreditDisplay({names}) {
const authorBBID = name.authorBBID ?? name.author?.id;
const nameElements = _map(names, (name) => (
<span key={`author-credit-${authorBBID}`}>
<a href={`/author/${authorBBID}`}>
{name.name}
</a>
{name.joinPhrase}
</span>
));
const nameElements = _map(names, (name) => {
const authorBBID = name.authorBBID ?? name.author?.id;
return (
<span key={`author-credit-${authorBBID}`}>
<a href={`/author/${authorBBID}`}>
{name.name}
</a>
{name.joinPhrase}
</span>
);
});

return (
<span>
Expand Down
6 changes: 5 additions & 1 deletion src/client/containers/layout.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ class Layout extends React.Component {
onSelect={this.handleDropdownClick}
onToggle={this.handleDropdownToggle}
>
<NavDropdown.Item href="/create">
{genEntityIconHTMLElement('Book')}
Book
</NavDropdown.Item>
<NavDropdown.Divider/>
<NavDropdown.Item href="/work/create">
{genEntityIconHTMLElement('Work')}
Work
Expand All @@ -154,7 +159,6 @@ class Layout extends React.Component {
{genEntityIconHTMLElement('Series')}
Series
</NavDropdown.Item>
<NavDropdown.Divider/>
<NavDropdown.Item href="/author/create">
{genEntityIconHTMLElement('Author')}
Author
Expand Down
58 changes: 6 additions & 52 deletions src/client/entity-editor/alias-editor/alias-editor.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,14 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/

import {Button, Col, Modal, OverlayTrigger, Row, Tooltip} from 'react-bootstrap';
import {addAliasRow, hideAliasEditor, removeEmptyAliases} from './actions';
import {faPlus, faQuestionCircle} from '@fortawesome/free-solid-svg-icons';

import AliasRow from './alias-row';
import {Button, Modal, OverlayTrigger, Tooltip} from 'react-bootstrap';
import {hideAliasEditor, removeEmptyAliases} from './actions';
import AliasModalBody from './alias-modal-body';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import PropTypes from 'prop-types';
import React from 'react';
import classNames from 'classnames';
import {connect} from 'react-redux';
import {faQuestionCircle} from '@fortawesome/free-solid-svg-icons';


/**
Expand All @@ -38,30 +36,17 @@ import {connect} from 'react-redux';
* editor.
* @param {Array} props.languageOptions - The list of possible languages for an
* alias.
* @param {Function} props.onAddAlias - A function to be called when the button
* to add an alias is clicked.
* @param {Function} props.onClose - A function to be called when the button to
* close the editor is clicked.
* @param {boolean} props.show - Whether or not the editor modal should be
* visible.
* @returns {ReactElement} React element containing the rendered AliasEditor.
*/
const AliasEditor = ({
aliases,
languageOptions,
onAddAlias,
onClose,
show
}) => {
const languageOptionsForDisplay = languageOptions.map((language) => ({
frequency: language.frequency,
label: language.name,
value: language.id
}));

const noAliasesTextClass =
classNames('text-center', {'d-none': aliases.size});

const helpText = `Variant names for an entity such as alternate spelling, different script, stylistic representation, acronyms, etc.
Refer to the help page for more details and examples.`;
const helpIconElement = (
Expand All @@ -86,29 +71,7 @@ const AliasEditor = ({
</Modal.Header>

<Modal.Body>
<div className={noAliasesTextClass}>
<p className="text-muted">This entity has no aliases</p>
</div>
<div>
{
aliases.map((alias, rowId) => (
<AliasRow
index={rowId}
// eslint-disable-next-line react/no-array-index-key
key={rowId}
languageOptions={languageOptionsForDisplay}
/>
)).toArray()
}
</div>
<Row>
<Col className="text-right" lg={{offset: 9, span: 3}}>
<Button variant="success" onClick={onAddAlias}>
<FontAwesomeIcon icon={faPlus}/>
<span>&nbsp;Add alias</span>
</Button>
</Col>
</Row>
<AliasModalBody languageOptions={languageOptions}/>
</Modal.Body>

<Modal.Footer>
Expand All @@ -119,9 +82,7 @@ const AliasEditor = ({
};
AliasEditor.displayName = 'AliasEditor';
AliasEditor.propTypes = {
aliases: PropTypes.object.isRequired,
languageOptions: PropTypes.array.isRequired,
onAddAlias: PropTypes.func.isRequired,
onClose: PropTypes.func.isRequired,
show: PropTypes.bool
};
Expand All @@ -131,18 +92,11 @@ AliasEditor.defaultProps = {

function mapDispatchToProps(dispatch) {
return {
onAddAlias: () => dispatch(addAliasRow()),
onClose: () => {
dispatch(hideAliasEditor());
dispatch(removeEmptyAliases());
}
};
}

function mapStateToProps(rootState) {
return {
aliases: rootState.get('aliasEditor')
};
}

export default connect(mapStateToProps, mapDispatchToProps)(AliasEditor);
export default connect(null, mapDispatchToProps)(AliasEditor);
MonkeyDo marked this conversation as resolved.
Show resolved Hide resolved
76 changes: 76 additions & 0 deletions src/client/entity-editor/alias-editor/alias-modal-body.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
import {Button, Col, Row} from 'react-bootstrap';
import AliasRow from './alias-row';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import Immutable from 'immutable';
import React from 'react';
import {addAliasRow} from './actions';
import classNames from 'classnames';
import {connect} from 'react-redux';
import {faPlus} from '@fortawesome/free-solid-svg-icons';


type AliasModalBodyStateProps = {
aliases: Immutable.List<string>;
};
type AliasModalBodyDispatchProps = {
onAddAlias: () => void;
};

type AliasModalBodyOwnProps = {
languageOptions?:any[],
};
type AliasModalBodyProps = AliasModalBodyStateProps & AliasModalBodyDispatchProps & AliasModalBodyOwnProps;

export const AliasModalBody = ({aliases, onAddAlias, languageOptions}:AliasModalBodyProps) => {
const noAliasesTextClass =
classNames('text-center', {'d-none': aliases.size});
const languageOptionsForDisplay = languageOptions.map((language) => ({
frequency: language.frequency,
label: language.name,
value: language.id
}));
return (
<>
<div className={noAliasesTextClass}>
<p className="text-muted">This entity has no aliases</p>
</div>
<div>
{
aliases.toArray().map((_, rowId) => (
<AliasRow
index={rowId}
// eslint-disable-next-line react/no-array-index-key
key={`alias-row-${rowId}`}
languageOptions={languageOptionsForDisplay}
/>
))
}
</div>
<Row>
<Col className="text-right" lg={{offset: 9, span: 3}}>
<Button variant="success" onClick={onAddAlias}>
<FontAwesomeIcon icon={faPlus}/>
<span>&nbsp;Add alias</span>
</Button>
</Col>
</Row>
</>);
};

AliasModalBody.defaultProps = {
languageOptions: []
};

function mapDispatchToProps(dispatch) {
return {
onAddAlias: () => dispatch(addAliasRow())
};
}

function mapStateToProps(rootState) {
return {
aliases: rootState.get('aliasEditor')
};
}

export default connect<AliasModalBodyStateProps, AliasModalBodyDispatchProps>(mapStateToProps, mapDispatchToProps)(AliasModalBody);
25 changes: 16 additions & 9 deletions src/client/entity-editor/annotation-section/annotation-section.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ import {faQuestionCircle} from '@fortawesome/free-solid-svg-icons';
* AnnotationSection.
*/
function AnnotationSection({
annotation,
onAnnotationChange
annotation: immutableAnnotation,
onAnnotationChange,
isUnifiedForm
}) {
const annotation = convertMapToObject(immutableAnnotation);
const annotationLabel = (
<span>
Annotation
Expand All @@ -54,14 +56,16 @@ function AnnotationSection({
Additional freeform data that does not fit in the above form
</Tooltip>
);

const lgCol = {offset: 3, span: 6};
if (isUnifiedForm) {
lgCol.offset = 0;
}
const heading = <h2> Annotation</h2>;
return (
<div>
<h2>
Annotation
</h2>
{!isUnifiedForm && heading}
<Row>
<Col lg={{offset: 3, span: 6}}>
<Col lg={lgCol}>
<Form.Group>
<Form.Label>
{annotationLabel}
Expand Down Expand Up @@ -95,12 +99,15 @@ function AnnotationSection({
AnnotationSection.displayName = 'AnnotationSection';
AnnotationSection.propTypes = {
annotation: PropTypes.object.isRequired,
isUnifiedForm: PropTypes.bool,
onAnnotationChange: PropTypes.func.isRequired
};

AnnotationSection.defaultProps = {
isUnifiedForm: false
};
function mapStateToProps(rootState) {
return {
annotation: convertMapToObject(rootState.get('annotationSection'))
annotation: rootState.get('annotationSection')
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ const AuthorCreditEditor = ({
authorCredit,
onAddAuthorCreditRow,
onClose,
showEditor
showEditor,
...rest
}) => (
<Modal show={showEditor} size="lg" onHide={onClose} >
<Modal.Header>
Expand Down Expand Up @@ -79,6 +80,7 @@ const AuthorCreditEditor = ({
index={rowId}
// eslint-disable-next-line react/no-array-index-key
key={rowId}
{...rest}
/>
))
}
Expand Down
Loading