2017-02-18 01:56:23 -07:00
|
|
|
'use strict';
|
2017-02-17 21:55:19 -07:00
|
|
|
|
2018-12-04 14:32:43 -05:00
|
|
|
define('admin/manage/categories', [
|
|
|
|
|
'translator',
|
|
|
|
|
'benchpress',
|
|
|
|
|
'categorySelector',
|
2020-10-01 14:09:44 -04:00
|
|
|
'api',
|
2020-10-10 23:45:58 -04:00
|
|
|
'Sortable',
|
2020-10-11 19:28:46 -04:00
|
|
|
], function (translator, Benchpress, categorySelector, api, Sortable) {
|
2017-02-17 20:20:42 -07:00
|
|
|
var Categories = {};
|
|
|
|
|
var newCategoryId = -1;
|
|
|
|
|
var sortables;
|
2014-10-08 15:36:47 -04:00
|
|
|
|
2016-10-13 11:43:39 +02:00
|
|
|
Categories.init = function () {
|
2020-07-29 11:57:20 -04:00
|
|
|
Categories.render(ajaxify.data.categories);
|
2014-12-30 12:25:39 -05:00
|
|
|
|
2015-07-17 18:19:51 -04:00
|
|
|
$('button[data-action="create"]').on('click', Categories.throwCreateModal);
|
2015-06-03 18:10:58 -04:00
|
|
|
|
|
|
|
|
// Enable/Disable toggle events
|
2020-07-27 12:39:32 -04:00
|
|
|
$('.categories').on('click', '.category-tools [data-action="toggle"]', function () {
|
2017-02-17 20:20:42 -07:00
|
|
|
var $this = $(this);
|
2020-07-27 12:39:32 -04:00
|
|
|
var cid = $this.attr('data-disable-cid');
|
2017-02-17 20:20:42 -07:00
|
|
|
var parentEl = $this.parents('li[data-cid="' + cid + '"]');
|
|
|
|
|
var disabled = parentEl.hasClass('disabled');
|
2019-02-15 11:17:27 -05:00
|
|
|
var childrenEls = parentEl.find('li[data-cid]');
|
|
|
|
|
var childrenCids = childrenEls.map(function () {
|
2015-10-08 16:05:05 -04:00
|
|
|
return $(this).attr('data-cid');
|
|
|
|
|
}).get();
|
|
|
|
|
|
2019-02-15 11:17:27 -05:00
|
|
|
parentEl.toggleClass('disabled', !disabled);
|
|
|
|
|
childrenEls.toggleClass('disabled', !disabled);
|
|
|
|
|
$this.translateText(!disabled ? '[[admin/manage/categories:enable]]' : '[[admin/manage/categories:disable]]');
|
2020-07-27 12:39:32 -04:00
|
|
|
childrenEls.find('li a[data-action="toggle"]').translateText(!disabled ? '[[admin/manage/categories:enable]]' : '[[admin/manage/categories:disable]]');
|
2019-02-15 11:17:27 -05:00
|
|
|
|
|
|
|
|
Categories.toggle([cid].concat(childrenCids), !disabled);
|
2015-06-03 18:10:58 -04:00
|
|
|
});
|
2017-07-09 16:08:03 -04:00
|
|
|
|
|
|
|
|
$('.categories').on('click', '.toggle', function () {
|
|
|
|
|
var el = $(this);
|
|
|
|
|
el.find('i').toggleClass('fa-minus').toggleClass('fa-plus');
|
|
|
|
|
el.closest('[data-cid]').find('> ul[data-cid]').toggleClass('hidden');
|
|
|
|
|
});
|
2018-02-15 12:46:04 -05:00
|
|
|
|
|
|
|
|
$('#collapse-all').on('click', function () {
|
|
|
|
|
toggleAll(false);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
$('#expand-all').on('click', function () {
|
|
|
|
|
toggleAll(true);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
function toggleAll(expand) {
|
|
|
|
|
var el = $('.categories .toggle');
|
|
|
|
|
el.find('i').toggleClass('fa-minus', expand).toggleClass('fa-plus', !expand);
|
|
|
|
|
el.closest('[data-cid]').find('> ul[data-cid]').toggleClass('hidden', !expand);
|
|
|
|
|
}
|
2020-07-20 13:17:08 -04:00
|
|
|
|
|
|
|
|
$('#category-search').on('keyup', function () {
|
|
|
|
|
searchCategory();
|
|
|
|
|
});
|
2015-03-25 18:08:11 -04:00
|
|
|
};
|
2014-10-08 15:36:47 -04:00
|
|
|
|
2020-07-20 13:17:08 -04:00
|
|
|
function searchCategory() {
|
|
|
|
|
var container = $('#content .categories');
|
|
|
|
|
function revealParents(cid) {
|
|
|
|
|
var parentCid = container.find('li[data-cid="' + cid + '"]').attr('data-parent-cid');
|
|
|
|
|
if (parentCid) {
|
|
|
|
|
container.find('li[data-cid="' + parentCid + '"]').removeClass('hidden');
|
|
|
|
|
revealParents(parentCid);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function revealChildren(cid) {
|
|
|
|
|
var els = container.find('li[data-parent-cid="' + cid + '"]');
|
|
|
|
|
els.each(function (index, el) {
|
|
|
|
|
var $el = $(el);
|
|
|
|
|
$el.removeClass('hidden');
|
|
|
|
|
revealChildren($el.attr('data-cid'));
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var categoryEls = container.find('li[data-cid]');
|
|
|
|
|
var val = $('#category-search').val().toLowerCase();
|
|
|
|
|
var noMatch = true;
|
|
|
|
|
var cids = [];
|
|
|
|
|
categoryEls.each(function () {
|
|
|
|
|
var liEl = $(this);
|
|
|
|
|
var isMatch = liEl.attr('data-name').toLowerCase().indexOf(val) !== -1;
|
|
|
|
|
if (noMatch && isMatch) {
|
|
|
|
|
noMatch = false;
|
|
|
|
|
}
|
|
|
|
|
if (isMatch && val) {
|
|
|
|
|
cids.push(liEl.attr('data-cid'));
|
|
|
|
|
}
|
|
|
|
|
liEl.toggleClass('hidden', !isMatch);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
cids.forEach(function (cid) {
|
|
|
|
|
revealParents(cid);
|
|
|
|
|
revealChildren(cid);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
$('[component="category/no-matches"]').toggleClass('hidden', !noMatch);
|
|
|
|
|
}
|
|
|
|
|
|
2016-10-13 11:43:39 +02:00
|
|
|
Categories.throwCreateModal = function () {
|
2018-12-04 14:32:43 -05:00
|
|
|
socket.emit('categories.getSelectCategories', {}, function (err, categories) {
|
2015-09-20 15:17:57 -04:00
|
|
|
if (err) {
|
|
|
|
|
return app.alertError(err.message);
|
|
|
|
|
}
|
|
|
|
|
|
2018-12-04 14:32:43 -05:00
|
|
|
categories.unshift({
|
|
|
|
|
cid: 0,
|
|
|
|
|
name: '[[admin/manage/categories:parent-category-none]]',
|
|
|
|
|
icon: 'fa-none',
|
|
|
|
|
});
|
2017-08-30 10:50:28 -06:00
|
|
|
Benchpress.parse('admin/partials/categories/create', {
|
2017-02-17 19:31:21 -07:00
|
|
|
categories: categories,
|
2016-10-13 11:43:39 +02:00
|
|
|
}, function (html) {
|
2016-12-09 20:47:28 -07:00
|
|
|
var modal = bootbox.dialog({
|
|
|
|
|
title: '[[admin/manage/categories:alert.create]]',
|
|
|
|
|
message: html,
|
|
|
|
|
buttons: {
|
|
|
|
|
save: {
|
|
|
|
|
label: '[[global:save]]',
|
|
|
|
|
className: 'btn-primary',
|
2017-02-17 19:31:21 -07:00
|
|
|
callback: submit,
|
|
|
|
|
},
|
|
|
|
|
},
|
2016-12-03 22:41:16 -07:00
|
|
|
});
|
2016-12-09 20:47:28 -07:00
|
|
|
|
2018-12-04 14:32:43 -05:00
|
|
|
var parentSelector = categorySelector.init(modal.find('#parentCidGroup [component="category-selector"]'));
|
|
|
|
|
var cloneFromSelector = categorySelector.init(modal.find('#cloneFromCidGroup [component="category-selector"]'));
|
2017-02-18 18:55:33 -07:00
|
|
|
function submit() {
|
|
|
|
|
var formData = modal.find('form').serializeObject();
|
|
|
|
|
formData.description = '';
|
|
|
|
|
formData.icon = 'fa-comments';
|
2018-08-15 20:42:59 -04:00
|
|
|
formData.uid = app.user.uid;
|
2018-12-04 14:32:43 -05:00
|
|
|
formData.parentCid = parentSelector.getSelectedCid();
|
|
|
|
|
formData.cloneFromCid = cloneFromSelector.getSelectedCid();
|
2017-02-18 18:55:33 -07:00
|
|
|
|
|
|
|
|
Categories.create(formData);
|
|
|
|
|
modal.modal('hide');
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-15 20:42:59 -04:00
|
|
|
$('#cloneChildren').on('change', function () {
|
|
|
|
|
var check = $(this);
|
2018-12-04 14:32:43 -05:00
|
|
|
var parentSelect = modal.find('#parentCidGroup [component="category-selector"] .dropdown-toggle');
|
2018-08-15 20:42:59 -04:00
|
|
|
|
|
|
|
|
if (check.prop('checked')) {
|
|
|
|
|
parentSelect.attr('disabled', 'disabled');
|
2018-12-04 14:32:43 -05:00
|
|
|
parentSelector.selectCategory(0);
|
2018-08-15 20:42:59 -04:00
|
|
|
} else {
|
|
|
|
|
parentSelect.removeAttr('disabled');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2016-12-09 20:47:28 -07:00
|
|
|
modal.find('form').on('submit', submit);
|
2015-07-17 18:19:51 -04:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
};
|
|
|
|
|
|
2016-10-13 11:43:39 +02:00
|
|
|
Categories.create = function (payload) {
|
2020-10-16 22:41:38 -04:00
|
|
|
api.post('/categories', payload, function (err, data) {
|
2015-09-20 15:17:57 -04:00
|
|
|
if (err) {
|
2015-07-17 18:19:51 -04:00
|
|
|
return app.alertError(err.message);
|
|
|
|
|
}
|
2014-10-08 15:36:47 -04:00
|
|
|
|
2015-07-17 18:19:51 -04:00
|
|
|
app.alert({
|
|
|
|
|
alert_id: 'category_created',
|
2016-12-09 20:47:28 -07:00
|
|
|
title: '[[admin/manage/categories:alert.created]]',
|
|
|
|
|
message: '[[admin/manage/categories:alert.create-success]]',
|
2015-07-17 18:19:51 -04:00
|
|
|
type: 'success',
|
2017-02-17 19:31:21 -07:00
|
|
|
timeout: 2000,
|
2014-10-08 15:36:47 -04:00
|
|
|
});
|
2015-07-17 18:19:51 -04:00
|
|
|
|
|
|
|
|
ajaxify.go('admin/manage/categories/' + data.cid);
|
2015-03-25 18:08:11 -04:00
|
|
|
});
|
2014-10-08 15:36:47 -04:00
|
|
|
};
|
|
|
|
|
|
2016-10-25 21:34:47 +02:00
|
|
|
Categories.render = function (categories) {
|
2015-06-04 14:24:33 -04:00
|
|
|
var container = $('.categories');
|
|
|
|
|
|
2015-09-20 15:17:57 -04:00
|
|
|
if (!categories || !categories.length) {
|
2016-12-09 20:47:28 -07:00
|
|
|
translator.translate('[[admin/manage/categories:alert.none-active]]', function (text) {
|
|
|
|
|
$('<div></div>')
|
|
|
|
|
.addClass('alert alert-info text-center')
|
|
|
|
|
.text(text)
|
|
|
|
|
.appendTo(container);
|
|
|
|
|
});
|
2015-06-04 14:24:33 -04:00
|
|
|
} else {
|
|
|
|
|
sortables = {};
|
|
|
|
|
renderList(categories, container, 0);
|
|
|
|
|
}
|
2015-05-30 18:44:31 +03:00
|
|
|
};
|
|
|
|
|
|
2016-10-13 11:43:39 +02:00
|
|
|
Categories.toggle = function (cids, disabled) {
|
2020-10-14 10:02:02 -04:00
|
|
|
Promise.all(cids.map(cid => api.put('/categories/' + cid, {
|
|
|
|
|
disabled: disabled ? 1 : 0,
|
|
|
|
|
})));
|
2015-09-20 15:17:57 -04:00
|
|
|
};
|
2015-06-03 18:10:58 -04:00
|
|
|
|
2015-09-20 15:17:57 -04:00
|
|
|
function itemDidAdd(e) {
|
2015-06-04 14:24:33 -04:00
|
|
|
newCategoryId = e.to.dataset.cid;
|
2015-05-31 10:49:03 +03:00
|
|
|
}
|
|
|
|
|
|
2015-09-28 16:09:33 -04:00
|
|
|
function itemDragDidEnd(e) {
|
2017-02-23 17:29:08 -07:00
|
|
|
var isCategoryUpdate = parseInt(newCategoryId, 10) !== -1;
|
2015-09-28 16:09:33 -04:00
|
|
|
|
2017-02-18 01:25:46 -07:00
|
|
|
// Update needed?
|
2017-02-23 17:29:08 -07:00
|
|
|
if ((e.newIndex != null && parseInt(e.oldIndex, 10) !== parseInt(e.newIndex, 10)) || isCategoryUpdate) {
|
2017-02-17 20:20:42 -07:00
|
|
|
var parentCategory = isCategoryUpdate ? sortables[newCategoryId] : sortables[e.from.dataset.cid];
|
|
|
|
|
var modified = {};
|
|
|
|
|
var i = 0;
|
|
|
|
|
var list = parentCategory.toArray();
|
|
|
|
|
var len = list.length;
|
2015-06-04 14:24:33 -04:00
|
|
|
|
2017-02-18 01:52:56 -07:00
|
|
|
for (i; i < len; i += 1) {
|
2015-06-04 14:24:33 -04:00
|
|
|
modified[list[i]] = {
|
2017-02-17 19:31:21 -07:00
|
|
|
order: (i + 1),
|
2015-09-20 15:17:57 -04:00
|
|
|
};
|
2015-06-04 14:24:33 -04:00
|
|
|
}
|
|
|
|
|
|
2016-10-25 21:34:47 +02:00
|
|
|
if (isCategoryUpdate) {
|
2015-09-20 15:17:57 -04:00
|
|
|
modified[e.item.dataset.cid].parentCid = newCategoryId;
|
2015-06-04 14:24:33 -04:00
|
|
|
}
|
|
|
|
|
|
2015-09-20 15:17:57 -04:00
|
|
|
newCategoryId = -1;
|
2020-04-02 20:44:04 -04:00
|
|
|
|
2020-10-14 10:02:02 -04:00
|
|
|
Object.keys(modified).map(cid => api.put('/categories/' + cid, modified[cid]));
|
2015-06-04 14:24:33 -04:00
|
|
|
}
|
2015-05-31 10:49:03 +03:00
|
|
|
}
|
|
|
|
|
|
2015-06-04 14:24:33 -04:00
|
|
|
/**
|
|
|
|
|
* Render categories - recursively
|
|
|
|
|
*
|
|
|
|
|
* @param categories {array} categories tree
|
|
|
|
|
* @param level {number} current sub-level of rendering
|
|
|
|
|
* @param container {object} parent jquery element for the list
|
|
|
|
|
* @param parentId {number} parent category identifier
|
|
|
|
|
*/
|
2016-10-25 21:34:47 +02:00
|
|
|
function renderList(categories, container, parentId) {
|
2016-03-14 12:57:45 -04:00
|
|
|
// Translate category names if needed
|
|
|
|
|
var count = 0;
|
2016-10-13 11:43:39 +02:00
|
|
|
categories.forEach(function (category, idx, parent) {
|
|
|
|
|
translator.translate(category.name, function (translated) {
|
2016-03-14 12:57:45 -04:00
|
|
|
if (category.name !== translated) {
|
|
|
|
|
category.name = translated;
|
|
|
|
|
}
|
2017-02-18 01:12:18 -07:00
|
|
|
count += 1;
|
2015-06-03 18:10:58 -04:00
|
|
|
|
2016-03-14 12:57:45 -04:00
|
|
|
if (count === parent.length) {
|
|
|
|
|
continueRender();
|
|
|
|
|
}
|
2015-05-30 18:44:31 +03:00
|
|
|
});
|
|
|
|
|
});
|
2016-03-14 12:57:45 -04:00
|
|
|
|
2016-04-25 19:28:28 +03:00
|
|
|
if (!categories.length) {
|
|
|
|
|
continueRender();
|
|
|
|
|
}
|
|
|
|
|
|
2016-03-14 12:57:45 -04:00
|
|
|
function continueRender() {
|
2017-08-30 10:50:28 -06:00
|
|
|
Benchpress.parse('admin/partials/categories/category-rows', {
|
2016-03-14 12:57:45 -04:00
|
|
|
cid: parentId,
|
2017-02-17 19:31:21 -07:00
|
|
|
categories: categories,
|
2016-10-13 11:43:39 +02:00
|
|
|
}, function (html) {
|
2016-12-03 22:41:16 -07:00
|
|
|
translator.translate(html, function (html) {
|
|
|
|
|
container.append(html);
|
2016-03-14 12:57:45 -04:00
|
|
|
|
2016-12-03 22:41:16 -07:00
|
|
|
// Handle and children categories in this level have
|
2017-02-18 01:52:56 -07:00
|
|
|
for (var x = 0, numCategories = categories.length; x < numCategories; x += 1) {
|
2016-12-03 22:41:16 -07:00
|
|
|
renderList(categories[x].children, $('li[data-cid="' + categories[x].cid + '"]'), categories[x].cid);
|
|
|
|
|
}
|
2016-03-14 12:57:45 -04:00
|
|
|
|
2016-12-03 22:41:16 -07:00
|
|
|
// Make list sortable
|
|
|
|
|
sortables[parentId] = Sortable.create($('ul[data-cid="' + parentId + '"]')[0], {
|
|
|
|
|
group: 'cross-categories',
|
|
|
|
|
animation: 150,
|
2020-07-27 16:07:52 -04:00
|
|
|
handle: '.information',
|
2016-12-03 22:41:16 -07:00
|
|
|
dataIdAttr: 'data-cid',
|
2017-02-18 01:56:23 -07:00
|
|
|
ghostClass: 'placeholder',
|
2016-12-03 22:41:16 -07:00
|
|
|
onAdd: itemDidAdd,
|
2017-02-17 19:31:21 -07:00
|
|
|
onEnd: itemDragDidEnd,
|
2016-12-03 22:41:16 -07:00
|
|
|
});
|
2016-03-14 12:57:45 -04:00
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
}
|
2015-06-04 14:24:33 -04:00
|
|
|
}
|
2015-05-30 18:44:31 +03:00
|
|
|
|
2014-10-08 15:36:47 -04:00
|
|
|
return Categories;
|
2017-02-18 02:30:48 -07:00
|
|
|
});
|