Skip to content

Commit

Permalink
close #594
Browse files Browse the repository at this point in the history
  • Loading branch information
MortenHofft committed Oct 29, 2024
1 parent e6d9e68 commit 26083fe
Show file tree
Hide file tree
Showing 5 changed files with 294 additions and 4 deletions.
4 changes: 2 additions & 2 deletions src/components/Collection/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ import withContext from '../hoc/withContext';
// Components
import { ItemMenu, ItemHeader, CreationFeedback } from '../common';
import CollectionDetails from './Details';
import { CommentList, ContactPersonList, IdentifierList, TagList, MachineTagList, MasterSource } from '../common/subtypes';
import { CommentList, ContactPersonList, GrSciCollIdentifierList, TagList, MachineTagList, MasterSource } from '../common/subtypes';
import DescriptorGroups from './subtypes/DescriptorGroups';
import Exception404 from '../exception/404';
import Actions from './collection.actions';
Expand Down Expand Up @@ -411,7 +411,7 @@ class Collection extends Component {
} />

<Route path={`${match.path}/identifier`} render={() =>
<IdentifierList
<GrSciCollIdentifierList
identifiers={collection.identifiers}
permissions={{ roles: [roles.GRSCICOLL_ADMIN] }}
createIdentifier={data => createIdentifier(key, data)}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Institution/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import PageWrapper from '../hoc/PageWrapper';
// Components
import { CreationFeedback, ItemHeader, ItemMenu } from '../common';
import InstitutionDetails from './Details';
import { CommentList, ContactPersonList, IdentifierList, TagList, MachineTagList, MasterSource } from '../common/subtypes';
import { CommentList, ContactPersonList, GrSciCollIdentifierList, TagList, MachineTagList, MasterSource } from '../common/subtypes';
import Exception404 from '../exception/404';
import { Collections } from './institutionSubtypes';
import Actions from './institution.actions';
Expand Down Expand Up @@ -334,7 +334,7 @@ class Institution extends Component {
} />

<Route path={`${match.path}/identifier`} render={() =>
<IdentifierList
<GrSciCollIdentifierList
identifiers={institution.identifiers}
permissions={{ roles: [roles.GRSCICOLL_ADMIN] }}
createIdentifier={data => createIdentifier(key, data)}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import React, {useState, useEffect} from "react";
import { Modal, Input, Select, Spin, Form, Checkbox } from "antd";
import { FormattedMessage } from "react-intl";
import PropTypes from "prop-types";

// APIs
import { getIdentifierTypes } from "../../../../api/enumeration";
// Components
import { FormItem } from "../../index";
const IdentifierCreateForm = (props) => {
const [identifierTypes, setIdentifierTypes] = useState([]);
const [fetching, setFetching] = useState(true);
const [form] = Form.useForm();
useEffect(() => {
getIdentifierTypes().then((types) => {
setIdentifierTypes(types);
setFetching(false);
});
}, []);

const { visible, onCancel, onCreate } = props;

return (
<Modal
visible={visible}
title={
<FormattedMessage
id="createNewIdentifier"
defaultMessage="Create a new identifier"
/>
}
okText={<FormattedMessage id="create" defaultMessage="Create" />}
onCancel={onCancel}
onOk={() => onCreate(form)}
destroyOnClose={true}
maskClosable={false}
closable={false}
>
<Form form={form}>
<FormItem
name="primary"
valuePropName="checked"
label={<FormattedMessage id="primary" defaultMessage="Primary" />}
helpText={
<FormattedMessage
id="help.primaryCheckboxTip"
defaultMessage="Indicates that the contact is the primary contact for the given type"
/>
}
>
<Checkbox />
</FormItem>
<FormItem
name="identifier"
rules={[
{
required: true,
message: (
<FormattedMessage
id="provide.identifier"
defaultMessage="Please provide an identifier"
/>
),
},
]}
label={
<FormattedMessage id="identifier" defaultMessage="Identifier" />
}
helpText={
<FormattedMessage
id="help.identifier"
defaultMessage="The value for the identifier (e.g. doi://12.123/123)."
/>
}
>
<Input />
</FormItem>
<FormItem
name="type"
label={<FormattedMessage id="type" defaultMessage="Type" />}
helpText={
<FormattedMessage
id="help.identifierType"
defaultMessage="Select the type of the identifier."
/>
}
>
<Select
placeholder={
<FormattedMessage
id="select.type"
defaultMessage="Select a type"
/>
}
notFoundContent={fetching ? <Spin size="small" /> : null}
>
{identifierTypes.map((identifierType) => (
<Select.Option value={identifierType} key={identifierType}>
{identifierType}
</Select.Option>
))}
</Select>
</FormItem>
</Form>
</Modal>
);
};

IdentifierCreateForm.propTypes = {
visible: PropTypes.bool.isRequired,
onCancel: PropTypes.func.isRequired,
onCreate: PropTypes.func.isRequired,
};

export default IdentifierCreateForm;
173 changes: 173 additions & 0 deletions src/components/common/subtypes/GrSciCollIdentifierList/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import React from 'react';
import PropTypes from 'prop-types';
import { List, Row, Col } from 'antd';
import { FormattedMessage, injectIntl, FormattedNumber } from 'react-intl';

// Wrappers
import { HasAccess } from '../../../auth';
import withWidth, { MEDIUM } from '../../../hoc/Width';
import withContext from '../../../hoc/withContext';
// Components
import IdentifierCreateForm from './IdentifierCreateForm';
import { ConfirmButton, FormattedRelativeDate } from '../../index';
import { CreateButton } from '../../CreateMessage';

class IdentifierList extends React.Component {
state = {
isModalVisible: false,
identifiers: this.props.identifiers || []
};

showModal = () => {
this.setState({ isModalVisible: true });
};

handleCancel = () => {
this.setState({ isModalVisible: false });
};

deleteIdentifier = item => {
this.props.deleteIdentifier(item.key).then(() => {
// Updating identifiers
const { identifiers } = this.state;
this.setState({
identifiers: identifiers.filter(el => el.key !== item.key)
});
this.props.updateCounts('identifiers', identifiers.length - 1);
this.props.addSuccess({
status: 200,
statusText: this.props.intl.formatMessage({
id: 'beenDeleted.identifier',
defaultMessage: 'Identifier has been deleted'
})
});
}).catch(error => {
this.props.addError({ status: error.response.status, statusText: error.response.data });
});
};

handleSave = form => {
form.validateFields().then((values) => {


this.props.createIdentifier(values).then(response => {
form.resetFields();

const { identifiers } = this.state;
identifiers.unshift({
...values,
key: response.data,
created: new Date().toISOString(),
createdBy: this.props.user.userName
});
this.props.updateCounts('identifiers', identifiers.length);
this.props.addSuccess({
status: 200,
statusText: this.props.intl.formatMessage({
id: 'beenSaved.identifier',
defaultMessage: 'Identifier has been saved'
})
});

this.setState({
isModalVisible: false,
identifiers
});
}).catch(error => {
this.props.addError({ status: error.response.status, statusText: error.response.data });
});
});
};

render() {
const { identifiers, isModalVisible } = this.state;
const { intl, width } = this.props;
const confirmTitle = intl.formatMessage({
id: 'delete.confirmation.identifier',
defaultMessage: 'Are you sure to delete this identifier?'
});

return (
<React.Fragment>
<div className="item-details">
<Row type="flex" justify="space-between">
<Col xs={12} sm={12} md={16}>
<h2><FormattedMessage id="identifiers" defaultMessage="Identifiers"/></h2>
</Col>
<Col xs={12} sm={12} md={8} className="text-right">
<HasAccess fn={this.props.canCreate}>
<CreateButton onClick={() => this.showModal()} />
</HasAccess>
</Col>
</Row>

<List
className="custom-list"
itemLayout="horizontal"
dataSource={identifiers}
header={
identifiers.length ? (<FormattedMessage
id="nResults"
defaultMessage={`{formattedNumber} {count, plural, zero {results} one {result} other {results}}`}
values={{ formattedNumber: <FormattedNumber value={identifiers.length}/>, count: identifiers.length }}
/>) : null
}
renderItem={item => (
<List.Item
actions={[
<HasAccess fn={() => this.props.canDelete(item.key)}>
<ConfirmButton
title={confirmTitle}
btnText={<FormattedMessage id="delete" defaultMessage="Delete"/>}
onConfirm={() => this.deleteIdentifier(item)}
type={'link'}
/>
</HasAccess>
]}
style={width < MEDIUM ? { flexDirection: 'column' } : {}}
>
<List.Item.Meta
title={
<React.Fragment>
<strong className="item-title">{item.identifier}</strong>
<span className="item-type">{item.type}</span>
{item.primary && <span className="item-type" style={{marginLeft: 10, fontSize: 12, background: '#1890ff', borderRadius: 6, color: 'white', padding: '2px 8px '}}>Is primary</span>}
</React.Fragment>
}
description={
<span className="item-description">
<FormattedMessage
id="createdByRow"
defaultMessage={`Created {date} by {author}`}
values={{ date: <FormattedRelativeDate value={item.created}/>, author: item.createdBy }}
/>
</span>
}
/>
</List.Item>
)}
/>

<IdentifierCreateForm
visible={isModalVisible}
onCancel={this.handleCancel}
onCreate={this.handleSave}
/>
</div>
</React.Fragment>
);
}
}

IdentifierList.propTypes = {
identifiers: PropTypes.array.isRequired,
createIdentifier: PropTypes.func,
deleteIdentifier: PropTypes.func,
updateCounts: PropTypes.func,
canCreate: PropTypes.func.isRequired,
canDelete: PropTypes.func.isRequired
};

const mapContextToProps = ({ user, addSuccess, addError }) => ({ user, addSuccess, addError });

export default withContext(mapContextToProps)(withWidth()(injectIntl(IdentifierList)));
2 changes: 2 additions & 0 deletions src/components/common/subtypes/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import ContactList from './ContactList';
import DefaultValueList from './DefaultValueList';
import EndpointList from './EndpointList';
import IdentifierList from './IdentifierList';
import GrSciCollIdentifierList from './GrSciCollIdentifierList';
import MachineTagList from './MachineTagList';
import PersonList from './PersonList';
import ContactPersonList from './ContactPersonList';
Expand All @@ -16,6 +17,7 @@ export {
DefaultValueList,
EndpointList,
IdentifierList,
GrSciCollIdentifierList,
MachineTagList,
PersonList,
ContactPersonList,
Expand Down

0 comments on commit 26083fe

Please sign in to comment.