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

fix BB-343 : Integrated the modification of identifiers and aliases into the primary editing workflow #1043

Open
wants to merge 24 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
6988878
other(editor): Introduced an identifier editing section and alias edi…
Tarunmeena0901 Dec 18, 2023
a56a519
typo fix
Tarunmeena0901 Dec 29, 2023
f9d3e89
typo fix
Tarunmeena0901 Dec 29, 2023
77bd98f
typo fix
Tarunmeena0901 Dec 29, 2023
8748dd2
typo fix
Tarunmeena0901 Dec 30, 2023
ddc6eb3
Merge branch 'BB-343' of https://github.com/Tarunmeena0901/bookbrainz…
Tarunmeena0901 Dec 30, 2023
a107325
Update alias-editor.js
Tarunmeena0901 Jan 2, 2024
68474e5
lint error fix
Tarunmeena0901 Jan 2, 2024
0ed84f8
fixed lint error
Tarunmeena0901 Jan 2, 2024
4b02088
identifier editing section heading change
Tarunmeena0901 Jan 12, 2024
8d6ad13
other(entity-editor): made UI changes and removed unecessary imports
Tarunmeena0901 Jan 16, 2024
ba28950
fix lint error
Tarunmeena0901 Jan 16, 2024
848b312
implemented new mockups and renamed identifierEditor and aliasEditor …
Tarunmeena0901 Apr 23, 2024
b5bb1d6
Merge remote-tracking branch 'upstream/master' into BB-343
Tarunmeena0901 Apr 23, 2024
e81bc36
Merge remote-tracking branch 'upstream/master' into BB-343
Tarunmeena0901 Apr 23, 2024
77ff0ff
fix error occur due to merge
Tarunmeena0901 Apr 23, 2024
3ef5b54
minor fix
Tarunmeena0901 Apr 24, 2024
7905072
build test fix
Tarunmeena0901 Apr 24, 2024
5f759c5
merging
Tarunmeena0901 Apr 24, 2024
107ad3d
Merge branch 'BB-343' of https://github.com/Tarunmeena0901/bookbrainz…
Tarunmeena0901 Apr 24, 2024
f645aa5
minor fix
Tarunmeena0901 Apr 24, 2024
eeaf8a5
minor fix
Tarunmeena0901 Apr 24, 2024
40a4066
done some remaining renaming of for alias merge
Tarunmeena0901 Apr 24, 2024
6bc94a3
lint error fix
Tarunmeena0901 Apr 24, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -18,7 +18,7 @@

export const UPDATE_ALIAS_NAME = 'UPDATE_ALIAS_NAME';
export const UPDATE_ALIAS_SORT_NAME = 'UPDATE_ALIAS_SORT_NAME';
export const ADD_ALIAS_ROW = 'ADD_ALIAS_ROW';
export const ADD_ALIAS = 'ADD_ALIAS';
export const UPDATE_ALIAS_LANGUAGE = 'UPDATE_ALIAS_LANGUAGE';
export const UPDATE_ALIAS_PRIMARY = 'UPDATE_ALIAS_PRIMARY';
export const REMOVE_ALIAS_ROW = 'REMOVE_ALIAS_ROW';
Expand All @@ -33,6 +33,26 @@ export type Action = {
}
};

let nextAliasRowId = 0;

export function addNewAlias(
nameValue: string, sortNameValue: string, LanguageValue: number | null | undefined,
primary: boolean
): Action {
return {
payload: {
data: {
language: LanguageValue,
name: nameValue,
primary,
sortName: sortNameValue
},
rowId: `n${nextAliasRowId++}`
},
type: ADD_ALIAS
};
}

/**
* Produces an action indicating that the name for a particular alias within
* the editor should be updated with the provided value. The action is
Expand Down Expand Up @@ -113,26 +133,6 @@ export function updateAliasPrimary(rowId: number, value: boolean): Action {
};
}

let nextAliasRowId = 0;

/**
* Produces an action indicating that a row for a new alias should be added
* to the alias editor. The row is assigned an ID based on an incrementing
* variable existing on the client.
*
* @returns {Action} The resulting ADD_ALIAS_ROW action.
*/
export function addAliasRow(): Action {
/*
* Prepend 'n' here to indicate new alias, and avoid conflicts with IDs of
* existing aliases.
*/
return {
payload: `n${nextAliasRowId++}`,
type: ADD_ALIAS_ROW
};
}

