/** @module hooks/sortable */
import { i18n, hooks, urlParam, addUrlParam, ajax } from '../util';
import $ from 'jquery';
import store from '../store';
import { message } from 'react-aiot';
const WP_TABLE_LIST_SELECTOR = '.wp-list-table.media tbody';
/**
* Apply an order to attachments browser without reloading the collection.
*/
export function applyToAttachmentsBrowser(attachmentsBrowser, selected, orderby = 'rml', order = 'ASC') {
let filter;
if (attachmentsBrowser && (filter = attachmentsBrowser.toolbar.get('rml_folder').filters[selected.id])) {
const props = attachmentsBrowser.collection.props, o = { silent: true };
if (selected.contentCustomOrder === 1) {
filter.props.orderby = 'rml';
filter.props.order = 'ASC';
props.set({ orderby, order }, o);
}else{
delete filter.props.orderby;
delete filter.props.order;
props.set({ orderby: 'date', order: 'DESC' }, o);
}
}
}
/**
* An item gets relocated, so update the table or grid view.
*/
hooks.register('attachment/relocate', (node, attachmentId, nextId, lastIdInView, next, e, ui) => {
const attachmentsBrowser = $(ui.item).parents(".attachments-browser").data('backboneView');
ui.item.stop().fadeTo(100, 0.2);
ajax('attachments/' + attachmentId, {
method: 'PUT',
data: {
folderId: node.id,
nextId,
lastId: lastIdInView
}
}).done(() => {
node.setter(node => (node.contentCustomOrder = 1));
applyToAttachmentsBrowser(attachmentsBrowser, node);
ui.item.stop().fadeTo(100, 1);
});
});
/**
* Prepare sortable in list table mode.
*/
hooks.register('ready', () => {
let lastIdInView;
// Grid mode
$(document).on('sortstart', '.attachments-browser ul.attachments', function(e, ui) {
const { collection } = $(this).parents(".attachments-browser").data('backboneView');
lastIdInView = collection.models[collection.models.length - 1].id;
}).on('sortupdate', '.attachments-browser ul.attachments', function(e, ui) {
const next = ui.item.next(),
nextId = next.html() ? next.data('id') : false,
attachmentId = ui.item.data('id'),
folder = $(this).parents(".attachments-browser").data('backboneView').controller.$RmlAppTree.getTreeItemById();
/**
* An attachment is relocated and should be saved to the server.
*
* @event module:util/hooks#attachment/relocate
* @param {module:store/TreeNode~TreeNode} folder The tree node
* @param {int} attachmentId The attachment id
* @param {int} nextId The next id
* @param {int} lastIdInView
* @param {jQuery} next
* @this wp.media.view.AttachmentsBrowser
*/
hooks.call('attachment/relocate', [folder, attachmentId, nextId, lastIdInView, next, e, ui]);
});
// List mode
$(WP_TABLE_LIST_SELECTOR).sortable({
disabled: true,
appendTo: 'body',
tolerance: 'pointer',
scrollSensitivity: 50,
placeholder: 'ui-sortable-helper-wp-media-list',
scrollSpeed: 50,
distance: 10,
cursor: 'move',
start: function(e, ui) {
ui.placeholder.height(ui.helper[0].scrollHeight);
// The last ID (grid mode is done in the backbone collection)
lastIdInView = +$(WP_TABLE_LIST_SELECTOR + ' tr:last input[name="media[]"]').val();
},
update: function(e, ui) {
const next = ui.item.next(),
nextId = next.html() ? next.find('input[name="media[]"]').val() : false,
attachmentId = ui.item.find('input[name="media[]"]').val(),
folderId = $('.rml-container .aiot-active').data('id');
hooks.call('attachment/relocate', [store.getTreeItemById(folderId), attachmentId, nextId, lastIdInView, next, e, ui]);
}
});
});
/**
* Checks if a filter is active.
*
* @param {object} [attachmentsBrowser] If set the filter is searched in the backbone controller
*/
export function isFilterActive(attachmentsBrowser) {
if (attachmentsBrowser) {
const filters = ['monthnum', 'year', 'uploadedTo', 'type'],
{ props } = attachmentsBrowser.collection;
for (let i = 0; i < filters.length; i++) {
if (props.get(filters[i])) {
return true;
}
}
return false;
}else{
// List
return !!urlParam('attachment-filter');
}
}
/**
* Checks if a orderby is active.
*
* @param {object} [attachmentsBrowser] If set the filter is searched in the backbone controller
*/
export function isOrderByActive(attachmentsBrowser, orderby = 'rml', order = 'ASC') {
if (attachmentsBrowser) {
const { props } = attachmentsBrowser.collection, propOrder = props.get('order') || 'DESC';
return props.get('orderby') === orderby && propOrder.toUpperCase() === order.toUpperCase();
}else{
// List
const propOrder = urlParam('order') || 'DESC';
return urlParam('orderby') === orderby && propOrder.toUpperCase() === order.toUpperCase();
}
}
/**
* @returns {string}
*/
export function orderUrl(href = window.location.href) {
return addUrlParam(addUrlParam(href, 'orderby', 'rml'), 'order', 'asc');
}
/**
* Toggle the sortable mode. Popup a message if custom order is not disabled, yet.
* If custom order is enabled check the different list and grid mode behavior.
*
* @param {object} selected The selected node
* @parma {boolean} mode The mode to activate
* @param {object} [attachmentsBrowser] If set the filter is searched in the backbone controller
*/
export function toggleSortable(selected, mode, attachmentsBrowser) {
const orderByActive = isOrderByActive(attachmentsBrowser) || isOrderByActive(attachmentsBrowser, 'date', 'DESC'),
filterActive = isFilterActive(attachmentsBrowser),
redirect = !orderByActive || filterActive;
// Redirect to the sortable mode
if (redirect && mode) {
if (!attachmentsBrowser) {
const href = orderUrl();
window.location.href = href + "#order";
}else{
// Grid mode, show popup that the filters should be deactivated
message.error(i18n('orderFilterActive'));
}
return false;
}
// Toggle sortable
(attachmentsBrowser ? attachmentsBrowser.attachments.$el : $(WP_TABLE_LIST_SELECTOR)).sortable(mode ? 'enable' : 'disable');
return true;
}