mirror of
https://github.com/vale981/Vulcan
synced 2025-03-05 17:41:43 -05:00
Add support for sortable property (bool/string) on datatable columns to make them sortable
This commit is contained in:
parent
4ec9c08500
commit
4da86c44a3
2 changed files with 65 additions and 9 deletions
|
@ -28,10 +28,23 @@ class Datatable extends PureComponent {
|
|||
this.updateQuery = this.updateQuery.bind(this);
|
||||
this.state = {
|
||||
value: '',
|
||||
query: ''
|
||||
query: '',
|
||||
currentSort: {}
|
||||
}
|
||||
}
|
||||
|
||||
toggleSort = column => {
|
||||
let currentSort;
|
||||
if (!this.state.currentSort[column]) {
|
||||
currentSort = { [column] : 1 };
|
||||
} else if (this.state.currentSort[column] === 1) {
|
||||
currentSort = { [column] : -1 };
|
||||
} else {
|
||||
currentSort = {};
|
||||
}
|
||||
this.setState({ currentSort });
|
||||
}
|
||||
|
||||
updateQuery(e) {
|
||||
e.persist()
|
||||
e.preventDefault();
|
||||
|
@ -66,7 +79,7 @@ class Datatable extends PureComponent {
|
|||
return (
|
||||
<div className={`datatable datatable-${collection.options.collectionName}`}>
|
||||
<Components.DatatableAbove {...this.props} collection={collection} canInsert={canInsert} value={this.state.value} updateQuery={this.updateQuery} />
|
||||
<DatatableWithList {...this.props} collection={collection} terms={{query: this.state.query}} currentUser={this.props.currentUser}/>
|
||||
<DatatableWithList {...this.props} collection={collection} terms={{query: this.state.query, orderBy: this.state.currentSort }} currentUser={this.props.currentUser} toggleSort={this.toggleSort} currentSort={this.state.currentSort}/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -116,7 +129,7 @@ registerComponent('DatatableAbove', DatatableAbove);
|
|||
DatatableHeader Component
|
||||
|
||||
*/
|
||||
const DatatableHeader = ({ collection, column }, { intl }) => {
|
||||
const DatatableHeader = ({ collection, column, toggleSort, currentSort }, { intl }) => {
|
||||
|
||||
const columnName = typeof column === 'string' ? column : column.label || column.name;
|
||||
|
||||
|
@ -135,7 +148,9 @@ const DatatableHeader = ({ collection, column }, { intl }) => {
|
|||
const defaultMessage = schema[columnName] ? schema[columnName].label : Utils.camelToSpaces(columnName);
|
||||
const formattedLabel = intl.formatMessage({ id: `${collection._name}.${columnName}`, defaultMessage });
|
||||
|
||||
return <th>{formattedLabel}</th>;
|
||||
// if sortable is a string, use it as the name of the property to sort by. If it's just `true`, use column.name
|
||||
const sortPropertyName = typeof column.sortable === 'string' ? column.sortable : column.name;
|
||||
return column.sortable ? <Components.DatatableSorter name={sortPropertyName} label={formattedLabel} toggleSort={toggleSort} currentSort={currentSort} sortable={column.sortable}/> : <th>{formattedLabel}</th>;
|
||||
|
||||
} else {
|
||||
|
||||
|
@ -151,6 +166,43 @@ DatatableHeader.contextTypes = {
|
|||
|
||||
registerComponent('DatatableHeader', DatatableHeader);
|
||||
|
||||
const SortNone = () =>
|
||||
<svg width='16' height='16' viewBox='0 0 438 438' fill='none' xmlns='http://www.w3.org/2000/svg'>
|
||||
<path d='M25.7368 247.243H280.263C303.149 247.243 314.592 274.958 298.444 291.116L171.18 418.456C161.128 428.515 144.872 428.515 134.926 418.456L7.55631 291.116C-8.59221 274.958 2.85078 247.243 25.7368 247.243ZM298.444 134.884L171.18 7.54408C161.128 -2.51469 144.872 -2.51469 134.926 7.54408L7.55631 134.884C-8.59221 151.042 2.85078 178.757 25.7368 178.757H280.263C303.149 178.757 314.592 151.042 298.444 134.884Z' transform='translate(66 6)' fill='#000' fillOpacity='0.2' />
|
||||
</svg>
|
||||
|
||||
const SortDesc = () =>
|
||||
<svg width="16" height="16" viewBox="0 0 438 438" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M25.7368 0H280.263C303.149 0 314.592 27.7151 298.444 43.8734L171.18 171.213C161.128 181.272 144.872 181.272 134.926 171.213L7.55631 43.8734C-8.59221 27.7151 2.85078 0 25.7368 0Z" transform="translate(66 253.243)" fill="black" fillOpacity="0.7"/>
|
||||
<path d="M171.18 7.54408L298.444 134.884C314.592 151.042 303.149 178.757 280.263 178.757H25.7368C2.85078 178.757 -8.59221 151.042 7.55631 134.884L134.926 7.54408C144.872 -2.51469 161.128 -2.51469 171.18 7.54408Z" transform="translate(66 6)" fill="black" fillOpacity="0.2"/>
|
||||
</svg>
|
||||
|
||||
const SortAsc = () =>
|
||||
<svg width="16" height="16" viewBox="0 0 438 438" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M298.444 134.884L171.18 7.54408C161.128 -2.51469 144.872 -2.51469 134.926 7.54408L7.55631 134.884C-8.59221 151.042 2.85078 178.757 25.7368 178.757H280.263C303.149 178.757 314.592 151.042 298.444 134.884Z" transform="translate(66 6)" fill="black" fillOpacity="0.7"/>
|
||||
<path d="M280.263 0H25.7368C2.85078 0 -8.59221 27.7151 7.55631 43.8734L134.926 171.213C144.872 181.272 161.128 181.272 171.18 171.213L298.444 43.8734C314.592 27.7151 303.149 0 280.263 0Z" transform="translate(66 253.243)" fill="black" fillOpacity="0.2"/>
|
||||
</svg>
|
||||
|
||||
const DatatableSorter = ({ name, label, toggleSort, currentSort }) =>
|
||||
|
||||
<th>
|
||||
<div className="datatable-sorter" onClick={() => {toggleSort(name)}}>
|
||||
<span className="datatable-sorter-label">{label}</span>
|
||||
<span className="sort-icon">
|
||||
{!currentSort[name] ? (
|
||||
<SortNone/>
|
||||
) : currentSort[name] === 1 ? (
|
||||
<SortDesc/>
|
||||
) : (
|
||||
<SortAsc/>
|
||||
)
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
</th>
|
||||
|
||||
registerComponent('DatatableSorter', DatatableSorter);
|
||||
|
||||
/*
|
||||
|
||||
DatatableContents Component
|
||||
|
@ -159,11 +211,11 @@ DatatableContents Component
|
|||
|
||||
const DatatableContents = (props) => {
|
||||
|
||||
const {collection, columns, results, loading, loadMore, count, totalCount, networkStatus, showEdit, currentUser, emptyState} = props;
|
||||
const {collection, columns, results, loading, loadMore, count, totalCount, networkStatus, showEdit, currentUser, emptyState, toggleSort, currentSort } = props;
|
||||
|
||||
if (loading) {
|
||||
return <div className="datatable-list datatable-list-loading"><Components.Loading /></div>;
|
||||
} else if (!results.length) {
|
||||
} else if (!results || !results.length) {
|
||||
return emptyState || null;
|
||||
}
|
||||
|
||||
|
@ -175,7 +227,7 @@ const DatatableContents = (props) => {
|
|||
<table className="table">
|
||||
<thead>
|
||||
<tr>
|
||||
{_.sortBy(columns, column => column.order).map((column, index) => <Components.DatatableHeader key={index} collection={collection} column={column}/>)}
|
||||
{_.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>
|
||||
|
|
|
@ -6,7 +6,6 @@ import { runCallbacks } from './callbacks.js';
|
|||
import { getSetting, registerSetting } from './settings.js';
|
||||
import { registerFragment, getDefaultFragmentText } from './fragments.js';
|
||||
import escapeStringRegexp from 'escape-string-regexp';
|
||||
import { isIntlField } from './intl.js';
|
||||
const wrapAsync = (Meteor.wrapAsync)? Meteor.wrapAsync : Meteor._wrapAsync;
|
||||
// import { debug } from './debug.js';
|
||||
|
||||
|
@ -297,6 +296,11 @@ export const createCollection = options => {
|
|||
parameters = runCallbacks(`${collectionName.toLowerCase()}.parameters.server`, parameters, _.clone(terms), context);
|
||||
}
|
||||
|
||||
// sort using terms.orderBy (overwrite defaultView's sort)
|
||||
if (terms.orderBy && !_.isEmpty(terms.orderBy)) {
|
||||
parameters.options.sort = terms.orderBy
|
||||
}
|
||||
|
||||
// if there is no sort, default to sorting by createdAt descending
|
||||
if (!parameters.options.sort) {
|
||||
parameters.options.sort = { createdAt: -1 };
|
||||
|
@ -318,7 +322,7 @@ export const createCollection = options => {
|
|||
});
|
||||
}
|
||||
|
||||
if(terms.query) {
|
||||
if (terms.query) {
|
||||
|
||||
const query = escapeStringRegexp(terms.query);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue