Add multisort to header & labels
This commit is contained in:
parent
9368c27990
commit
d379e5f34a
|
@ -1253,37 +1253,13 @@
|
||||||
"shortcutsNote": {
|
"shortcutsNote": {
|
||||||
"message": "Define keyboard shortcuts"
|
"message": "Define keyboard shortcuts"
|
||||||
},
|
},
|
||||||
"sortDateNewestFirst": {
|
|
||||||
"message": "newest first",
|
|
||||||
"description": "Text added to indicate that sorting a date would add the newest entries at the top"
|
|
||||||
},
|
|
||||||
"sortDateOldestFirst": {
|
|
||||||
"message": "oldest first",
|
|
||||||
"description": "Text added to indicate that sorting a date would add the oldest entries at the top"
|
|
||||||
},
|
|
||||||
"sortHeader": {
|
"sortHeader": {
|
||||||
"message": "Sort",
|
"message": "Sort",
|
||||||
"description": "Title of sort column, indicating that the style can be manually sorted by dragging & dropping"
|
"description": "Title of sort column, indicating that the style can be manually sorted by dragging & dropping"
|
||||||
},
|
},
|
||||||
"sortLabel": {
|
"sortLabel": {
|
||||||
"message": "Select a sort to apply to the installed styles",
|
"message": "Click to sort; Shift + click to sort multiple columns",
|
||||||
"description": "Title on the sort select to indicate it is used for sorting entries"
|
"description": "Title added to links in the manager page header to inform the user on how to sort the columns"
|
||||||
},
|
|
||||||
"sortLabelTitleAsc": {
|
|
||||||
"message": "Title Ascending",
|
|
||||||
"description": "Text added to option group to indicate a block of options that apply a title ascending (A to Z) sort"
|
|
||||||
},
|
|
||||||
"sortLabelTitleDesc": {
|
|
||||||
"message": "Title Descending",
|
|
||||||
"description": "Text added to option group to indicate a block of options that apply a title descending (Z to A) sort"
|
|
||||||
},
|
|
||||||
"sortStylesHelp": {
|
|
||||||
"message": "Choose the type of sort to apply to the installed entries from within the sort dropdown. The default setting applies an ascending sort (A to Z) to the entry titles. Sorts within the \"Title Descending\" group will apply a descending sort (Z to A) to the title.\nThere are other presets that will allow sorting the entries by multiple criteria. Think of this like sorting a table with multiple columns and each category in a select (between the plus signs) represents a column, or group.\nFor example, if the setting is \"Enabled (first) + Title\", the entries would sort so that all the enabled entries are sorted to the top of the list, then an entry title ascending sort (A to Z) is applied to both the enabled and disabled entries separately.",
|
|
||||||
"description": "Text in the minihelp displayed when clicking (i) icon to the right of the sort input field on the Manage styles page"
|
|
||||||
},
|
|
||||||
"sortStylesHelpTitle": {
|
|
||||||
"message": "Sort contents",
|
|
||||||
"description": "Label for the sort info popup on the Manage styles page"
|
|
||||||
},
|
},
|
||||||
"styleBadRegexp": {
|
"styleBadRegexp": {
|
||||||
"message": "Regexp is invalid.",
|
"message": "Regexp is invalid.",
|
||||||
|
|
15
manage.html
15
manage.html
|
@ -364,7 +364,6 @@
|
||||||
<button id="manage-shortcuts-button"></button>
|
<button id="manage-shortcuts-button"></button>
|
||||||
<button id="sorter-help"></button>
|
<button id="sorter-help"></button>
|
||||||
<input id="manage.newUI" type="checkbox">
|
<input id="manage.newUI" type="checkbox">
|
||||||
<select id="manage.newUI.sort"></select>
|
|
||||||
<input id="manage.newUI.faviconsGray" type="checkbox">
|
<input id="manage.newUI.faviconsGray" type="checkbox">
|
||||||
<input id="manage.newUI.targets" type="number" min="1" max="100" value="3">
|
<input id="manage.newUI.targets" type="number" min="1" max="100" value="3">
|
||||||
<input id="manage.newUI.favicons" type="checkbox">
|
<input id="manage.newUI.favicons" type="checkbox">
|
||||||
|
@ -381,13 +380,15 @@
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="entry-col header-id">#</div>
|
<a href="#" class="entry-col sortable header-id" data-type="order" i18n-title="sortLabel">#</a>
|
||||||
<div class="entry-col header-state center-text" i18n-text="genericEnabledLabel"></div>
|
<a href="#" class="entry-col sortable header-state center-text" i18n-text="genericEnabledLabel" i18n-title="sortLabel" data-type="disabled"></a>
|
||||||
<div class="entry-col header-name" i18n-text="genericName"></div>
|
<div class="entry-col header-name">
|
||||||
|
<a href="#" class="sortable" i18n-text="genericName" i18n-title="sortLabel" data-type="title"></a>
|
||||||
|
</div>
|
||||||
<div class="entry-col header-actions" i18n-text="optionsActions"></div>
|
<div class="entry-col header-actions" i18n-text="optionsActions"></div>
|
||||||
<div class="entry-col header-sort center-text" i18n-text="sortHeader"></div>
|
<div class="entry-col header-sort center-text" i18n-text="sortHeader" i18n-title="sortOrderLabel"></div>
|
||||||
<div class="entry-col header-version">v#</div>
|
<a href="#" class="entry-col sortable header-version" i18n-title="sortLabel" data-type="version">v#</a>
|
||||||
<div class="entry-col header-last-update center-text" i18n-text="searchResultUpdated"></div>
|
<a href="#" class="entry-col sortable header-last-update center-text" i18n-text="searchResultUpdated" i18n-title="sortLabel" data-type="dateUpdated"></a>
|
||||||
<div class="entry-col header-applies-to" i18n-text="appliesLabel"></div>
|
<div class="entry-col header-applies-to" i18n-text="appliesLabel"></div>
|
||||||
</header>
|
</header>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -128,7 +128,8 @@ Object.assign(handleEvent, {
|
||||||
'.update': 'update',
|
'.update': 'update',
|
||||||
'.entry-delete': 'delete',
|
'.entry-delete': 'delete',
|
||||||
'.entry-configure-usercss': 'config',
|
'.entry-configure-usercss': 'config',
|
||||||
'#toggle-actions': 'toggleBulkActions'
|
'#toggle-actions': 'toggleBulkActions',
|
||||||
|
'.sortable': 'updateSort'
|
||||||
},
|
},
|
||||||
|
|
||||||
entryClicked(event) {
|
entryClicked(event) {
|
||||||
|
@ -204,6 +205,12 @@ Object.assign(handleEvent, {
|
||||||
API[json.usercssData ? 'installUsercss' : 'installStyle'](json);
|
API[json.usercssData ? 'installUsercss' : 'installStyle'](json);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
updateSort(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
sorter.updateSort(event);
|
||||||
|
removeSelection();
|
||||||
|
},
|
||||||
|
|
||||||
delete(event, entry) {
|
delete(event, entry) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const id = entry.styleId;
|
const id = entry.styleId;
|
||||||
|
@ -427,6 +434,17 @@ function updateBulkFilters({target}) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function removeSelection() {
|
||||||
|
const sel = window.getSelection ? window.getSelection() : document.selection;
|
||||||
|
if (sel) {
|
||||||
|
if (sel.removeAllRanges) {
|
||||||
|
sel.removeAllRanges();
|
||||||
|
} else if (sel.empty) {
|
||||||
|
sel.empty();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function lazyLoad() {
|
function lazyLoad() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$$('link[data-href]').forEach(link => {
|
$$('link[data-href]').forEach(link => {
|
||||||
|
|
|
@ -46,6 +46,7 @@ const UI = {
|
||||||
},
|
},
|
||||||
|
|
||||||
showStyles: (styles = [], matchUrlIds) => {
|
showStyles: (styles = [], matchUrlIds) => {
|
||||||
|
UI.addHeaderLabels();
|
||||||
const sorted = sorter.sort({
|
const sorted = sorter.sort({
|
||||||
styles: styles.map(style => ({
|
styles: styles.map(style => ({
|
||||||
style,
|
style,
|
||||||
|
@ -275,6 +276,23 @@ const UI = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
addHeaderLabels: () => {
|
||||||
|
const header = $('.header-name');
|
||||||
|
const labels = document.createElement('span');
|
||||||
|
const label = document.createElement('a');
|
||||||
|
labels.className = 'header-labels';
|
||||||
|
label.className = 'header-label sortable';
|
||||||
|
label.title = t('sortLabel');
|
||||||
|
label.href = '#';
|
||||||
|
Object.keys(UI.labels).forEach(item => {
|
||||||
|
const newLabel = label.cloneNode(true);
|
||||||
|
newLabel.dataset.type = item;
|
||||||
|
newLabel.textContent = UI.labels[item].text;
|
||||||
|
labels.appendChild(newLabel);
|
||||||
|
});
|
||||||
|
header.appendChild(labels);
|
||||||
|
},
|
||||||
|
|
||||||
addLabels: entry => {
|
addLabels: entry => {
|
||||||
const style = entry.styleMeta;
|
const style = entry.styleMeta;
|
||||||
const container = $('.entry-labels', entry);
|
const container = $('.entry-labels', entry);
|
||||||
|
@ -285,7 +303,7 @@ const UI = {
|
||||||
Object.keys(UI.labels).forEach(item => {
|
Object.keys(UI.labels).forEach(item => {
|
||||||
if (UI.labels[item].is({entry, style})) {
|
if (UI.labels[item].is({entry, style})) {
|
||||||
const newLabel = label.cloneNode(true);
|
const newLabel = label.cloneNode(true);
|
||||||
newLabel.dataset.label = item;
|
newLabel.dataset.type = item;
|
||||||
newLabel.textContent = UI.labels[item].text;
|
newLabel.textContent = UI.labels[item].text;
|
||||||
labels.appendChild(newLabel);
|
labels.appendChild(newLabel);
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,6 +211,31 @@ a:hover {
|
||||||
margin-right: 8px;
|
margin-right: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.entry-header:not(.sortable) {
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sortable {
|
||||||
|
align-self: center;
|
||||||
|
cursor: pointer;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sortable[data-sort-dir="asc"]:after,
|
||||||
|
.sortable[data-sort-dir="desc"]:after {
|
||||||
|
font-size: 16px;
|
||||||
|
position: relative;
|
||||||
|
top: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.sortable[data-sort-dir="asc"]:after {
|
||||||
|
content: '▴';
|
||||||
|
}
|
||||||
|
|
||||||
|
.sortable[data-sort-dir="desc"]:after {
|
||||||
|
content: '▾';
|
||||||
|
}
|
||||||
|
|
||||||
.entry-sort {
|
.entry-sort {
|
||||||
cursor: move;
|
cursor: move;
|
||||||
}
|
}
|
||||||
|
@ -267,6 +292,12 @@ body.dragging .entry:not(.dragging) .entry-name:before {
|
||||||
fill: #000;
|
fill: #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.header-labels {
|
||||||
|
margin-left: 16px;
|
||||||
|
justify-content: center
|
||||||
|
}
|
||||||
|
|
||||||
|
.header-label,
|
||||||
.entry-label {
|
.entry-label {
|
||||||
padding: 2px 4px;
|
padding: 2px 4px;
|
||||||
margin-left: 2px;
|
margin-left: 2px;
|
||||||
|
@ -275,13 +306,15 @@ body.dragging .entry:not(.dragging) .entry-name:before {
|
||||||
text-transform: lowercase;
|
text-transform: lowercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.entry-label[data-label="usercss"] {
|
.header-label[data-type="usercss"],
|
||||||
|
.entry-label[data-type="usercss"] {
|
||||||
background-color: hsla(180, 100%, 20%, 1);
|
background-color: hsla(180, 100%, 20%, 1);
|
||||||
color: white;
|
color: white;
|
||||||
text-transform: lowercase;
|
text-transform: lowercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.entry-label[data-label="disabled"] {
|
.header-label[data-type="disabled"],
|
||||||
|
.entry-label[data-type="disabled"] {
|
||||||
background: rgba(128, 128, 128, .2);
|
background: rgba(128, 128, 128, .2);
|
||||||
color: #222;
|
color: #222;
|
||||||
}
|
}
|
||||||
|
|
190
manage/sort.js
190
manage/sort.js
|
@ -1,9 +1,18 @@
|
||||||
/* global installed messageBox t $ $create prefs */
|
/* global installed t $ prefs */
|
||||||
/* exported sorter */
|
/* exported sorter */
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
const sorter = (() => {
|
const sorter = (() => {
|
||||||
|
|
||||||
|
// Set up for only one column
|
||||||
|
const defaultSort = 'title,asc';
|
||||||
|
|
||||||
|
const sortOrder = [
|
||||||
|
'asc',
|
||||||
|
'desc',
|
||||||
|
'' // unsorted
|
||||||
|
];
|
||||||
|
|
||||||
const sorterType = {
|
const sorterType = {
|
||||||
alpha: (a, b) => a < b ? -1 : a === b ? 0 : 1,
|
alpha: (a, b) => a < b ? -1 : a === b ? 0 : 1,
|
||||||
number: (a, b) => (a || 0) - (b || 0),
|
number: (a, b) => (a || 0) - (b || 0),
|
||||||
|
@ -15,115 +24,130 @@ const sorter = (() => {
|
||||||
parse: ({name}) => name,
|
parse: ({name}) => name,
|
||||||
sorter: sorterType.alpha
|
sorter: sorterType.alpha
|
||||||
},
|
},
|
||||||
|
order: {
|
||||||
|
text: '#',
|
||||||
|
parse: ({style}) => style.id,
|
||||||
|
sorter: sorterType.number,
|
||||||
|
},
|
||||||
usercss: {
|
usercss: {
|
||||||
text: 'Usercss',
|
text: 'Usercss',
|
||||||
parse: ({style}) => style.usercssData ? 0 : 1,
|
parse: ({style}) => style.usercssData ? 0 : 1,
|
||||||
sorter: sorterType.number
|
sorter: sorterType.number
|
||||||
},
|
},
|
||||||
disabled: {
|
disabled: {
|
||||||
text: '', // added as either "enabled" or "disabled" by the addOptions function
|
text: t('genericDisabledLabel'), // added as either "enabled" or "disabled" by the addOptions function
|
||||||
parse: ({style}) => style.enabled ? 1 : 0,
|
parse: ({style}) => style.enabled ? 0 : 1,
|
||||||
|
sorter: sorterType.number
|
||||||
|
},
|
||||||
|
version: {
|
||||||
|
text: '#',
|
||||||
|
parse: ({style}) => (style.usercssData && style.usercssData.version || '')
|
||||||
|
.split(/[.-]/)
|
||||||
|
.splice(0, 3) // ignore extra labels; e.g. 1.2.3-beta.1
|
||||||
|
.map(n => n ? n.padStart(4, '0') : '')
|
||||||
|
.join(''),
|
||||||
sorter: sorterType.number
|
sorter: sorterType.number
|
||||||
},
|
},
|
||||||
dateInstalled: {
|
dateInstalled: {
|
||||||
text: t('dateInstalled'),
|
text: t('dateInstalled'),
|
||||||
parse: ({style}) => style.installDate,
|
parse: ({style}) => style.installDate || '',
|
||||||
sorter: sorterType.number
|
sorter: sorterType.number
|
||||||
},
|
},
|
||||||
dateUpdated: {
|
dateUpdated: {
|
||||||
text: t('dateUpdated'),
|
text: t('dateUpdated'),
|
||||||
parse: ({style}) => style.updateDate,
|
parse: ({style}) => style.updateDate || '',
|
||||||
sorter: sorterType.number
|
sorter: sorterType.number
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Adding (assumed) most commonly used ('title,asc' should always be first)
|
|
||||||
// whitespace before & after the comma is ignored
|
|
||||||
const selectOptions = [
|
|
||||||
'{groupAsc}',
|
|
||||||
'title,asc',
|
|
||||||
'dateInstalled,desc, title,asc',
|
|
||||||
'dateInstalled,asc, title,asc',
|
|
||||||
'dateUpdated,desc, title,asc',
|
|
||||||
'dateUpdated,asc, title,asc',
|
|
||||||
'usercss,asc, title,asc',
|
|
||||||
'usercss,desc, title,asc',
|
|
||||||
'disabled,asc, title,asc',
|
|
||||||
'disabled,desc, title,asc',
|
|
||||||
'disabled,desc, usercss,asc, title,asc',
|
|
||||||
'{groupDesc}',
|
|
||||||
'title,desc',
|
|
||||||
'usercss,asc, title,desc',
|
|
||||||
'usercss,desc, title,desc',
|
|
||||||
'disabled,desc, title,desc',
|
|
||||||
'disabled,desc, usercss,asc, title,desc'
|
|
||||||
];
|
|
||||||
|
|
||||||
const splitRegex = /\s*,\s*/;
|
const splitRegex = /\s*,\s*/;
|
||||||
|
const whitespace = /\s+/g;
|
||||||
|
|
||||||
let columns = 1;
|
let columns = 1;
|
||||||
|
let lastSort;
|
||||||
function addOptions() {
|
|
||||||
let container;
|
|
||||||
const select = $('#manage.newUI.sort');
|
|
||||||
const renderBin = document.createDocumentFragment();
|
|
||||||
const option = $create('option');
|
|
||||||
const optgroup = $create('optgroup');
|
|
||||||
const meta = {
|
|
||||||
desc: ' \u21E9',
|
|
||||||
enabled: t('genericEnabledLabel'),
|
|
||||||
disabled: t('genericDisabledLabel'),
|
|
||||||
dateNew: ` (${t('sortDateNewestFirst')})`,
|
|
||||||
dateOld: ` (${t('sortDateOldestFirst')})`,
|
|
||||||
groupAsc: t('sortLabelTitleAsc'),
|
|
||||||
groupDesc: t('sortLabelTitleDesc')
|
|
||||||
};
|
|
||||||
const optgroupRegex = /\{\w+\}/;
|
|
||||||
selectOptions.forEach(sort => {
|
|
||||||
if (optgroupRegex.test(sort)) {
|
|
||||||
if (container) {
|
|
||||||
renderBin.appendChild(container);
|
|
||||||
}
|
|
||||||
container = optgroup.cloneNode();
|
|
||||||
container.label = meta[sort.substring(1, sort.length - 1)];
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
let lastTag = '';
|
|
||||||
const opt = option.cloneNode();
|
|
||||||
opt.textContent = sort.split(splitRegex).reduce((acc, val) => {
|
|
||||||
if (tagData[val]) {
|
|
||||||
lastTag = val;
|
|
||||||
return acc + (acc !== '' ? ' + ' : '') + tagData[val].text;
|
|
||||||
}
|
|
||||||
if (lastTag.indexOf('date') > -1) return acc + meta[val === 'desc' ? 'dateNew' : 'dateOld'];
|
|
||||||
if (lastTag === 'disabled') return acc + meta[val === 'desc' ? 'enabled' : 'disabled'];
|
|
||||||
return acc + (meta[val] || '');
|
|
||||||
}, '');
|
|
||||||
opt.value = sort;
|
|
||||||
container.appendChild(opt);
|
|
||||||
});
|
|
||||||
renderBin.appendChild(container);
|
|
||||||
select.appendChild(renderBin);
|
|
||||||
select.value = prefs.get('manage.newUI.sort');
|
|
||||||
}
|
|
||||||
|
|
||||||
function sort({styles}) {
|
function sort({styles}) {
|
||||||
const sortBy = prefs.get('manage.newUI.sort').split(splitRegex);
|
let sortBy = prefs.get('manage.newUI.sort').replace(whitespace, '');
|
||||||
|
if (lastSort === sortBy) {
|
||||||
|
return styles;
|
||||||
|
}
|
||||||
|
sortBy = sortBy.split(splitRegex);
|
||||||
|
if (sortBy.join('') === '') {
|
||||||
|
sortBy = defaultSort.split(splitRegex);
|
||||||
|
}
|
||||||
|
updateHeaders(sortBy);
|
||||||
const len = sortBy.length;
|
const len = sortBy.length;
|
||||||
return styles.sort((a, b) => {
|
return styles.sort((a, b) => {
|
||||||
let types, direction;
|
let types, direction, x, y;
|
||||||
let result = 0;
|
let result = 0;
|
||||||
let index = 0;
|
let index = 0;
|
||||||
// multi-sort
|
// multi-sort
|
||||||
while (result === 0 && index < len) {
|
while (result === 0 && index < len) {
|
||||||
types = tagData[sortBy[index++]];
|
types = tagData[sortBy[index++]];
|
||||||
|
x = types.parse(a);
|
||||||
|
y = types.parse(b);
|
||||||
|
// sort empty values to the bottom
|
||||||
|
if (x === '') {
|
||||||
|
result = 1;
|
||||||
|
} else if (y === '') {
|
||||||
|
result = -1;
|
||||||
|
} else {
|
||||||
direction = sortBy[index++] === 'asc' ? 1 : -1;
|
direction = sortBy[index++] === 'asc' ? 1 : -1;
|
||||||
result = types.sorter(types.parse(a), types.parse(b)) * direction;
|
result = types.sorter(x, y) * direction;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update default sort on init & when all other columns are unsorted
|
||||||
|
function updateHeaders(sortBy) {
|
||||||
|
let header, sortDir;
|
||||||
|
let i = 0;
|
||||||
|
const len = sortBy.length;
|
||||||
|
while (i < len) {
|
||||||
|
header = $(`.entry-header [data-type="${sortBy[i++]}"]`);
|
||||||
|
sortDir = sortBy[i++];
|
||||||
|
if (header) {
|
||||||
|
header.dataset.sortDir = sortDir;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSort(event) {
|
||||||
|
const sortables = $$('.entry-header .sortable');
|
||||||
|
const elm = event.target;
|
||||||
|
// default sort column only allows asc, desc; not unsorted
|
||||||
|
const len = sortOrder.length - (elm.dataset.type === defaultSort.split(splitRegex)[0] ? 1 : 0);
|
||||||
|
let index = (sortOrder.indexOf(elm.dataset.sortDir) + 1) % len;
|
||||||
|
// shift key for multi-column sorting
|
||||||
|
if (!event.shiftKey) {
|
||||||
|
sortables.forEach(el => {
|
||||||
|
el.dataset.sortDir = '';
|
||||||
|
el.dataset.timestamp = '';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
elm.dataset.sortDir = sortOrder[index];
|
||||||
|
elm.dataset.timestamp = Date.now();
|
||||||
|
|
||||||
|
const newSort = sortables
|
||||||
|
.filter(el => el.dataset.sortDir !== '')
|
||||||
|
.reduce((acc, el) => {
|
||||||
|
const {sortDir, type, timestamp = new Date()} = el.dataset;
|
||||||
|
if (sortDir) {
|
||||||
|
acc.push({sortDir, type, timestamp: parseFloat(timestamp)});
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, [])
|
||||||
|
.sort((a, b) => a.timestamp - b.timestamp)
|
||||||
|
.reduce((acc, item) => {
|
||||||
|
acc = acc.concat(item.type, item.sortDir);
|
||||||
|
return acc;
|
||||||
|
}, [])
|
||||||
|
.join(',');
|
||||||
|
prefs.set('manage.newUI.sort', newSort || defaultSort);
|
||||||
|
}
|
||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
if (!installed) return;
|
if (!installed) return;
|
||||||
const current = [...installed.children];
|
const current = [...installed.children];
|
||||||
|
@ -176,25 +200,11 @@ const sorter = (() => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function showHelp(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
messageBox({
|
|
||||||
className: 'help-text',
|
|
||||||
title: t('sortStylesHelpTitle'),
|
|
||||||
contents:
|
|
||||||
$create('div',
|
|
||||||
t('sortStylesHelp').split('\n').map(line =>
|
|
||||||
$create('p', line))),
|
|
||||||
buttons: [t('confirmOK')],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
prefs.subscribe(['manage.newUI.sort'], update);
|
prefs.subscribe(['manage.newUI.sort'], update);
|
||||||
$('#sorter-help').onclick = showHelp;
|
// addOptions();
|
||||||
addOptions();
|
|
||||||
updateColumnCount();
|
updateColumnCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
return {init, update, sort, updateStripes};
|
return {init, update, sort, updateSort, updateStripes};
|
||||||
})();
|
})();
|
||||||
|
|
Loading…
Reference in New Issue
Block a user