@uppy/provider-views
Version:
View library for Uppy remote provider plugins.
82 lines (77 loc) • 2.75 kB
JavaScript
/* eslint-disable no-param-reassign */
import shallowClone from './shallowClone.js';
/*
FROM | TO
root | root
folder | folder
folder ✅︎ | folder ✅︎
file | file ✅︎
file | file ✅︎
folder | folder ✅︎
file | file ✅︎
file | file
file | file
*/
const percolateDown = (tree, id, shouldMarkAsChecked) => {
const children = tree.filter(item => item.type !== 'root' && item.parentId === id);
children.forEach(item => {
item.status = shouldMarkAsChecked && !(item.type === 'file' && item.restrictionError) ? 'checked' : 'unchecked';
percolateDown(tree, item.id, shouldMarkAsChecked);
});
};
/*
FROM | TO
root | root
folder | folder
folder | folder [▬] ('partial' status)
file | file
folder | folder ✅︎
file ✅︎ | file ✅︎
file | file
file | file
*/
const percolateUp = (tree, id) => {
const folder = tree.find(item => item.id === id);
if (folder.type === 'root') return;
const validChildren = tree.filter(item =>
// is a child
item.type !== 'root' && item.parentId === folder.id &&
// does pass validations
!(item.type === 'file' && item.restrictionError));
const areAllChildrenChecked = validChildren.every(item => item.status === 'checked');
const areAllChildrenUnchecked = validChildren.every(item => item.status === 'unchecked');
if (areAllChildrenChecked) {
folder.status = 'checked';
} else if (areAllChildrenUnchecked) {
folder.status = 'unchecked';
} else {
folder.status = 'partial';
}
percolateUp(tree, folder.parentId);
};
const afterToggleCheckbox = (oldTree, clickedRange) => {
const tree = shallowClone(oldTree);
if (clickedRange.length >= 2) {
// We checked two or more items
const newlyCheckedItems = tree.filter(item => item.type !== 'root' && clickedRange.includes(item.id));
newlyCheckedItems.forEach(item => {
if (item.type === 'file') {
item.status = item.restrictionError ? 'unchecked' : 'checked';
} else {
item.status = 'checked';
}
});
newlyCheckedItems.forEach(item => {
percolateDown(tree, item.id, true);
});
percolateUp(tree, newlyCheckedItems[0].parentId);
} else {
// We checked exactly one item
const clickedItem = tree.find(item => item.id === clickedRange[0]);
clickedItem.status = clickedItem.status === 'checked' ? 'unchecked' : 'checked';
percolateDown(tree, clickedItem.id, clickedItem.status === 'checked');
percolateUp(tree, clickedItem.parentId);
}
return tree;
};
export default afterToggleCheckbox;