/**
* Produces an action indicating that the row with the provided ID should be
* removed from the alias editor.
Expand All @@ -147,20 +147,6 @@ export function removeAliasRow(rowId: number): Action {
};
}

/**
* Produces an action indicating that the alias editor should be hidden from
* view.
*
* @see showAliasEditor
*
* @returns {Action} The resulting HIDE_ALIAS_EDITOR action.
*/
export function hideAliasEditor(): Action {
return {
type: HIDE_ALIAS_EDITOR
};
}

/**
* Produces an action indicating that the empty rows should be deleted.
*
Expand Down
Expand Up @@ -71,7 +71,7 @@ AliasEditorMerge.propTypes = {

function mapStateToProps(rootState) {
const nameSection = rootState.get('nameSection');
const aliases = rootState.get('aliasEditor');
const aliases = rootState.get('aliasSection');

/** Dynamically filter out aliases that are different
* from the attributes selected in the nameSection
Expand Down
129 changes: 129 additions & 0 deletions src/client/entity-editor/alias-section/alias-editor.tsx
@@ -0,0 +1,129 @@
/*
* Copyright (C) 2016 Ben Ockmore
*
* 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 {Button, Col, Form, Modal, Row} from 'react-bootstrap';
import {
validateAliasLanguage, validateAliasName, validateAliasSortName
} from '../validators/common';
import LanguageField from '../common/language-field';
import NameField from '../common/name-field';
import PropTypes from 'prop-types';
import React from 'react';
import SortNameField from '../common/sort-name-field';
import {connect} from 'react-redux';
import {isAliasEmpty} from '../helpers';


const onClose = (setVisibility, removeEmptyAliases) => {
setVisibility(false);
removeEmptyAliases();
};

function AliasEditor({
show,
setVisibility,
nameValue,
sortNameValue,
aliasLanguage,
languageOptions,
languageValue,
primaryCheck,
onLanguageChange,
onNameChange,
onSortNameChange,
onPrimaryClick,
removeEmptyAliases
}) {
const handleModalCLose = React.useCallback(() => {
onClose(setVisibility, removeEmptyAliases);
}, []);
return (
<Modal show={show} size="lg" onHide={handleModalCLose}>
<Modal.Header>
<Modal.Title>
Identifier Editor
</Modal.Title>
</Modal.Header>

<Modal.Body>
<Row>
<Col lg={3}>
<NameField
autoFocus
defaultValue={nameValue}
empty={isAliasEmpty(nameValue, sortNameValue, aliasLanguage)}
error={!validateAliasName(nameValue)}
onChange={onNameChange}
/>
</Col>
<Col lg={5}>
<SortNameField
defaultValue={sortNameValue}
empty={isAliasEmpty(nameValue, sortNameValue, aliasLanguage)}
error={!validateAliasSortName(sortNameValue)}
storedNameValue={nameValue}
onChange={onSortNameChange}
/>
</Col>
<Col lg={4}>
<LanguageField
empty={isAliasEmpty(nameValue, sortNameValue, aliasLanguage)}
error={!validateAliasLanguage(aliasLanguage)}
instanceId="language"
options={languageOptions}
value={languageValue}
onChange={onLanguageChange}
/>
</Col>
</Row>
<Row className="justify-content-center">
<div className="d-flex align-items-center">
<Form.Check
defaultChecked={primaryCheck}
label="Primary"
type="checkbox"
onChange={onPrimaryClick}
/>
</div>
</Row>
</Modal.Body>
<Modal.Footer>
<Button variant="primary" onClick={handleModalCLose}>Close</Button>
</Modal.Footer>
</Modal>
);
}
AliasEditor.displayName = 'AliasEditor';
AliasEditor.propTypes = {
aliasLanguage: PropTypes.number.isRequired,
languageOptions: PropTypes.array.isRequired,
languageValue: PropTypes.array.isRequired,
nameValue: PropTypes.string.isRequired,
onLanguageChange: PropTypes.func.isRequired,
onNameChange: PropTypes.func.isRequired,
onPrimaryClick: PropTypes.func.isRequired,
onSortNameChange: PropTypes.func.isRequired,
primaryCheck: PropTypes.bool.isRequired,
removeEmptyAliases: PropTypes.func.isRequired,
setVisibility: PropTypes.func.isRequired,
show: PropTypes.bool.isRequired,
sortNameValue: PropTypes.string.isRequired
};


export default connect(null, null)(AliasEditor);
136 changes: 136 additions & 0 deletions src/client/entity-editor/alias-section/alias-fields.tsx
@@ -0,0 +1,136 @@
/*
* Copyright (C) 2016 Ben Ockmore
*
* 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 {Button, Col, Container, Form, Row} from 'react-bootstrap';
import {
validateAliasLanguage, validateAliasName, validateAliasSortName
} from '../validators/common';
import {FontAwesomeIcon} from '@fortawesome/react-fontawesome';
import LanguageField from '../common/language-field';
import NameField from '../common/name-field';
import PropTypes from 'prop-types';
import React from 'react';
import SortNameField from '../common/sort-name-field';
import {addNewAlias} from './actions';
import {connect} from 'react-redux';
import {faPlus} from '@fortawesome/free-solid-svg-icons';
import {isAliasEmpty} from '../helpers';


type LanguageObj = {
frequency: number,
label: string,
value: number
};

function AliasFields({
languageOptions,
onAddNewAlias
}) {
const [nameValue, setNameValue] = React.useState<string>('');
const [sortNameValue, setSortNameValue] = React.useState<string>('');
const [languageValue, setLanguageValue] = React.useState<LanguageObj>(null);
const [primaryCheck, setPrimaryCheckbox] = React.useState<boolean>(false);

const handleNameChange = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
setNameValue(event.target.value);
}, []);
const handleSortNameChange = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
setSortNameValue(event.target.value);
}, []);
const handlePrimaryCheckboxChange = React.useCallback((event: React.ChangeEvent<HTMLInputElement>) => {
setPrimaryCheckbox(event.target.checked);
}, []);

const handleAddAliasButtonClick = React.useCallback(() => {
onAddNewAlias(nameValue, sortNameValue, languageValue?.value, primaryCheck);
}, [nameValue, sortNameValue, languageValue?.value, primaryCheck]);

return (
<Container>
<Row className="justify-content-center mt-3">
<Col lg={{offset: 1, span: 2}}>
<NameField
autoFocus
defaultValue={nameValue}
empty={isAliasEmpty(nameValue, sortNameValue, languageValue?.value)}
error={!validateAliasName(nameValue)}
onChange={handleNameChange}
/>
</Col>
<Col lg={3}>
<SortNameField
defaultValue={sortNameValue}
empty={isAliasEmpty(nameValue, sortNameValue, languageValue?.value)}
error={!validateAliasSortName(sortNameValue)}
storedNameValue={nameValue}
onChange={handleSortNameChange}
/>
</Col>
<Col lg={3}>
<LanguageField
empty={isAliasEmpty(nameValue, sortNameValue, languageValue?.value)}
error={!validateAliasLanguage(languageValue?.value)}
instanceId="language"
options={languageOptions}
value={languageOptions.filter((el) => el.value === languageValue).label}
onChange={setLanguageValue}
/>
</Col>
<Col lg={2}>
<div className="mt-4 d-flex flex-column justify-content-between">
<div>
<Form.Check
className="font-weight-bold"
defaultChecked={primaryCheck}
label="Primary"
style={{zoom: 0.8}}
type="checkbox"
onChange={handlePrimaryCheckboxChange}
/>
</div>
<div>
<Button
size="sm"
variant="success"
onClick={handleAddAliasButtonClick}
>
<FontAwesomeIcon icon={faPlus}/>
<span>&nbsp;Add</span>
</Button>
</div>
</div>
</Col>
</Row>
</Container>
);
}
AliasFields.displayName = 'AliasEditor.AliasRow';
AliasFields.propTypes = {
languageOptions: PropTypes.array.isRequired,
onAddNewAlias: PropTypes.func.isRequired
};

function mapDispatchToProps(dispatch) {
return {
onAddNewAlias: (nameValue, sortNameValue, languageValue, primary) =>
dispatch(addNewAlias(nameValue, sortNameValue, languageValue, primary))
};
}

export default connect(null, mapDispatchToProps)(AliasFields);
Expand Up @@ -75,7 +75,7 @@ function mapDispatchToProps(dispatch, {index}) {
}

function mapStateToProps(rootState, {index}) {
const state = rootState.get('aliasEditor');
const state = rootState.get('aliasSection');
return {
languageValue: state.getIn([index, 'language']),
nameValue: state.getIn([index, 'name']),
Expand Down