Make Card and Datatable components more flexible when working with static data; add title prop

This commit is contained in:
SachaG 2018-07-11 08:34:01 +02:00
parent 2eeb5af8a8
commit 4af2492e07
2 changed files with 54 additions and 31 deletions

View file

@ -7,8 +7,8 @@ import moment from 'moment';
import { Link } from 'react-router';
const getLabel = (field, fieldName, collection, intl) => {
const schema = collection.simpleSchema()._schema;
const fieldSchema = schema[fieldName];
const schema = collection && collection.simpleSchema()._schema;
const fieldSchema = schema && schema[fieldName];
if (fieldSchema) {
return intl.formatMessage({id: `${collection._name}.${fieldName}`, defaultMessage: fieldSchema.label});
} else {
@ -17,8 +17,8 @@ const getLabel = (field, fieldName, collection, intl) => {
}
const getTypeName = (field, fieldName, collection) => {
const schema = collection.simpleSchema()._schema;
const fieldSchema = schema[fieldName];
const schema = collection && collection.simpleSchema()._schema;
const fieldSchema = schema && schema[fieldName];
if (fieldSchema) {
const type = fieldSchema.type.singleType;
const typeName = typeof type === 'function' ? type.name : type;
@ -53,6 +53,11 @@ export const getFieldValue = (value, typeName) => {
return ''
}
// JSX element
if (React.isValidElement(value)) {
return value;
}
if (Array.isArray(value)) {
typeName = 'Array';
}
@ -80,9 +85,13 @@ export const getFieldValue = (value, typeName) => {
case 'Date':
return moment(new Date(value)).format('dddd, MMMM Do YYYY, h:mm:ss');
default:
case 'String':
case 'string':
return parseImageUrl(value);
}
default:
return value.toString();
}
}
const getObject = object => {
@ -143,13 +152,14 @@ const CardEditForm = ({ collection, document, closeModal }) =>
}}
/>
const Card = ({className, collection, document, currentUser, fields, showEdit = true}, {intl}) => {
const Card = ({title, className, collection, document, currentUser, fields, showEdit = true}, {intl}) => {
const fieldNames = fields ? fields : _.without(_.keys(document), '__typename');
const canEdit = showEdit && currentUser && collection.options.mutations.update.check(currentUser, document);
const canEdit = showEdit && currentUser && collection && collection.options.mutations.update.check(currentUser, document);
return (
<div className={classNames(className, 'datacard', `datacard-${collection._name}`)}>
<div className={classNames(className, 'datacard', collection && `datacard-${collection._name}`)}>
{title && <div className="datacard-title">{title}</div>}
<table className="table table-bordered" style={{maxWidth: '100%'}}>
<tbody>
{canEdit ? <CardEdit collection={collection} document={document} /> : null}

View file

@ -62,7 +62,7 @@ class Datatable extends PureComponent {
if (this.props.data) { // static JSON datatable
return <Components.DatatableContents {...this.props} results={this.props.data}/>;
return <Components.DatatableContents columns={Object.keys(this.props.data[0])} {...this.props} results={this.props.data} showEdit={false} showNew={false} />;
} else { // dynamic datatable with data loading
@ -87,6 +87,7 @@ class Datatable extends PureComponent {
}
Datatable.propTypes = {
title: PropTypes.string,
collection: PropTypes.object,
columns: PropTypes.array,
data: PropTypes.array,
@ -211,7 +212,8 @@ DatatableContents Component
const DatatableContents = (props) => {
const {collection, columns, results, loading, loadMore, count, totalCount, networkStatus, showEdit, currentUser, emptyState, toggleSort, currentSort } = props;
// if no columns are provided, default to using keys of first array item
const { title, collection, results, columns, loading, loadMore, count, totalCount, networkStatus, showEdit, currentUser, emptyState, toggleSort, currentSort } = props;
if (loading) {
return <div className="datatable-list datatable-list-loading"><Components.Loading /></div>;
@ -224,32 +226,43 @@ const DatatableContents = (props) => {
return (
<div className="datatable-list">
<table className="table">
<thead>
<tr>
{_.sortBy(columns, column => column.order).map((column, index) => <Components.DatatableHeader key={index} collection={collection} column={column} toggleSort={toggleSort} currentSort={currentSort} />)}
{showEdit ? <th><FormattedMessage id="datatable.edit"/></th> : null}
</tr>
</thead>
<tbody>
{results.map((document, index) => <Components.DatatableRow {...props} collection={collection} columns={columns} document={document} key={index} showEdit={showEdit} currentUser={currentUser}/>)}
</tbody>
</table>
{hasMore &&
<div className="datatable-list-load-more">
{isLoadingMore ?
<Components.Loading/> :
<Components.Button variant="primary" onClick={e => {e.preventDefault(); loadMore();}}>Load More ({count}/{totalCount})</Components.Button>
}
</div>
}
</div>
{title && <Components.DatatableTitle title={title}/>}
<table className="table">
<thead>
<tr>
{_.sortBy(columns, column => column.order).map((column, index) => <Components.DatatableHeader key={index} collection={collection} column={column} toggleSort={toggleSort} currentSort={currentSort} />)}
{showEdit ? <th><FormattedMessage id="datatable.edit"/></th> : null}
</tr>
</thead>
<tbody>
{results.map((document, index) => <Components.DatatableRow {...props} collection={collection} columns={columns} document={document} key={index} showEdit={showEdit} currentUser={currentUser}/>)}
</tbody>
</table>
{hasMore &&
<div className="datatable-list-load-more">
{isLoadingMore ?
<Components.Loading/> :
<Components.Button variant="primary" onClick={e => {e.preventDefault(); loadMore();}}>Load More ({count}/{totalCount})</Components.Button>
}
</div>
}
</div>
)
}
registerComponent('DatatableContents', DatatableContents);
/*
DatatableTitle Component
*/
const DatatableTitle = ({ title }) =>
<div className="datatable-title">{title}</div>
registerComponent('DatatableTitle', DatatableTitle);
/*
DatatableRow Component
*/