2023-05-16 10:50:42 +08:00

395 lines
14 KiB
JavaScript

$(function()
{
var $editModal = $('#editorElementModal');
var $editModalBtn = $('#editorElementModalBtn');
var $editorDeleteBtn = $('#editorDeleteBtn');
var $editorCanvas = $('#editorCanvas');
var editCallback;
var showElementEditModal = function(position, element, callback)
{
var $window = $(window);
var width = $editModal.outerWidth();
var height = $editModal.outerHeight();
position.top = Math.max(0, Math.min($window.height() - height, position.top));
position.left = Math.max(0, Math.min($window.width() - width, position.left));
$editModal.find('#elementName').val(element.name).parent().removeClass('has-error');
$editModal.find('#elementCode').val(element.code).attr('readonly', element.codeReadonly ? 'readonly' : null).parent().removeClass('has-error');
if($editModalBtn.data('zui.tooltip')) $editModalBtn.tooltip('destroy');
editCallback = callback;
$editModal.css(position).addClass('show');
$editModal.find('#elementName').select().focus();
};
var isElementReadonly = function(element)
{
return element.type === 'start' || element.type === 'stop' || element.getData('readonly') ||(window.readonlyActions && window.readonlyActions.indexOf(element.getData('code')) > -1);
};
var handleElementActiveChange = function()
{
var activeElements = this.getActiveElements();
var elementsCanDelete = activeElements.filter(function(ele)
{
return !isElementReadonly(ele) && (window.defaultActions.indexOf(ele.getData('code')) === -1 || !ele.data._saved);
});
$editorDeleteBtn.attr('disabled', elementsCanDelete.length ? null : 'disabled');
};
var getStartStopElements = function(flowchart)
{
flowchart = flowchart || getFlowchart();
var start, stop;
var nodeList = flowchart.nodeList;
for(var i = 0; i < nodeList.length; ++i)
{
var node = nodeList[i];
if(node.type === 'start') start = node;
else if(node.type === 'stop') stop = node;
if(start && stop) break;
}
return {start: start, stop: stop};
};
$editModal.on('input change', 'input', function()
{
$editModal.find('td.has-error').removeClass('has-error');
if($editModalBtn.data('zui.tooltip')) $editModalBtn.tooltip('destroy');
});
$editModalBtn.on('click', function()
{
var $name = $editModal.find('#elementName');
var $code = $editModal.find('#elementCode');
var data = {name: $name.val(), code: $code.val()};
var hasError;
if(!data.name.length)
{
$name.parent().addClass('has-error');
hasError = true;
}
if(!data.code.length)
{
$code.parent().addClass('has-error');
hasError = true;
}
if(hasError)
{
if(!$editModalBtn.data('zui.tooltip'))
{
$editModalBtn.attr('data-toggle', 'tooltip').tooltip(
{
show: true,
title: window.langNameAndCodeRequired,
tipClass: 'tooltip-danger',
placement: 'top',
});
}
$editModalBtn.tooltip('show');
return;
}
if(editCallback)
{
editCallback(data);
editCallback = null;
}
$editModal.removeClass('show');
});
$(document).on('mouseup', function(e)
{
var $modal = $('#editorElementModal');
if($modal.hasClass('show') && !$(e.target).closest('#editorElementModal').length)
{
editCallback = null;
$modal.removeClass('show');
}
});
$('.editor-element').on('mousedown', function()
{
$(this).tooltip('hide');
})
var canvasHeight = $editorCanvas.height() || ($(window).height() - 145);
flowchartData.forEach(function(data, index)
{
data.codeReadonly = true;
if(window.isDefaultData)
{
// Adjust positions for default data
if(data.id === 'start') data.position = {left: 40, top: 20};
else if(data.id === 'stop') data.position = {left: 40, top: canvasHeight - 60};
else data.position = {left: 30, top: 20 + index * 100};
}
else data._saved = true;
});
var flowChartOptions =
{
height: 'auto',
data: flowchartData,
autoLayoutDirection: 'vert',
relationLineWidth: 2,
padding: 20,
relationLineColor: '#a6aab8',
relationLineShape: 'polyline',
defaultNodeType: 'process',
relationArrowSize: 6,
allowFreePorts: true,
nodeMinWidth: 80,
addFromDrop: '#editorElements',
nodeHeight: 42,
activeColor: '#1CA5FF',
exportDetailPosition: false,
centerOnCreate: 'horz',
confirmRelationType: false,
elementTypes:
{
start:
{
minWidth: 80,
shapeStyle: {backgroundColor: '#b0bac1', borderColor: 'transparent'},
textStyle: {color: '#fff'},
text: window.flowchartElementTypes.start
},
process:
{
minWidth: 100,
type: 'action',
shapeStyle: {backgroundColor: '#40caca', borderColor: 'transparent'},
textStyle: {color: '#fff'},
text: window.flowchartElementTypes.process
},
decision:
{
type: 'diamond',
style: {minWidth: 70, minHeight: 70},
shapeStyle: {backgroundColor: '#fad43c', borderColor: 'transparent'},
textStyle: {color: '#fff'},
text: window.flowchartElementTypes.decision
},
result:
{
type: 'circle',
shapeStyle: {backgroundColor: '#0964eb', borderColor: 'transparent', minWidth: 70, minHeight: 70},
textStyle: {color: '#fff'},
text: window.flowchartElementTypes.result
},
stop:
{
minWidth: 80,
shapeStyle: {backgroundColor: '#b0bac1', borderColor: 'transparent'},
textStyle: {color: '#fff'},
text: window.flowchartElementTypes.stop
},
},
showContextMenu: function(ele, items)
{
items.splice(0, 2);
if(ele.id == 'start' || ele.id == 'stop' || ele.id == 'edit' || ele.id == 'create')
{
items.splice(1, 1);
}
return items;
},
onActiveElement: handleElementActiveChange,
onUnactiveElement: handleElementActiveChange,
onAddElement: function(elementsToAdd)
{
var flowchart = this;
var elementsCanAdd = [];
var startAndStop = getStartStopElements(flowchart);
elementsToAdd.forEach(function(element)
{
var duplicatedStart = element.type === 'start' && startAndStop.start;
var duplicatedStop = !duplicatedStart && element.type === 'stop' && startAndStop.stop;
if(!duplicatedStart && !duplicatedStop)
{
elementsCanAdd.push(element);
}
if(element.data && element.data['zui.tooltip']) delete element.data['zui.tooltip'];
});
if(elementsCanAdd.length < elementsToAdd.length)
{
bootbox.alert(window.langStartOrStopDuplicated);
}
return elementsCanAdd.length ? elementsCanAdd : false;
},
afterUpdateElement: function()
{
var startAndStop = getStartStopElements(this);
var $editorElements = $('#editorElements');
$editorElements.find('.editor-element-start')[startAndStop.start ? 'hide' : 'show']();
$editorElements.find('.editor-element-stop')[startAndStop.stop ? 'hide' : 'show']();
if(this.created) this.changed = true;
},
onChangeElementPosition: function()
{
if(this.created) this.changed = true;
},
deleteConfirm: function(ele, deleteElement)
{
window.bootbox.confirm(window.langConfirmToDelete.replace('%s', window.flowchartElementTypes[ele.type]), function(result)
{
if(result) deleteElement();
});
},
onDeleteElement: function(elements)
{
handleElementActiveChange.call(this);
elements.forEach(function(ele)
{
$('#tooltip-' + ele.id).remove();
});
if(this.created) this.changed = true;
},
doubleClickToEdit: function(element, flowchart, e)
{
var elementType = element.type;
if(elementType === 'process' && !isElementReadonly(element))
{
showElementEditModal({left: e.pageX, top: e.pageY},
{
name: element.getText(),
code: element.getData('code'),
codeReadonly: element.getData('codeReadonly'),
}, function(newData)
{
if(!element.codeReadonly) element.setData('code', newData.code);
element.setText(newData.name);
flowchart.render(element);
if(flowchart.created) flowchart.changed = true;
});
return true;
}
if(elementType === 'start' || elementType === 'stop') return true;
}
};
var flowChart = $editorCanvas.flowChart(flowChartOptions).data('zui.flowChart');
$editorDeleteBtn.on('click', function()
{
flowChart.tryDeleteElement(flowChart.getActiveElements()[0]);
handleElementActiveChange.call(flowChart);
});
$('#saveBtn').on('click', saveFlowchart.bind(this, null, true));
$('.nextStep, #editorSteps > ul > li > a[href*=ui]').on('click', function()
{
var href = $(this).attr('href');
if(saveFlowchart(function(result)
{
if(result) setTimeout(function(){location.href = href;}, 1200);
})) return false;
});
$('#elementCode').on('change', function()
{
var $input = $(this);
$input.val($input.val().replace(/[^a-zA-Z]/g, '').toLowerCase());
});
$(window).on('beforeunload', function(e)
{
if(getFlowchart().changed)
{
e = e || window.event;
// IE8, Firefox 4
if(e) e.returnValue = window.leavePageTip;
// Chrome, Safari, Firefox 4+, Opera 12+ , IE 9+
return window.leavePageTip;
}
});
setAutoHeight();
$(window).on('resize', setAutoHeight);
});
/**
* Get FlowChart object instance
* @return {FlowChart}
*/
function getFlowchart()
{
return $('#editorCanvas').data('zui.flowChart');
}
/**
* Save flowChart data
* @param {function} [callback] Callback for save complete
* @param {boolean} [force] Force save and ignore changes status
* @return {Object[]} Flowchart elements list
*/
function saveFlowchart(callback, force)
{
var flowChart = getFlowchart();
if(!force && !flowChart.changed) return;
var data = flowChart.exportData();
data.forEach(function(elementData) {delete elementData._saved;});
var link = createLink('workflow', 'ajaxSaveFlowchart', 'module=' + window.moduleName);
$.post(link, {'data':JSON.stringify(data)}, function(response)
{
try {response = JSON.parse(response);}
catch(error)
{
response = response ? response : window.unknownError;
new $.zui.Messager(response,
{
type: 'danger',
icon: 'bell',
placement: 'center',
time: 10000
}).show();
if(callback) callback(false, response);
return;
}
if(response.result == 'fail')
{
if($.type(response.message) == 'object')
{
for(var controlID in response.message)
{
var $element = $('#editorCanvas-' + controlID);
var tooltip = $element.data('zui.tooltip');
if(tooltip && tooltip.show)
{
tooltip.hoverState = 'in';
tooltip.show(removeHtmlTag(response.message[controlID]));
}
else $element.attr('data-toggle', 'tooltip').tooltip({tipClass: 'tooltip-danger', tipId: 'tooltip-' + controlID}).tooltip('show', removeHtmlTag(response.message[controlID]));
}
} else if($.type(response.message) == 'string') bootbox.alert(removeHtmlTag(response.message));
if(callback) callback(false, response);
}
else
{
var flowChartData = JSON.parse(response.flowchart);
flowChartData.forEach(function(element)
{
element._saved = true;
});
flowChart.resetData(flowChartData);
flowChart.changed = false;
$('#saveBtn').popover(
{
trigger: 'manual',
content: response.message,
tipClass: 'popover-success popover-form-result',
placement: 'left'
}).popover('show');
setTimeout(function(){$('#saveBtn').popover('destroy')}, 2000);
if($.isFunction(callback)) callback(true, response);
}
});
return true;
}