563 lines
20 KiB
JavaScript
Vendored
563 lines
20 KiB
JavaScript
Vendored
var IeBomTreeEditor = (function () {
|
|
var $root, bomId, storeUrl, moveUrl, updateBase, deleteBase;
|
|
var applyTemplateUrl, saveTemplateUrl, deleteTemplateUrl, duplicateUrl;
|
|
var selectedParentId = null, selectedParentName = '';
|
|
var selectedLineId = null;
|
|
var clipboardBranchId = null, clipboardBranchName = '';
|
|
var THEME_STORAGE_KEY = 'ie_bom_tree_theme';
|
|
var THEME_DEFAULT_KEY = 'ie_bom_tree_theme_default';
|
|
var COLLAPSE_STORAGE_KEY = 'ie_bom_tree_collapsed';
|
|
var CLIPBOARD_STORAGE_KEY = 'ie_bom_tree_clipboard';
|
|
var themeLabels = {};
|
|
var defaultThemeId = '18';
|
|
|
|
function init() {
|
|
$root = $('#ie_structure_editor');
|
|
if (!$root.length) return;
|
|
|
|
bomId = $root.data('bom-id');
|
|
storeUrl = $root.data('store-url');
|
|
moveUrl = $root.data('move-url');
|
|
updateBase = $root.data('update-url');
|
|
deleteBase = $root.data('delete-url');
|
|
applyTemplateUrl = $root.data('apply-template-url');
|
|
saveTemplateUrl = $root.data('save-template-url');
|
|
deleteTemplateUrl = $root.data('delete-template-url');
|
|
duplicateUrl = $root.data('duplicate-url');
|
|
|
|
$('#ie_bom_nestable').nestable({ maxDepth: 20, group: 1 });
|
|
|
|
// Prevent drag when clicking action buttons and toggles
|
|
$root.on('mousedown click', '.ie-node-actions .btn, .ie-node-actions, .ie-btn-toggle-branch', function (e) {
|
|
e.stopPropagation();
|
|
});
|
|
|
|
$('#ie_save_tree').on('click', saveTree);
|
|
$('#ie_add_root_node').on('click', function () {
|
|
resetForm(null);
|
|
setTemplateParent(null, '');
|
|
});
|
|
$('#ie_node_form').on('submit', submitNode);
|
|
|
|
$root.on('click', '.ie-btn-add-child', function () {
|
|
var id = $(this).data('id');
|
|
var name = $(this).data('name') || '';
|
|
resetForm(id);
|
|
setTemplateParent(id, name);
|
|
});
|
|
$root.on('click', '.ie-btn-edit-node', function () {
|
|
var id = $(this).data('id');
|
|
loadNodeForEdit(id);
|
|
selectedLineId = id;
|
|
});
|
|
$root.on('click', '.ie-btn-delete-node', function () {
|
|
deleteNode($(this).data('id'));
|
|
});
|
|
$root.on('click', '.ie-btn-select-parent', function () {
|
|
setTemplateParent($(this).data('id'), $(this).data('name') || '');
|
|
selectedLineId = $(this).data('id');
|
|
toastr.info('والد الگو: ' + ($(this).data('name') || ''));
|
|
});
|
|
$root.on('click', '.ie-btn-bulk-child', function () {
|
|
var id = $(this).data('id');
|
|
var name = $(this).data('name') || '';
|
|
setTemplateParent(id, name);
|
|
selectedLineId = id;
|
|
$('#ie_builtin_template').val('air_section_children').trigger('change');
|
|
$('html, body').animate({ scrollTop: $('#ie_apply_builtin_template').offset().top - 80 }, 300);
|
|
});
|
|
|
|
$('#ie_builtin_template').on('change', function () {
|
|
var desc = $(this).find(':selected').data('desc') || '';
|
|
$('#ie_template_desc').text(desc);
|
|
});
|
|
|
|
$('#ie_apply_builtin_template').on('click', function () {
|
|
var key = $('#ie_builtin_template').val();
|
|
if (!key) {
|
|
toastr.warning('یک الگوی آماده انتخاب کنید');
|
|
return;
|
|
}
|
|
applyTemplate(key);
|
|
});
|
|
|
|
$('#ie_apply_saved_template').on('click', function () {
|
|
var key = $('#ie_saved_template').val();
|
|
if (!key) {
|
|
toastr.warning('الگوی ذخیرهشدهای انتخاب نشده');
|
|
return;
|
|
}
|
|
applyTemplate(key);
|
|
});
|
|
|
|
$('#ie_delete_saved_template').on('click', deleteSavedTemplate);
|
|
$('#ie_save_template_btn').on('click', saveTemplate);
|
|
|
|
$root.on('click', '.ie-btn-toggle-branch', function (e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
toggleBranch($(this).closest('.dd-item'), true);
|
|
});
|
|
|
|
$root.on('click', '.ie-btn-copy-branch', function (e) {
|
|
e.stopPropagation();
|
|
copyBranch($(this).data('id'), $(this).data('name') || '');
|
|
});
|
|
|
|
$root.on('click', '.ie-btn-paste-branch', function (e) {
|
|
e.stopPropagation();
|
|
pasteBranch($(this).data('id'), $(this).data('name') || '');
|
|
});
|
|
|
|
$('#ie_expand_all').on('click', function () { setAllBranches(true); });
|
|
$('#ie_collapse_all').on('click', function () { setAllBranches(false); });
|
|
$('#ie_paste_to_root').on('click', function () { pasteBranch(null, 'ریشه درخت'); });
|
|
$('#ie_clear_clipboard').on('click', clearClipboard);
|
|
|
|
loadClipboard();
|
|
initBranchCollapse();
|
|
initThemePicker();
|
|
}
|
|
|
|
function branchStorageKey() {
|
|
return COLLAPSE_STORAGE_KEY + '_' + (bomId || '0');
|
|
}
|
|
|
|
function getCollapsedIds() {
|
|
try {
|
|
return JSON.parse(localStorage.getItem(branchStorageKey()) || '[]');
|
|
} catch (e) {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
function saveCollapsedIds(ids) {
|
|
localStorage.setItem(branchStorageKey(), JSON.stringify(ids));
|
|
}
|
|
|
|
function initBranchCollapse() {
|
|
var collapsed = getCollapsedIds();
|
|
$('.dd-item[data-has-children="1"]').each(function () {
|
|
var id = String($(this).data('id'));
|
|
if (collapsed.indexOf(id) !== -1) {
|
|
setBranchCollapsed($(this), true, false);
|
|
} else {
|
|
setBranchExpanded($(this), false);
|
|
}
|
|
});
|
|
}
|
|
|
|
function toggleBranch($item, persist) {
|
|
if ($item.hasClass('ie-branch-collapsed')) {
|
|
setBranchExpanded($item, persist);
|
|
} else {
|
|
setBranchCollapsed($item, true, persist);
|
|
}
|
|
}
|
|
|
|
function setBranchCollapsed($item, animate, persist) {
|
|
var $children = $item.children('.ie-branch-children');
|
|
var $btn = $item.find('> .ie-dd-handle .ie-btn-toggle-branch i');
|
|
$item.addClass('ie-branch-collapsed');
|
|
$btn.removeClass('fa-minus').addClass('fa-plus');
|
|
if (animate) {
|
|
$children.stop(true, true).slideUp(160);
|
|
} else {
|
|
$children.hide();
|
|
}
|
|
if (persist) {
|
|
var ids = getCollapsedIds();
|
|
var id = String($item.data('id'));
|
|
if (ids.indexOf(id) === -1) ids.push(id);
|
|
saveCollapsedIds(ids);
|
|
}
|
|
}
|
|
|
|
function setBranchExpanded($item, persist) {
|
|
var $children = $item.children('.ie-branch-children');
|
|
var $btn = $item.find('> .ie-dd-handle .ie-btn-toggle-branch i');
|
|
$item.removeClass('ie-branch-collapsed');
|
|
$btn.removeClass('fa-plus').addClass('fa-minus');
|
|
$children.stop(true, true).slideDown(160);
|
|
if (persist) {
|
|
var ids = getCollapsedIds().filter(function (id) {
|
|
return id !== String($item.data('id'));
|
|
});
|
|
saveCollapsedIds(ids);
|
|
}
|
|
}
|
|
|
|
function setAllBranches(expand) {
|
|
$('.dd-item[data-has-children="1"]').each(function () {
|
|
if (expand) {
|
|
setBranchExpanded($(this), false);
|
|
} else {
|
|
setBranchCollapsed($(this), true, false);
|
|
}
|
|
});
|
|
saveCollapsedIds(expand ? [] : $('.dd-item[data-has-children="1"]').map(function () {
|
|
return String($(this).data('id'));
|
|
}).get());
|
|
}
|
|
|
|
function loadClipboard() {
|
|
try {
|
|
var raw = localStorage.getItem(CLIPBOARD_STORAGE_KEY);
|
|
if (!raw) return;
|
|
var data = JSON.parse(raw);
|
|
if (data && data.bomId == bomId && data.lineId) {
|
|
clipboardBranchId = data.lineId;
|
|
clipboardBranchName = data.name || '';
|
|
updateClipboardBar();
|
|
}
|
|
} catch (e) { /* ignore */ }
|
|
}
|
|
|
|
function saveClipboard() {
|
|
if (!clipboardBranchId) {
|
|
localStorage.removeItem(CLIPBOARD_STORAGE_KEY);
|
|
return;
|
|
}
|
|
localStorage.setItem(CLIPBOARD_STORAGE_KEY, JSON.stringify({
|
|
bomId: bomId,
|
|
lineId: clipboardBranchId,
|
|
name: clipboardBranchName
|
|
}));
|
|
}
|
|
|
|
function updateClipboardBar() {
|
|
if (clipboardBranchId) {
|
|
$('#ie_clipboard_bar').show();
|
|
$('#ie_clipboard_label').text(clipboardBranchName || ('#' + clipboardBranchId));
|
|
$('.ie-btn-paste-branch').prop('disabled', false);
|
|
} else {
|
|
$('#ie_clipboard_bar').hide();
|
|
$('.ie-btn-paste-branch').prop('disabled', true);
|
|
}
|
|
}
|
|
|
|
function copyBranch(lineId, name) {
|
|
clipboardBranchId = lineId;
|
|
clipboardBranchName = name || '';
|
|
saveClipboard();
|
|
updateClipboardBar();
|
|
highlightNode(lineId);
|
|
if (typeof toastr !== 'undefined') {
|
|
toastr.info('شاخه کپی شد: ' + (name || lineId));
|
|
}
|
|
}
|
|
|
|
function clearClipboard() {
|
|
clipboardBranchId = null;
|
|
clipboardBranchName = '';
|
|
saveClipboard();
|
|
updateClipboardBar();
|
|
}
|
|
|
|
function pasteBranch(targetParentId, targetName) {
|
|
if (!clipboardBranchId) {
|
|
toastr.warning('ابتدا یک شاخه را کپی کنید');
|
|
return;
|
|
}
|
|
if (String(clipboardBranchId) === String(targetParentId)) {
|
|
toastr.warning('نمیتوان شاخه را روی خودش پیست کرد');
|
|
return;
|
|
}
|
|
var msg = 'پیست شاخه «' + (clipboardBranchName || clipboardBranchId) + '» زیر «' + (targetName || 'ریشه درخت') + '»؟';
|
|
if (!confirm(msg)) return;
|
|
|
|
$.ajax({
|
|
url: duplicateUrl,
|
|
method: 'POST',
|
|
data: {
|
|
_token: $('meta[name="csrf-token"]').attr('content'),
|
|
source_line_id: clipboardBranchId,
|
|
target_parent_line_id: targetParentId || null
|
|
},
|
|
success: function (res) {
|
|
if (res.success) {
|
|
toastr.success(res.msg);
|
|
location.reload();
|
|
}
|
|
},
|
|
error: function (xhr) {
|
|
toastr.error(xhr.responseJSON?.msg || xhr.responseJSON?.message || 'خطا در پیست شاخه');
|
|
}
|
|
});
|
|
}
|
|
|
|
function initThemePicker() {
|
|
var $wrapper = $('#ie_tree_wrapper');
|
|
var $select = $('#ie_tree_theme_select');
|
|
if (!$wrapper.length) return;
|
|
|
|
$('#ie_tree_theme_select option').each(function () {
|
|
themeLabels[$(this).val()] = $(this).text();
|
|
});
|
|
|
|
defaultThemeId = String(localStorage.getItem(THEME_DEFAULT_KEY) || '18');
|
|
var saved = localStorage.getItem(THEME_STORAGE_KEY) || defaultThemeId;
|
|
applyTheme(saved, false);
|
|
updateDefaultBadges();
|
|
|
|
$('.ie-theme-card').on('click', function (e) {
|
|
if ($(e.target).closest('.ie-theme-pin').length) return;
|
|
applyTheme($(this).data('theme'), true);
|
|
$('#ie_tree_theme_picker').collapse('hide');
|
|
});
|
|
|
|
$('.ie-theme-pin').on('click', function (e) {
|
|
e.preventDefault();
|
|
e.stopPropagation();
|
|
setDefaultTheme($(this).data('theme'));
|
|
});
|
|
|
|
$('#ie_apply_default_theme').on('click', function () {
|
|
applyTheme(defaultThemeId, true);
|
|
});
|
|
|
|
$select.on('change', function () {
|
|
applyTheme($(this).val(), true);
|
|
});
|
|
}
|
|
|
|
function setDefaultTheme(themeId) {
|
|
themeId = String(themeId || '2');
|
|
defaultThemeId = themeId;
|
|
localStorage.setItem(THEME_DEFAULT_KEY, themeId);
|
|
updateDefaultBadges();
|
|
if (typeof toastr !== 'undefined') {
|
|
toastr.success('پیشفرض: ' + (themeLabels[themeId] || themeId));
|
|
}
|
|
}
|
|
|
|
function updateDefaultBadges() {
|
|
$('.ie-theme-card').removeClass('is-default');
|
|
$('.ie-theme-pin i').removeClass('fa-star').addClass('fa-star-o');
|
|
$('.ie-theme-card[data-theme="' + defaultThemeId + '"]').addClass('is-default');
|
|
$('.ie-theme-pin[data-theme="' + defaultThemeId + '"] i').removeClass('fa-star-o').addClass('fa-star');
|
|
$('#ie_default_theme_label').text(themeLabels[defaultThemeId] || defaultThemeId);
|
|
}
|
|
|
|
function applyTheme(themeId, persist) {
|
|
themeId = String(themeId || defaultThemeId || '18');
|
|
var $wrapper = $('#ie_tree_wrapper');
|
|
var baseClass = 'ie-tree-indented';
|
|
$wrapper.attr('class', baseClass + ' ie-tree-theme-' + themeId);
|
|
$('.ie-theme-card').removeClass('active');
|
|
$('.ie-theme-card[data-theme="' + themeId + '"]').addClass('active');
|
|
$('#ie_tree_theme_select').val(themeId);
|
|
$('#ie_current_theme_label').text(themeLabels[themeId] || themeId);
|
|
if (persist) {
|
|
localStorage.setItem(THEME_STORAGE_KEY, themeId);
|
|
if (typeof toastr !== 'undefined') {
|
|
toastr.info('دیزاین درخت: ' + (themeLabels[themeId] || themeId));
|
|
}
|
|
}
|
|
}
|
|
|
|
function setTemplateParent(id, name) {
|
|
selectedParentId = id || null;
|
|
selectedParentName = name || '';
|
|
$('#ie_template_parent_id').val(id || '');
|
|
$('#ie_template_parent_label').val(name || 'ریشه درخت (سطح خط تولید)');
|
|
highlightNode(id);
|
|
}
|
|
|
|
function highlightNode(lineId) {
|
|
$('.ie-dd-handle').removeClass('ie-node-selected');
|
|
if (lineId) {
|
|
$('.dd-item[data-id="' + lineId + '"] > .ie-dd-handle').addClass('ie-node-selected');
|
|
}
|
|
}
|
|
|
|
function applyTemplate(templateKey) {
|
|
if (!confirm('اعمال الگو زیر «' + (selectedParentName || 'ریشه درخت') + '»؟')) return;
|
|
|
|
$.ajax({
|
|
url: applyTemplateUrl,
|
|
method: 'POST',
|
|
data: {
|
|
_token: $('meta[name="csrf-token"]').attr('content'),
|
|
parent_line_id: selectedParentId,
|
|
template_key: templateKey
|
|
},
|
|
success: function (res) {
|
|
if (res.success) {
|
|
toastr.success(res.msg);
|
|
location.reload();
|
|
}
|
|
},
|
|
error: function (xhr) {
|
|
toastr.error(xhr.responseJSON?.msg || xhr.responseJSON?.message || 'خطا در اعمال الگو');
|
|
}
|
|
});
|
|
}
|
|
|
|
function saveTemplate() {
|
|
var lineId = selectedLineId || selectedParentId;
|
|
var name = $('#ie_save_template_name').val();
|
|
if (!lineId) {
|
|
toastr.warning('ابتدا یک شاخه را انتخاب کنید (دکمه هدف یا ویرایش)');
|
|
return;
|
|
}
|
|
if (!name) {
|
|
toastr.warning('نام الگو را وارد کنید');
|
|
return;
|
|
}
|
|
|
|
$.ajax({
|
|
url: saveTemplateUrl,
|
|
method: 'POST',
|
|
data: {
|
|
_token: $('meta[name="csrf-token"]').attr('content'),
|
|
bom_line_id: lineId,
|
|
name: name
|
|
},
|
|
success: function (res) {
|
|
if (res.success) {
|
|
toastr.success(res.msg);
|
|
location.reload();
|
|
}
|
|
},
|
|
error: function (xhr) {
|
|
toastr.error(xhr.responseJSON?.msg || xhr.responseJSON?.message || 'خطا در ذخیره الگو');
|
|
}
|
|
});
|
|
}
|
|
|
|
function deleteSavedTemplate() {
|
|
var key = $('#ie_saved_template').val();
|
|
if (!key || key.indexOf('saved:') !== 0) return;
|
|
var id = key.replace('saved:', '');
|
|
if (!confirm('حذف این الگوی ذخیرهشده؟')) return;
|
|
|
|
$.ajax({
|
|
url: deleteTemplateUrl + '/' + id,
|
|
method: 'DELETE',
|
|
data: { _token: $('meta[name="csrf-token"]').attr('content') },
|
|
success: function (res) {
|
|
if (res.success) {
|
|
toastr.success(res.msg);
|
|
location.reload();
|
|
}
|
|
},
|
|
error: function (xhr) {
|
|
toastr.error(xhr.responseJSON?.msg || 'خطا در حذف');
|
|
}
|
|
});
|
|
}
|
|
|
|
function nestableData() {
|
|
return $('#ie_bom_nestable').nestable('serialize');
|
|
}
|
|
|
|
function saveTree() {
|
|
$.ajax({
|
|
url: moveUrl,
|
|
method: 'POST',
|
|
data: {
|
|
_token: $('meta[name="csrf-token"]').attr('content'),
|
|
nestable: nestableData()
|
|
},
|
|
success: function (res) {
|
|
if (res.success) {
|
|
toastr.success(res.msg);
|
|
location.reload();
|
|
}
|
|
},
|
|
error: function (xhr) {
|
|
toastr.error(xhr.responseJSON?.msg || xhr.responseJSON?.message || 'خطا در ذخیره درخت');
|
|
}
|
|
});
|
|
}
|
|
|
|
function resetForm(parentId) {
|
|
$('#ie_node_form')[0].reset();
|
|
$('#ie_parent_line_id').val(parentId || '');
|
|
$('#ie_bom_line_id').val('');
|
|
$('#ie_item_name').prop('disabled', false);
|
|
$('#ie_item_master_id').val('').trigger('change');
|
|
$('#ie_panel_title').text(parentId ? 'افزودن زیرمجموعه' : 'افزودن ریشه درخت');
|
|
$('#ie_submit_node').html('<i class="fa fa-plus"></i> افزودن به درخت');
|
|
}
|
|
|
|
function submitNode(e) {
|
|
e.preventDefault();
|
|
var lineId = $('#ie_bom_line_id').val();
|
|
var data = $('#ie_node_form').serializeArray();
|
|
data.push({ name: '_token', value: $('meta[name="csrf-token"]').attr('content') });
|
|
|
|
var url = storeUrl;
|
|
var method = 'POST';
|
|
if (lineId) {
|
|
url = updateBase + '/' + lineId;
|
|
method = 'PUT';
|
|
}
|
|
|
|
$.ajax({
|
|
url: url,
|
|
method: method,
|
|
data: $.param(data),
|
|
success: function (res) {
|
|
if (res.success) {
|
|
toastr.success(res.msg);
|
|
if (res.integration_messages) {
|
|
res.integration_messages.forEach(function (m) {
|
|
if (m.type === 'warning' && typeof toastr.warning === 'function') {
|
|
toastr.warning(m.text, '', { timeOut: 8000 });
|
|
} else if (m.type === 'success' && typeof toastr.info === 'function') {
|
|
toastr.info(m.text);
|
|
}
|
|
});
|
|
}
|
|
location.reload();
|
|
}
|
|
},
|
|
error: function (xhr) {
|
|
toastr.error(xhr.responseJSON?.msg || xhr.responseJSON?.message || 'خطا');
|
|
}
|
|
});
|
|
}
|
|
|
|
function loadNodeForEdit(lineId) {
|
|
var $item = $('.dd-item[data-id="' + lineId + '"]');
|
|
if (!$item.length) return;
|
|
$('#ie_bom_line_id').val(lineId);
|
|
$('#ie_parent_line_id').val('');
|
|
$('#ie_panel_title').text('ویرایش گره');
|
|
$('#ie_submit_node').html('<i class="fa fa-save"></i> ذخیره تغییرات');
|
|
$('#ie_item_name').prop('disabled', true);
|
|
$('#ie_item_master_id').val($item.data('item-master-id') || '').trigger('change');
|
|
$('#ie_item_name').val($item.data('item-name') || '');
|
|
$('#ie_item_type').val($item.data('item-type') || 'part');
|
|
$('#ie_quantity').val($item.data('quantity') || 1);
|
|
$('#ie_position_code').val($item.data('position-code') || '');
|
|
$('#ie_find_number').val($item.data('find-number') || '');
|
|
$('#ie_variation_id').val($item.data('variation-id') || '');
|
|
$('#ie_item_code').val('');
|
|
$('#ie_search_product').val('');
|
|
setTemplateParent(lineId, $item.data('item-name') || '');
|
|
}
|
|
|
|
function deleteNode(lineId) {
|
|
if (!confirm('حذف این گره و تمام زیرمجموعههایش؟')) return;
|
|
$.ajax({
|
|
url: deleteBase + '/' + lineId,
|
|
method: 'DELETE',
|
|
data: { _token: $('meta[name="csrf-token"]').attr('content') },
|
|
success: function (res) {
|
|
if (res.success) {
|
|
toastr.success(res.msg);
|
|
$('.dd-item[data-id="' + lineId + '"]').remove();
|
|
}
|
|
},
|
|
error: function (xhr) {
|
|
toastr.error(xhr.responseJSON?.msg || xhr.responseJSON?.message || 'خطا در حذف');
|
|
}
|
|
});
|
|
}
|
|
|
|
return { init: init };
|
|
})();
|