Instantly share code, notes, and snippets.

Embed
What would you like to do?

Sort WorkFlowy

  • Zoom on a bullet.
  • Activate the bookmarklet or use the userscript shortcut Ctrl+Shft+S.
  • A prompt appears with 2 sorting buttons: A-Z and Z-A.
  • Only the zoom level children get sorted.
  • Grandchildren stay with their parents, but are not sorted.
  • Completed children are sorted, even when hidden.
  • After sorting is complete, a message confirms the sort.
  • Undo the sort using WorkFlowy's standard undo feature.
  • For transparency, the bookmarklet will not sort if search is active.
  • To limit the load on WorkFlowy's servers, the maximum number of children that can be sorted is 400.

Links:

Version Notes:

  • v3.1 (2018-12-11) Update to new move API
  • v3.0 (2018-11-06) Fix broken dialog
// ==UserScript==
// @name Sort WorkFlowy
// @namespace https://rawbytz.wordpress.com
// @version 3.1
// @description Use Ctrl+Shift+S to sort the current zoom level children.
// @author rawbytz
// @match https://workflowy.com/*
// @match https://beta.workflowy.com/*
// @updateUrl https://gist.github.com/rawbytz/3b295652c24738b044dd4d4ee8b4a0e3/raw/sortWorkFlowy.user.js
// @downloadUrl https://gist.github.com/rawbytz/3b295652c24738b044dd4d4ee8b4a0e3/raw/sortWorkFlowy.user.js
// @grant none
// @run-at document-end
// ==/UserScript==
(function () {
'use strict';
function sortMe(maxChildren) {
function toastMsg(str, sec, err) {
WF.showMessage("<b>" + str + "</b>", err);
setTimeout(function () { WF.hideMessage() }, (sec || 2) * 1000);
}
function getPlainName(item) {
return item.isMainTreeRoot() ? "Home" : item.getNameInPlainText();
}
function sortAndMove(items, reverse) {
WF.hideDialog();
setTimeout(function () {
items.sort(function (a, b) {
var aName = getPlainName(a);
var bName = getPlainName(b);
return reverse ? bName.localeCompare(aName) : aName.localeCompare(bName);
});
WF.editGroup(function () {
items.forEach(function (item, i) {
if (item.getPriority() !== i) WF.moveItems([item], parent, i);
});
});
const dir = reverse ? "Z-A." : "A-Z.";
toastMsg("Sorted " + dir, 1)
}, 50);
}
function showSortDialog(bodyHtml, title, button1, button2) {
const style = '.btnX{font-size:18px;background-color:#49baf2;border:2px solid;border-radius:20px;color:#fff;padding:5px 15px;margin-top:16px;margin-right:16px}.btnX:focus{border-color:#c4c4c4}';
const buttons = '<div><button type="button" class="btnX" id="btn1">' + button1 + '</button><button type="button" class="btnX" id="btn2">' + button2 + '</button></div>';
WF.showAlertDialog('<style>' + htmlEscapeText(style) + '</style><div>' + bodyHtml + '</div>' + buttons, title);
setTimeout(function () {
const btn1 = document.getElementById("btn1");
const btn2 = document.getElementById("btn2");
btn1.focus();
btn1.onclick = function () { sortAndMove(children) };
btn2.onclick = function () { sortAndMove(children, true) };
}, 100);
}
if (WF.currentSearchQuery()) {
return void toastMsg("Sorting is disabled when search is active.", 3, true);
}
const parent = WF.currentItem();
const children = parent.getChildren();
if (children.length < 2) {
return void toastMsg("Nothing to sort.", 3, true);
}
if (children.length > maxChildren) {
return void toastMsg("Sorting more than " + maxChildren + " children upsets the WorkFlowy gods, and has been disabled.", 5, true);
}
const sortInfo = 'Sort <b>' + children.length + '</b> children?';
showSortDialog(sortInfo, getPlainName(parent), 'A-Z', 'Z-A');
}
// Ctrl+Shft+S
document.addEventListener("keydown", function (event) {
if (!event.altKey && event.ctrlKey && event.shiftKey && !event.metaKey && event.keyCode === 83) {
sortMe(400);
event.preventDefault();
}
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment