@aappddeevv/dynamics-client-ui
Version:
## What is it? A library to help you create great dynamics applications.
153 lines • 5.95 kB
JavaScript
;
/** Helpers for managing a DetailsList. */
Object.defineProperty(exports, "__esModule", { value: true });
const R = require("ramda");
exports.OTHER = "OTHER";
/**
* Default sort order state machine table. You can also store these as state in
* in your component and provide them to the byColumns* functions.
*/
exports.defaultOrder = {
FIRST: "asc",
OTHER: "asc",
asc: "desc",
desc: "OTHER"
};
/**
* Previous SortingState => new SortingState (state machine). Only allows single
* column sorting. Cycles through sorting order if its already sorted on that column.
*/
function byColumn({ current, transitions = exports.defaultOrder, selectedColumn = -1, defaultPosition = 0 }) {
if (typeof selectedColumn === "number" && selectedColumn < 0)
return current;
let nextState = transitions.FIRST;
// find if current column is in current state, so we can cycle it
const maybeCurCol = current[selectedColumn];
if (maybeCurCol) {
nextState = transitions[maybeCurCol.direction]; // returns next state
if (!nextState)
return {};
}
return {
[selectedColumn]: {
direction: nextState,
position: defaultPosition
}
};
}
exports.byColumn = byColumn;
/**
* Updates a multi column sorting state by updating the selectedColumn.
* If selectedColumn is new to the sorting state, it is placed last in the
* positions.
*/
function byColumns({ current, transitions = exports.defaultOrder, selectedColumn = -1 }) {
// get last position, assume sorting state is "short"
const max = Math.max(...Object.keys(current ? current : {}).map(k => current[k].position)) + 1;
const alreadyExists = current ? (current[selectedColumn] ? true : false) : false;
let newOrUsed = alreadyExists ?
byColumn({ current, transitions, selectedColumn, defaultPosition: current[selectedColumn].position }) :
byColumn({ current, transitions, selectedColumn, defaultPosition: max });
return Object.assign({}, current, newOrUsed);
}
exports.byColumns = byColumns;
/** Get the property name of the data accessor used for sorting from an IColumn. */
function getSortAttribute(c) {
if (c.data && c.data.sortAttribute)
return c.data.sortAttribute;
else
return c.fieldName;
}
/**
* Create a Sorter given columns, sorting state and a sort function factory.
* Uses IColumn.key to lookup fieldname|data.sortAttribute if sorting state has a property name as a key,
* or IColumn[index] to lookup the column.
*/
exports.sorter = ({ columns, state, factory = ramdaSortFunctionFactory }) => {
// flatten sorting state
const x = Object.keys(state).map(k => {
const sortInfo = state[k];
let p = (typeof k === "number") ?
getSortAttribute(columns[k]) :
getSortAttribute(columns.find(c => c.key === k));
return { property: p,
direction: sortInfo.direction,
order: sortInfo.position };
});
return factory ?
factory(R.sort(i => i.order, x)) :
ramdaSortFunctionFactory(R.sort(i => i.order, x));
};
/** Sort function factory that uses ramda sortWith. */
function ramdaSortFunctionFactory(info) {
const comparators = info.filter(i => i.direction !== exports.OTHER).
map(i => {
if (i.direction === "asc")
return R.ascend(R.prop(i.property));
else
return R.descend(R.prop(i.property));
});
return (comparators.length === 0 ?
R.identity :
R.sortWith(comparators));
}
exports.ramdaSortFunctionFactory = ramdaSortFunctionFactory;
/** Update column definitios based on the column key and the map of updates. */
function updateColumns(columns, updates) {
return columns.map(c => {
const update = Object.assign({}, c, updates[c.key]);
return update;
});
}
exports.updateColumns = updateColumns;
/**
* Enhance a list of column-like information based on the sortState. All columns are
* are sortable unless data.isSortable = false.
* You can set a DetailsList.onColumnHeaderClick instead of passing in onSortColumn.
*/
function augmentColumns(cols, sortState, onSortColumn, getMoreProps) {
return cols.map((c, idx) => {
if (c.data && typeof c.data.isSortable === "boolean" && !c.data.isSortable)
return Object.assign({}, c);
const sortInfo = sortState[c.key];
const isSorted = sortInfo ? (sortInfo.direction !== exports.OTHER) : undefined;
const isSortedDescending = isSorted ?
(sortInfo.direction === "desc" ? true : false) : undefined;
const moreProps = getMoreProps ? getMoreProps(c, idx) : {};
const onCC = onSortColumn ?
{ onColumnClick: (x, col) => { if (col)
onSortColumn(col); } } :
{};
return Object.assign({}, c, moreProps, { isSorted,
isSortedDescending }, onCC);
});
}
exports.augmentColumns = augmentColumns;
/**
* Given a request to sort, update critical key parts of the sorting infrastructure.
* You will need to sort your data with the returned sorter function. The returned
* columns are updated with the new sort state (e.g. isSorted, isSortedDescending).
*/
function onSortColumn(c, columns, sortState, transitions, factory = ramdaSortFunctionFactory) {
// create the new sort state
const state = byColumns({
current: sortState,
transitions,
selectedColumn: c.key,
});
// augment the columns with the new sort state
const newColumns = augmentColumns(columns, state);
// create the new sorter function
const newSorter = exports.sorter({
columns: newColumns,
state,
factory,
});
return {
columns: newColumns,
sortState: state,
sorter: newSorter,
};
}
exports.onSortColumn = onSortColumn;
//# sourceMappingURL=DetailsListHelpers.js.map