component that shows the buttons and modal
import React, { Component } from 'react';
import PropTypes from 'prop-types';
// Redux
import { connect } from 'react-redux';
import * as actions from './actions';
// Global Components
import MainContent from 'components/MainContent';
import TableFilter from 'components/TableFilter';
import DataTable from 'components/Datatable';
import Pagination from 'components/Pagination';
import TitleScreen from 'components/TitleScreen';
import DetailArchivesLibrary from 'components/DetailArchivesLibrary';
import ContextMenu from 'components/ContextMenu';
import Icon from 'components/Icon';
// Services
import Hash from 'services/HashQuery';
const hash = new Hash();
// Features
import FeatureCreator from 'features/FeatureCreator';
// Utils
import convertDate from 'utils/convertDate';
class ArchiveLibrary extends Component {
constructor(props) {
super(props);
this.state = {
dataTable: [],
infoTable: null,
showFeature: false,
featureData: null,
modelteste: 'cadastro'
};
}
componentWillMount() {
this.props.libraryList(this.props.userData.account_id);
}
componentWillReceiveProps(nextProps) {
if (nextProps.features.messageCode === 'request_create_document_library') return;
if ( nextProps.response.code === 'api.delete.document.success' || this.props.features.updateKey !== nextProps.features.updateKey )
return this.props.libraryList(this.props.userData.account_id);
this.setState({
dataTable: nextProps.response.results,
infoTable: nextProps.response.resultsInfo
});
}
render() {
const headerTable = [
{ name: 'Tipo', orderBy: 'type' },
{ name: 'Vencimento', orderBy: 'maturity', align: 'center' },
{ name: 'Status', orderBy: 'isMaturity', align: 'center' },
];
const isExpires = (item) => {
return item.validity_status == 0 ?
<Icon name="check" size="small" color="green" />
: item.validity_status == 1 ?
<Icon name="warning_2" size="small" color="yellow" /> :
<Icon name="warning" size="small" color="red" />;
};
return (
<MainContent>
<MainContent.Header>
<TitleScreen title={this.props.name} />
</MainContent.Header>
<MainContent.Body>
<TableFilter
currentSearch={hash.toObject().search}
onSubmitSearch={this.submitSearch.bind(this)}
/>
<br />
<DataTable
data={this.state.dataTable}
openedRow={hash.toObject().row}
onToggleRow={rowId => rowId ? hash.push({ row: rowId }) : null}
header={headerTable}
rowDetails={row =>
<DetailArchivesLibrary
onEdit={this.onEditLibrary.bind(this)}
onRemove={this.onRemoveLibrary.bind(this)}
currentUser={this.props.currentUser}
rowData={row}
/>}>
<DataTable.Col template={row => <span>{row.type.description}</span>} />
<DataTable.Col template={row => <span>{convertDate(row.expires_at) || '-'}</span>} />
<DataTable.Col template={row => <span>{isExpires(row)}</span>} />
</DataTable>
<Pagination
current={hash.toObject().page}
total={this.state.infoTable !== null && this.state.infoTable !== undefined ? this.state.infoTable.total : 0}
itemsPerPage={this.state.infoTable !== null && this.state.infoTable !== undefined ? this.state.infoTable.perPage : 0}
onChange={this.changeTablePage.bind(this)}
/>
</MainContent.Body>
<MainContent.Footer>
<ContextMenu
options={[{ label: 'Cadastrar Documento', icon: 'plus', onClick: this.openModal.bind(this, null) }]}
/>
<FeatureCreator
scope="RegisterDocument"
trigger={this.state.showFeature}
tooltip={this.state.modelteste}
defaultData={this.state.featureData}
/>
</MainContent.Footer>
</MainContent>
);
}
onEditLibrary(data,index) {
this.setState({modelteste: 'editar'})
this.openModal(data);
}
onRemoveLibrary(data) {
this.props.removeLibrary(this.props.userData.account_id, data.id);
}
openModal(data) {
this.setState({
showFeature: !this.state.showFeature,
featureData: data
});
setTimeout(() => this.setState({ showFeature: false }), 100);
}
// SEARCH METHODS
/**
* Recebe a palavra digitada no campo de pesquisa e filtra a lista de itens de acordo
* com a 'search word'.
* @param {nullElement} event
* @param {Proxy} form
*/
submitSearch(event, form) {
const search = form.elements.search.value.toLowerCase();
this.props.libraryList(this.props.userData.account_id, 'search=${search}');
}
/**
* Método executado quando clicamos
* no botão de paginação da lista
*/
changeTablePage(currentPage) {
this.props.libraryList(this.props.userData.account_id, 'page=${currentPage}');
}
}
ArchiveLibrary.propTypes = {
};
export default connect((store) => {
return {
response: store.archiveLibrary,
userData: store.login.response,
features: store.features
};
}, actions)(ArchiveLibrary);
component modal
import React from 'react';
import PropTypes from 'prop-types';
import classnames from 'classnames';
import sprites from 'static/media/sprites.svg';
export default class Modal extends React.PureComponent {
constructor() {
super();
this.state = {
isOpen: false
};
}
componentWillReceiveProps(nextProps) {
updateModalPosition(460);
if (this.state.isOpen != nextProps.isOpen) {
setTimeout(() => {
this.setState({
isOpen: nextProps.isOpen
});
}, 50);
if (this.props.onOpen && nextProps.isOpen == true) this.props.onOpen();
setTimeout(() => {
updateModalPosition(460);
}, 60);
}
}
componentDidMount() {
if (this.state.isOpen != this.props.isOpen) {
setTimeout(() => {
this.setState({
isOpen: this.props.isOpen
});
}, 50);
if (this.props.onOpen && this.props.isOpen == true) this.props.onOpen();
setTimeout(() => {
updateModalPosition(460);
}, 60);
}
window.addEventListener('resize', updateModalPosition);
}
componentWillUnmount() {
window.removeEventListener('resize', updateModalPosition);
}
closeModal() {
this.setState({ isOpen: false });
if (this.props.onClose) this.props.onClose();
}
render() {
const { children, title } = this.props;
const modalClasses = classnames([
'modal',
{ 'is-active': this.state.isOpen }
]);
return (
<div className={modalClasses}>
<div className="modal__content">
<header className="modal-header">
<h3 className="heading heading--primary heading--bold">
{title}
</h3>
<button className="modal-close" title="Fechar" onClick={this.closeModal.bind(this)} style={{ marginTop: '0px' }}>
<svg xmlns="http://www.w3.org/2000/svg" className="icon icon--small">
<use xmlnsXlink="http://www.w3.org/1999/xlink" xlinkHref={'${sprites}#close'}></use>
</svg>
</button>
</header>
<div className="modal-body" style={{ maxHeight: window.innerHeight - 69, overflowY: 'auto' }}>
{children}
</div>
{/*
<footer className="modal-footer">
<div className="button-group button-group--row">
<button type="button" className="button button--bare">
<span className="button__label" onClick={this.closeModal.bind(this)}>
Cancelar
</span>
</button>
<button type="button" className="button">
<span className="button__label">Salvar</span>
</button>
</div>
</footer>
*/}
</div>
<div className="modal__background"></div>
</div>
);
}
};
Modal.propTypes = {
onClose: PropTypes.func,
onOpen: PropTypes.func
};
function elementProps(target) {
if (!target) return;
let box = target.getBoundingClientRect();
let body = document.body;
let docElem = document.documentElement;
let scrollTop = window.pageYOffset || docElem.scrollTop || body.scrollTop;
let scrollLeft = window.pageXOffset || docElem.scrollLeft || body.scrollLeft;
let clientTop = docElem.clientTop || body.clientTop || 0;
let clientLeft = docElem.clientLeft || body.clientLeft || 0;
let top = box.top + scrollTop - clientTop;
let left = box.left + scrollLeft - clientLeft;
return { top: Math.round(top), left: Math.round(left), width: box.width, height: box.height };
};
function windowSize() {
let wWidth = window.innerWidth;
let wHeight = window.innerHeight;
return { width: wWidth, height: wHeight };
};
function updateModalPosition(size) {
let allModalContent = document.querySelectorAll('.modal__content');
Array(...allModalContent).forEach((modalContent) => {
let modalContentTop = Math.round((windowSize().height / 2) - (elementProps(modalContent).height / 2));
if (elementProps(modalContent).height > windowSize().height || elementProps(modalContent).height == windowSize().height) {
modalContentTop = 0;
}
let modalContentLeft = Math.round((windowSize().width / 2) - (size / 2));
modalContent.setAttribute('style', 'top: ' + modalContentTop + 'px; left: ' + modalContentLeft + 'px;')
});
}
There is already a modal of inputs but I needed a confirmation when deleting could give me a light where to start or seila send me some post that talks about it thanks