Created
July 1, 2016 03:26
-
-
Save elquimista/677af350749de3dd631596494ba8a01d to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SVGAnimatedTransformList.prototype.translate = function (x, y) { | |
var xForms = this.baseVal, | |
xFormTranslate = undefined, | |
transform = undefined; | |
for (var i = 0, n = xForms.numberOfItems; i < n; i ++) { | |
transform = xForms.getItem(i); | |
if (transform.type === SVGTransform.SVG_TRANSFORM_TRANSLATE) { | |
xFormTranslate = transform; | |
break; | |
} | |
if (transform.type === SVGTransform.SVG_TRANSFORM_MATRIX) { | |
xFormTranslate = transform; | |
break; | |
} | |
} | |
if (xFormTranslate) { | |
if (x) { | |
xFormTranslate.matrix.e = x; | |
} | |
if (y) { | |
xFormTranslate.matrix.f = y; | |
} | |
} | |
}; | |
var RAPPID = function() { | |
var $ = window.jQuery, | |
graph, paper, paperScroller, snaplines, stencil, nav, inspector, halo, gOptions, | |
shapeSize = [50, 50], | |
shapeMargin = [20, 10], | |
shapeTextMarginTop = 5, | |
iconSize = [32, 32], | |
shapeBigSize = [150, 150], | |
zoomMax = 1, | |
zoomMin = 0.4, | |
zoomStep = 0.2, | |
defaultPaperSize = [$('#paper').width() || 1500, $('#paper').height() || 900], | |
wfAutoSaveInterval = 1000, // in milliseconds | |
chartPieRadius = 60, | |
chartSerieFillColor = ['#8bce5d', '#53abdd', '#c377b1', '#ffe891', '#888888', '#53abdd', '#c377b1', '#ffe891', '#888888'], | |
logTimerId, | |
chart = new joint.shapes.chart.Pie({ | |
attrs: { | |
'.slice-inner-label': { fill: '#000' } | |
}, | |
position: { x: 0, y: 0 }, | |
size: { width: chartPieRadius * 2, height: chartPieRadius * 2 }, | |
serieDefaults: { | |
degree: 360, | |
startAngle: 0, | |
showLegend: false | |
}, | |
sliceDefaults: { | |
innerLabel: '{label}' | |
}, | |
series: [] | |
}), | |
$statusBarEl = $('#status_bar'), | |
configErrors = {}, | |
linkDownFlag = false, | |
graphHasChanged = false, | |
agentDownFlag = false, | |
$goalMarkerEl = V('<path d="M 0.000 10.000 L 11.756 16.180 L 9.511 3.090 L 19.021 -6.180 L 5.878 -8.090 L 0.000 -20.000 L -5.878 -8.090 L -19.021 -6.180 L -9.511 3.090 L -11.756 16.180 L 0.000 10.000" fill="#f8b600" stroke="#f8b600" transform="translate(75 145)"></path>').node, | |
// Used for showing sticky config option icons for agents that are not configured yet. | |
halo2 = {}, | |
configIcon = 'data:image/png;base64,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', | |
configIconGreen = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAAEEfUpiAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAIGNIUk0AAHolAACAgwAA+f8AAIDpAAB1MAAA6mAAADqYAAAXb5JfxUYAAAjJSURBVHjaAEQAu/8BRERAAh0SBP+8Phz9VbzkCAD/QUMAL6Zy//3//v8vpnL/AhxRG/YAAAAA/QD/AAAAAAACb7PjEAAAAADsAPgAAAAAAAAAAP//YnZzcWD+WWi/jNdTX8T8t+AFRq2Fuf+YmZkZmZmZGd68efOfiZWVlZEBCoSFhRmZPnz48JuJiYnh////DG/evGEAAAAA//9idHNxYL7qJ6fLx8d3jo2NDa7648ePfy6sus/KKDM5fo6wsHAyTIKVlZXh9+/fDAwMDAyMjIwMTAwMDHthkv/+/WM4FtIG4zL8//+fgZExw5r53w2Ov7LBMn9ERESY//+HeOjt27cMaRsecQAAAAD//2J0cXFgVv3PyLjeR0qEhYXlFgMDw4vT65+oBTL9ZeJhYGBkrHZ2ZJ/vJ/NDVFQUbjQjIyPD69evPylteiTMtDBA7j1McnVkLQMPDw/D////GURERPju+ckZM6rNzfzDycnJjOxQJiYmBgYGBobXr18zMLGzs8Mll0ZWM/Dx8cGtYmZmZmD68uXLP5jL0cHfv38ZmH7//t3OyMjI8P//f4bN/+8yfP36Fa7g1sZnjMw/xLkPMQty+bKxsUlcu3aN8f///wzfv3//8+HDB8P9tz+8BbBN9SoNg1H0nO+LNkmloTV1UVwEF8HBjkUoWHVzEEQ61ElEH8KXcBIXFxGdCoq+gPQJFEEEl1YRO5QaCMGQ+7k01VrXezncc88Pq9WKVgBLhvpkzaftOAFJy3XdJOWXJImJoshEUaQAHL9evB8sZ2PLBsB6taJvViYtJ5uNfN8f4WnbNsIwHHwOAEEQJHEcP7euXxY4fbRTVEp9FAqFEfDu5jZqmUWsXh5CRIY8NsaYbrf7qUg+eJ43IpOIYD0zjzwycF0XJIf2SimS9BSAtoj8q/MXZNCG9HIahYGpd41WqdfrqXT42zPpg0WkH80fFmEYJgDOyb2ylicnmd2aebMsq5jL5ay/Zmuth5h1Oh0AWKpdtR/J/bIGwLHIYCOZYLM0NUeyCSBPkmn/RARa67PbRqt+Chm/pxED4JuPqueJKgqiZ+69cEWLx1NJjLJqxNhZGgolENzExPiBSKGFRgsSbQwVv8CvyhhMjLHzD0As1JioQQsRLGykIUqMLCGEXdlkF967zzd3bHib3RWY5jYzc8+cOXMon+/TALAOyPHdLeZGiZOhi503lVKjAI6JyDqAt2majgx8XVlsW/6rZ0lkYydC+XyfiQCsKeKVc7mHAEattd5aS8YYAoA4jjmKIg3AO+fC22+W3RQJCyDUk+8zn1inBy/nlpRSe8IwbNlM/CICZpZyuUwAeodfLkx/JkmVAMgNdn4xxuxtb2+vFXvvYa2tMU9E0FrThlo/Pj27b+dhAan587mjItIdBIFplvDU4D28u3IXzNyw/zAMYa39M+Z1apRS74MgEBFpkFocx1iFw2s/33AH2aEDwJGB/V10YOy6dHR0oHnubITMBJsjiiIfRdErlZnBZlc4PfQAk1fv10aoD2utEpEzWzao/QT+7xbq+Gg1zRrfLurzmFkA/FZZg+1QbMGBAHikiOhJpVJJm1HUG8hm8OM4VjMThTE1O1G445wzWUL2JkmCVTh8SH9BKdUAv1wup0T07AX5Vuq+1t9aONGZA/Cj2RO99yCihuJqtcrOubWF8ULQr1mrmV3On55cLDBzV6lUQrVaTetsq4G0YrHISZL8/Da+EJzSbDQAolsnDQD0VHaox0uSXLiUe+69H66H7b0XIqowc++hueJ3PRejbYOaf5RWTWhcVRT+zrnvP4lhTEDND2pclKi0IohgFEwNWgptJUZsVrooNbta6aZ0IQW3WVgL6qqrCiJto1Ywlvq3ERGxVAQVahfO1NZqyCTzyJt33z3HRWamMZ0k413eyz333POd831fkw8IABhADcBjSrzQ7+mhm87u2TswysyvMfOUiNwJQAG0iKZZVBGBiGiDbJcAfGytnf3i/I1Lp7rhSSrmO1KXNAJgbQIMUA3AhJI5LlQffH5whIg+JKJHAbgwDDWOY2OMoc1apnnWEDKXZRmpqiGi31T1xUvnKpffYQnnSV0XAAGUdk48bR5UMm9bkw9NDTzAzN845wbCMCzW83M76VHV27rklj+hlhBmWWaYuaqq4+WzlR+PGAl/IC1o9pnx4IBw/tDk0JsAjhGRLZVK/mbTJSI4ODWN6XA7HBTncRUnPzgF59ymU7m4uFgUReER0Xu/ni3PnGAJeFIpf/iF4bdU9VgYhkVfX9+Wj0dR1BLdfkTYhxEkSdJq+40GsFQqeUmSOBF5ddvk0OmXlXMaPvnKtHPu/SAIpLe3lzuhgabL8n0fAFAUxapX4o6uY3l5WbIsY2PMIQ/AEWZGFEX/i4tmJvdjf7gdOQQXiquYPdMegnZkGccx1et1qOrrLCKjDQfc8e+DIMBYOII7EKCEEDu9+xDHcVsI2sFpjKFGte5lAMsN46DrMdtoMTMYWz+0Uaw1+zkz8ycAYK2VTjHcajXsY9ukiAh5nkujWvPsnDtKRJU0TU2e59qpuG0lfBvFcc5pmqYMoOqcO8yVuWs3RWSCiFaq1So1k9gKigCr1TIgxDAtFlwva+uN5sLCQvPsud/nrl2h4QPjppbWQTsG/KSr6ysReTyKoqKnp8fbrBGJCHEcN8X1tglYX4FareZWVlYMM/9SFMUT1+f/qB60zEQzY4ZzoZeWEnP6H9SHJ4d2APhMRO72PM92d3d7QRDQ2h9thO/afSKCtVbTNHV5nnvMvKSqe386V/76BGt4kdTFgLbsNQD4mWJfGpuL9ZWcnxwK4yQ5DuCwiPhEBN/3xfd99TyPjTG0VoBERIuikDzPyVrLDY0QVX3XWnv0+pm/lt6IXPglqYtuKaISzYxxM4Hm8uqCUYnpfvL529Fe+/n837przz13eZ63G8CzAB4BMAigq3E3JaI/AVxW1Qsi8uncR5Xy7l39NFxe9p/6OZPvSbVnVQH/U7R/BwC/DDNb2ALc6QAAAABJRU5ErkJggg==', | |
// Customized Halo - Halo2 | |
Halo2 = function(options) { | |
// possible options: { cellView } | |
this.options = options; | |
this.$el = undefined; | |
} | |
; | |
Halo2.prototype = { | |
_options: { | |
tinyThreshold: 40, | |
smallThreshold: 80 | |
}, | |
render: function() { | |
var cellView = this.options.cellView, | |
$cell = cellView.$el, | |
cellPos = $cell.offset(), | |
paperPos = $('#paper .paper').offset(), | |
$haloEl = $('<div class="halo surrounding halo2"></div>'), | |
cellSize = cellView.model.attributes.size, | |
width = cellSize.width * paperScroller._sx, | |
height = cellSize.height * paperScroller._sy, | |
_options = this._options, | |
$handleEl = $('<div class="handle config"></div>'); | |
$haloEl.css('width', width + 'px') | |
.css('height', height + 'px') | |
.css('left', (cellPos.left - paperPos.left) + 'px') | |
.css('top', (cellPos.top - paperPos.top) + 'px') | |
.attr('data-model-id', cellView.model.id) | |
.toggleClass('tiny', width < _options.tinyThreshold && height < _options.tinyThreshold) | |
.toggleClass('small', !$haloEl.hasClass('tiny') && width < _options.smallThreshold && height < _options.smallThreshold); | |
$handleEl.css('background-image', 'url("' + configIcon + '")') | |
.appendTo($haloEl); | |
$haloEl.appendTo(cellView.paper.$el); | |
this.$el = $haloEl; | |
}, | |
remove: function() { | |
if (this.$el) { | |
this.$el.remove(); | |
this.$el = undefined; | |
} | |
}, | |
update: function() { | |
try { | |
var cellView = this.options.cellView, | |
$cell = cellView.$el, | |
cellPos = $cell.offset(), | |
paperPos = $('#paper .paper').offset(), | |
cellSize = cellView.model.attributes.size, | |
width = cellSize.width * paperScroller._sx, | |
height = cellSize.height * paperScroller._sy, | |
_options = this._options, | |
$el = this.$el; | |
$el.css('width', width + 'px') | |
.css('height', height + 'px') | |
.css('left', (cellPos.left - paperPos.left) + 'px') | |
.css('top', (cellPos.top - paperPos.top) + 'px') | |
.toggleClass('tiny', width < _options.tinyThreshold && height < _options.tinyThreshold) | |
.toggleClass('small', !$el.hasClass('tiny') && width < _options.smallThreshold && height < _options.smallThreshold); | |
} catch (error) { | |
console.log(error); | |
} | |
} | |
}; | |
/** | |
* getWordWrapText() | |
* | |
* @param String text | |
* @param Object options | |
*/ | |
function getWordWrapText(text, options) { | |
var lines = joint.util.breakText(text, options).split("\n"), | |
textContent = ''; | |
for (var i = 0, n = lines.length; i < n; i ++) { | |
textContent += '<tspan dy="' + (i > 0 ? 1 : 0) + 'em" x="0" class="v-line">' + lines[i] + '</tspan>'; | |
} | |
return textContent; | |
} | |
/** | |
* wrapText(): Wrap texts in SVG using joint.util.breakText | |
* | |
* @param Array size | |
* @param Bool isOnPaper | |
*/ | |
function wrapText(size, isOnPaper) { | |
var xForms, xFormTranslate; | |
if (isOnPaper) { | |
// Yes, it's on the paper | |
$('.wrap').each(function () { | |
var $this = $(this), | |
klass = $this.attr('class'), | |
model = graph.getCell( $this.parents('[model-id]').attr('model-id') ), | |
modelText = model && model.attributes.textRaw; | |
if (!model) return; | |
model.attributes.attrs.text.text = modelText; | |
$this.html(getWordWrapText(modelText, { width: size[0] })) | |
.attr('fill', '#000') | |
.attr('font-size', '14'); | |
this.transform.translate(null, size[1] / 2); | |
$this.attr('class', klass.replace(/\bwrap\b/, '')); | |
}); | |
} else { | |
// No, it's not on the paper. Then it must be on the STENCIL. No doubt!! | |
$('.wrap').each(function () { | |
var $this = $(this), | |
klass = $this.attr('class'); | |
this.transform.translate(null, size[1] + shapeTextMarginTop); | |
$this.attr('class', klass.replace(/\bwrap\b/, '')); | |
}); | |
} | |
} | |
/** | |
* logStatus() | |
* | |
* @param Any data | |
* @param Number duration milliseconds | |
*/ | |
function logStatus(data, duration) { | |
clearTimeout(logTimerId); | |
$statusBarEl.html(data); | |
if (duration) { | |
logTimerId = setTimeout(function () { $statusBarEl.html(''); }, duration); | |
} | |
} | |
/** | |
* saveGraphAsync() | |
* | |
*/ | |
function saveGraphAsync() { | |
var workflow_draft = graph.toJSON(); | |
workflow_draft.options = { | |
paperWidth: defaultPaperSize[0], | |
paperHeight: defaultPaperSize[1], | |
paperOrigin: {x: 0, y: 0} | |
}; | |
if (paper && paperScroller) { | |
workflow_draft.options = { | |
paperWidth: paper.options.width / paperScroller._sx, | |
paperHeight: paper.options.height / paperScroller._sy, | |
paperOrigin: { | |
x: paper.options.origin.x / paperScroller._sx, | |
y: paper.options.origin.y / paperScroller._sy | |
} | |
} | |
} | |
return $.ajax({ | |
url: gOptions.save_to, | |
type: 'post', | |
dataType: 'json', | |
data: { | |
id: gOptions.workflow_id, | |
workflow_draft: JSON.stringify(workflow_draft) | |
} | |
}); | |
} | |
/** | |
* saveWorkflow() | |
* | |
* @param Function doneCallback | |
*/ | |
function saveWorkflow(doneCallback) { | |
logStatus('<div class="alert alert-info">Saving...</div>'); | |
saveGraphAsync().then(function(data) { | |
configErrors = data.errors; | |
if (data.isValid) { | |
logStatus('<div class="alert alert-success">The workflow has been saved!</div>', 5000); | |
} else { | |
logStatus('<div class="alert alert-warning">The workflow has been saved, BUT we have invalid config.</div>'); | |
} | |
if (doneCallback) { | |
doneCallback(data); | |
} | |
}, function(jqXHR, textStatus, errorThrown) { | |
logStatus('<div class="alert alert-danger">Uh oh, seems we lost connection. The workflow could not be saved.</div>'); | |
}); | |
} | |
/** | |
* cronSaveWorkflow() | |
*/ | |
function cronSaveWorkflow() { | |
if (graphHasChanged) { | |
saveWorkflow(); | |
graphHasChanged = false; | |
} | |
} | |
/** | |
* isAgent() | |
* | |
* @param joint.dia.ElementView|joint.dia.Element cell | |
* @return Bool | |
*/ | |
function isAgent(cell) { | |
if (cell.model) { | |
return (cell.model.attributes.config != undefined); | |
} else { | |
return (cell.attributes.config != undefined); | |
} | |
} | |
/** | |
* validateConnection() | |
* | |
* @param joint.dia.ElementView cellViewS, | |
* @param magnetS | |
* @param joint.dia.ElementView cellViewT, | |
* @param magnetT | |
* @param String end | |
* @param joint.dia.LinkView linkView | |
*/ | |
function validateConnection(cellViewS, magnetS, cellViewT, magnetT, end, linkView) { | |
if (isAgent(cellViewT) && cellViewS.model.id != cellViewT.model.id && | |
cellViewT.model.attributes.cannot_receive_events === false) { | |
return true; | |
} | |
return false; | |
} | |
/** | |
* initializePaper(): Create a graph, paper and wrap the paper in a PaperScroller. | |
*/ | |
function initializePaper() { | |
var workflow_draft = gOptions.workflow_draft, | |
wfdOptions = workflow_draft.options, | |
$paperContainer = $('#paper'); | |
graph = new joint.dia.Graph; | |
paper = new joint.dia.Paper({ | |
width: defaultPaperSize[0], | |
height: defaultPaperSize[1], | |
gridSize: 10, | |
model: graph, | |
async: { batchSize: 1 }, | |
defaultLink: new joint.dia.Link({ | |
attrs: { | |
'.connection': { stroke: '#8d8d94', 'stroke-width': 3 }, | |
'.marker-target': { stroke: '#8d8d94', fill: '#272634', d: 'M5.5,15.499,15.8,21.447,15.8,9.552z' }, | |
'.marker-source': { stroke: '#8d8d94', fill: '#272634' } | |
} | |
}), | |
linkConnectionPoint: joint.util.shapePerimeterConnectionPoint, | |
validateConnection: validateConnection | |
}); | |
paperScroller = new joint.ui.PaperScroller({ | |
paper: paper, | |
autoResizePaper: true, | |
padding: 50, | |
baseWidth: 200, | |
baseHeight: 200 | |
}); | |
$paperContainer.append(paperScroller.$el); | |
paper.on('render:done', function() { | |
var cells = graph.getElements(), | |
cellView, attributes, | |
agentsConfigByType = gOptions.agentsConfigByType, | |
updatedAttrs; | |
if (wfdOptions) { | |
if (wfdOptions.paperOrigin) { | |
paper.setOrigin(workflow_draft.options.paperOrigin.x, workflow_draft.options.paperOrigin.y); | |
nav.updatePaper(paper.options.width, paper.options.height); | |
} | |
if (wfdOptions.paperWidth && wfdOptions.paperHeight) { | |
paper.setDimensions(wfdOptions.paperWidth, wfdOptions.paperHeight); | |
} | |
} | |
wrapText(shapeBigSize, true); | |
for (var i = 0, n = cells.length; i < n; i ++) { | |
if (!isAgent(cells[i])) continue; | |
attributes = cells[i].attributes; | |
cellView = paper.findViewByModel(cells[i]); | |
checkAgentIfConfiguredAndDoIt(cellView); | |
initAgentSubtitle(cellView); | |
if (attributes.is_goal) { | |
showGoalMarker(cellView); | |
} | |
updatedAttrs = agentsConfigByType[attributes.config.type] && agentsConfigByType[attributes.config.type].attrs; | |
if (updatedAttrs) { | |
attributes.config = agentsConfigByType[attributes.config.type].config; | |
if (updatedAttrs.rect) { | |
cells[i].attr('rect/fill', updatedAttrs.rect.fill); | |
cells[i].attr('rect/stroke', updatedAttrs.rect.stroke); | |
} else if (updatedAttrs.circle) { | |
cells[i].attr('circle/fill', updatedAttrs.circle.fill); | |
cells[i].attr('circle/stroke', updatedAttrs.circle.stroke); | |
} else if (updatedAttrs.path) { | |
cells[i].attr('path/fill', updatedAttrs.path.fill); | |
cells[i].attr('path/stroke', updatedAttrs.path.stroke); | |
} | |
cells[i].attr('image/xlink:href', updatedAttrs.image['xlink:href']); | |
} | |
} | |
if (!gOptions.wf_valid) { | |
logStatus('<div class="alert alert-warning">Some agents have invalid configuration.</div>'); | |
} | |
configErrors = gOptions.wf_errors; | |
paperScroller.zoomToFit({ | |
padding: 100, | |
maxScaleX: 1, | |
maxScaleY: 1 | |
}); | |
setInterval(cronSaveWorkflow, wfAutoSaveInterval); | |
}); | |
paper.on('cell:pointerdown', function(cellView) { | |
if (isAgent(cellView)) { | |
agentDownFlag = true; | |
} | |
}); | |
paper.on('cell:pointerup', function() { | |
agentDownFlag = false; | |
}); | |
paper.on('blank:pointerdown', paperScroller.startPanning); | |
$paperContainer.on('contextmenu', function(e) { e.preventDefault(); }); | |
snaplines = new joint.ui.Snaplines({ paper: paper }); | |
snaplines.startListening(); | |
graph.on('add', function(cell) { | |
if (isAgent(cell)) { | |
var $image = $('image', '[model-id=' + cell.id + ']'), | |
image = cell.attr('image'), | |
newX = (shapeBigSize[0] - iconSize[0]) / 2, | |
newY = shapeBigSize[1] / 2 - iconSize[1] - 10; | |
cell.set('size', { width: shapeBigSize[0], height: shapeBigSize[1] }); | |
$image.attr('x', newX).attr('y', newY); | |
image.x = newX; | |
image.y = newY; | |
wrapText(shapeBigSize, true); | |
initializeDefaultConfigValues(cell); | |
} | |
}); | |
if (workflow_draft.cells && workflow_draft.cells.length > 0) { | |
graph.fromJSON(workflow_draft); | |
} else { | |
setInterval(cronSaveWorkflow, wfAutoSaveInterval); | |
} | |
graph.on('change', function(cell) { | |
if (cell.id != chart.id && linkDownFlag == false) { | |
graphHasChanged = true; | |
} | |
}); | |
graph.on('remove', function(cell) { | |
if (cell instanceof joint.dia.Link && cell.get('target').id) { | |
var link = cell, | |
source = graph.getCell(link.get('source').id), | |
sourceAttr = source.attributes, | |
groupKey = link.attributes.groupKey; | |
if (groupKey) { | |
sourceAttr.targetIds[groupKey] = _.without(sourceAttr.targetIds[groupKey], link.get('target').id); | |
} else { | |
sourceAttr.targetIds = _.without(sourceAttr.targetIds, link.get('target').id); | |
} | |
} | |
if (cell.id != chart.id && linkDownFlag == false) { | |
graphHasChanged = true; | |
} | |
}); | |
paper.on('scale resize', function() { | |
for (var modelId in halo2) { | |
halo2[modelId].update(); | |
} | |
}); | |
} | |
/** | |
* createCustomShapes(): Create custom elements. | |
*/ | |
function createCustomShapes() { | |
joint.shapes.custom = {}; | |
joint.shapes.custom.CircleEx = joint.shapes.basic.Circle.extend({ | |
markup: '<g class="scalable"><circle/></g><image/><text/>', | |
defaults: joint.util.deepSupplement({ | |
type: 'custom.CircleEx' | |
}, joint.shapes.basic.Circle.prototype.defaults) | |
}); | |
joint.shapes.custom.RectEx = joint.shapes.basic.Rect.extend({ | |
markup: '<g class="scalable"><rect/></g><image/><text/>', | |
defaults: joint.util.deepSupplement({ | |
type: 'custom.RectEx' | |
}, joint.shapes.basic.Rect.prototype.defaults) | |
}); | |
joint.shapes.custom.PathEx = joint.shapes.basic.Path.extend({ | |
markup: '<g class="scalable"><path/></g><image/><text/>', | |
defaults: joint.util.deepSupplement({ | |
type: 'custom.PathEx' | |
}, joint.shapes.basic.Path.prototype.defaults) | |
}); | |
} | |
/** | |
* initializeStencil(): Create and populate stencil. | |
* | |
* @param Object stencilData | |
*/ | |
function initializeStencil(stencilData) { | |
stencil = new joint.ui.Stencil({ | |
paper: paperScroller, | |
width: (shapeSize[0] + shapeMargin[0]) * 3, | |
groups: stencilData.groups, | |
dropAnimation: { duration: 200, easing: 'swing' } | |
}); | |
$('#stencil').append(stencil.render().el) | |
.find('.content').mCustomScrollbar({ theme: 'minimal-dark' }); | |
stencil.$el.on('contextmenu', function(e) { e.preventDefault(); }); | |
$('.stencil-paper-drag').on('contextmenu', function(e) { e.preventDefault(); }); | |
var layoutOptions = { | |
columns: 3, | |
columnWidth: shapeSize[0] + shapeMargin[0], | |
rowHeight: shapeSize[1] * 2 + shapeTextMarginTop | |
}, | |
shapes = stencilData.shapes; | |
_.each(stencilData.groups, function(group, name) { | |
stencil.load(shapes[name], name); | |
joint.layout.GridLayout.layout(stencil.getGraph(name), layoutOptions); | |
stencil.getPaper(name).fitToContent(1, 1, 30); | |
}); | |
wrapText(shapeSize); | |
} | |
/** | |
* initializeHaloAndInspector() | |
*/ | |
function initializeHaloAndInspector() { | |
paper.on('cell:mouseover', function(cellView) { | |
if (linkDownFlag || agentDownFlag) return; | |
// We don't want a Halo for links. | |
if (cellView.model instanceof joint.dia.Link || !isAgent(cellView)) return; | |
var model = cellView.model, | |
modelId = model.id, | |
attributes = model.attributes, | |
configHandleOptions; | |
showAgentSubtitle(cellView, false); | |
if (halo && halo.options.cellView === cellView) return; | |
// Removes the sticky halo | |
if (halo2[modelId]) { | |
halo2[modelId].remove(); | |
delete halo2[modelId]; | |
} | |
halo = new joint.ui.Halo({ cellView: cellView }); | |
halo.removeHandle('clone'); | |
halo.removeHandle('resize'); | |
halo.removeHandle('rotate'); | |
halo.removeHandle('fork'); | |
if (attributes.cannot_create_events) { | |
halo.removeHandle('link'); | |
} | |
configHandleOptions = { | |
name: 'config', | |
position: 'n' | |
}; | |
if (isAgentConfigured(cellView)) { | |
configHandleOptions.icon = configIconGreen; | |
} else { | |
configHandleOptions.icon = configIcon; | |
configHandleOptions.attrs = { | |
'.config': { | |
'data-toggle': 'tooltip', | |
'data-placement': 'top', | |
'title': configErrors[modelId] ? configErrors[modelId].join('\n') : 'Invalid config' | |
} | |
}; | |
} | |
halo.addHandle(configHandleOptions); | |
halo.render(); | |
$('.handle.config[data-toggle="tooltip"]').tooltip(); | |
halo.on('action:link:add', function(link) { | |
var sourceId = link.get('source').id, | |
targetId = link.get('target').id, | |
source = graph.getCell(sourceId), | |
sourceAttr = source.attributes, | |
sourceType = sourceAttr.config.type, | |
activeSliceIndex = chart.prop('active-slice'); | |
linkDownFlag = false; | |
chart.remove(); | |
if ( !sourceId || !targetId || | |
(sourceType == 'Split' && activeSliceIndex === undefined) || | |
(sourceType == 'Balance' && activeSliceIndex === undefined) || | |
(sourceType == 'Send Email' && activeSliceIndex === undefined) || | |
(sourceType == 'Twitter Status' && activeSliceIndex === undefined)) { | |
link.remove(); | |
} else { | |
if (sourceType == 'Split' || sourceType == 'Balance' || sourceType == 'Send Email' || | |
sourceType == 'Twitter Status' || sourceType == 'Twitter Message') { | |
var chartData = chart.get('series')[0].data[activeSliceIndex], | |
groupKey = chartData.groupKey; | |
link.label(0, { position: 0.5, attrs: { text: { text: chartData.label } } }); | |
link.attributes.groupKey = groupKey; | |
if (!sourceAttr.targetIds) { | |
sourceAttr.targetIds = {}; | |
} | |
if (!sourceAttr.targetIds[groupKey]) { | |
sourceAttr.targetIds[groupKey] = []; | |
} | |
sourceAttr.targetIds[groupKey].push(targetId); | |
} | |
else { | |
if (!sourceAttr.targetIds) { | |
sourceAttr.targetIds = []; | |
} | |
sourceAttr.targetIds.push(targetId); | |
} | |
graph.trigger('change', link); | |
} | |
chart.prop('active-slice', undefined); | |
if (halo2[sourceId] === undefined) { | |
halo && (halo.remove(), halo = undefined); | |
checkAgentIfConfiguredAndDoIt(paper.findViewByModel(source)); | |
} | |
if (targetId) { | |
paper.trigger('cell:mouseover', paper.findViewByModel(graph.getCell(targetId))); | |
} | |
}); | |
halo.on('action:config:pointerdown', function(e) { | |
e.stopPropagation(); | |
if (model instanceof joint.dia.Link) return; | |
createInspector(cellView); | |
}); | |
halo.on('action:link:pointerdown', function(e) { | |
var bbox = model.getBBox(), | |
pieValue, chartView, $chartViewDataEl; | |
linkDownFlag = true; | |
// Display pie chart for Split and Balance agents. | |
if (attributes.config.type === 'Split') { | |
var criteria = attributes.criteriaUI, | |
serieData = []; | |
if (criteria && criteria.length > 0) { | |
chart.prop('position', { x: bbox.x + bbox.width - chartPieRadius, y: bbox.y + bbox.height / 2 - chartPieRadius }); | |
for (var i = 0, n = criteria.length, v = parseFloat((100 / n).toFixed(2)); i < n; i ++) { | |
serieData.push({ | |
value: v, | |
label: criteria[i].weight_label + ' (' + criteria[i].weight + ')', | |
fill: chartSerieFillColor[i], | |
groupKey: criteria[i].weight_label.toString() | |
}); | |
} | |
chart.prop('series', [{ data: serieData }]); | |
chart.prop('active-slice', undefined); | |
graph.addCell(chart); | |
chart.toFront(); | |
chartView = paper.findViewByModel(chart); | |
$chartViewDataEl = chartView.$('.data'); | |
chartView.$('.slice-inner-label').each(function () { | |
var $textEl = $(this); | |
$textEl.attr('data-slice', $textEl.parents('.slice').attr('data-slice')); | |
$textEl.appendTo($chartViewDataEl); | |
}); | |
chartView.on('mouseover', function(slice, e) { | |
var $slice = $('.slice[data-serie="' + slice.serieIndex + '"][data-slice="' + slice.sliceIndex + '"]', $chartViewDataEl), | |
elSlice = V($slice[0]); | |
// _.each(this.$('.slice'), function(slice) { V(slice).scale(1); $('.slice-inner-label', $(slice)).css('display', 'none'); }); | |
_.each($('.slice', $chartViewDataEl), function(slice) { V(slice).scale(1); }); | |
$('.slice-inner-label', $chartViewDataEl).css('display', 'none'); | |
elSlice.scale(1.2); | |
chart.prop('active-slice', slice.sliceIndex); | |
// $('.slice-inner-label', $slice).css('display', 'block'); | |
$('.slice-inner-label[data-slice="' + slice.sliceIndex + '"]', $chartViewDataEl).css('display', 'block'); | |
}); | |
} | |
} | |
else if (attributes.config.type === 'Balance') { | |
chart.prop('position', { x: bbox.x + bbox.width - chartPieRadius, y: bbox.y + bbox.height / 2 - chartPieRadius }); | |
chart.prop('series', [{ data: [ | |
{ value: 50, label: '50', fill: chartSerieFillColor[0], groupKey: '50' }, | |
{ value: 50, label: '50', fill: chartSerieFillColor[1], groupKey: '50' } | |
] }]); | |
chart.prop('active-slice', undefined); | |
graph.addCell(chart); | |
chart.toFront(); | |
chartView = paper.findViewByModel(chart); | |
$chartViewDataEl = chartView.$('.data'); | |
chartView.$('.slice-inner-label').each(function () { | |
var $textEl = $(this); | |
$textEl.attr('data-slice', $textEl.parents('.slice').attr('data-slice')); | |
$textEl.appendTo($chartViewDataEl); | |
}); | |
chartView.on('mouseover', function(slice, e) { | |
var $slice = $('.slice[data-serie="' + slice.serieIndex + '"][data-slice="' + slice.sliceIndex + '"]', $chartViewDataEl), | |
elSlice = V($slice[0]); | |
// _.each(this.$('.slice'), function(slice) { V(slice).scale(1); $('.slice-inner-label', $(slice)).css('display', 'none'); }); | |
_.each($('.slice', $chartViewDataEl), function(slice) { V(slice).scale(1); }); | |
$('.slice-inner-label', $chartViewDataEl).css('display', 'none'); | |
elSlice.scale(1.2); | |
chart.prop('active-slice', slice.sliceIndex); | |
// $('.slice-inner-label', $slice).css('display', 'block'); | |
$('.slice-inner-label[data-slice="' + slice.sliceIndex + '"]', $chartViewDataEl).css('display', 'block'); | |
}); | |
} | |
else if (attributes.config.type === 'Send Email') { | |
chart.prop('position', { x: bbox.x + bbox.width - chartPieRadius, y: bbox.y + bbox.height / 2 - chartPieRadius }); | |
pieValue = 100 / 7; | |
chart.prop('series', [{ data: [ | |
{ value: pieValue, label: 'On Bounce', fill: chartSerieFillColor[0], groupKey: 'on_bounce' }, | |
{ value: pieValue, label: 'On Click', fill: chartSerieFillColor[1], groupKey: 'on_click' }, | |
{ value: pieValue, label: 'On Open', fill: chartSerieFillColor[2], groupKey: 'on_open' }, | |
{ value: pieValue, label: 'On Unsubscribe', fill: chartSerieFillColor[3], groupKey: 'on_unsubscribe' }, | |
{ value: pieValue, label: 'On Reply', fill: chartSerieFillColor[4], groupKey: 'on_reply' }, | |
{ value: pieValue, label: 'On Send', fill: chartSerieFillColor[5], groupKey: 'on_send' }, | |
{ value: pieValue, label: 'On No Response', fill: chartSerieFillColor[6], groupKey: 'on_no_response' } | |
] }]); | |
chart.prop('active-slice', undefined); | |
graph.addCell(chart); | |
chart.toFront(); | |
chartView = paper.findViewByModel(chart); | |
$chartViewDataEl = chartView.$('.data'); | |
chartView.$('.slice-inner-label').each(function () { | |
var $textEl = $(this); | |
$textEl.attr('data-slice', $textEl.parents('.slice').attr('data-slice')); | |
$textEl.appendTo($chartViewDataEl); | |
}); | |
chartView.on('mouseover', function(slice, e) { | |
var $slice = $('.slice[data-serie="' + slice.serieIndex + '"][data-slice="' + slice.sliceIndex + '"]', $chartViewDataEl), | |
elSlice = V($slice[0]); | |
// _.each(this.$('.slice'), function(slice) { V(slice).scale(1); $('.slice-inner-label', $(slice)).css('display', 'none'); }); | |
_.each($('.slice', $chartViewDataEl), function(slice) { V(slice).scale(1); }); | |
$('.slice-inner-label', $chartViewDataEl).css('display', 'none'); | |
elSlice.scale(1.2); | |
chart.prop('active-slice', slice.sliceIndex); | |
// $('.slice-inner-label', $slice).css('display', 'block'); | |
$('.slice-inner-label[data-slice="' + slice.sliceIndex + '"]', $chartViewDataEl).css('display', 'block'); | |
}); | |
} | |
else if (attributes.config.type === 'Twitter Status') { | |
chart.prop('position', { x: bbox.x + bbox.width - chartPieRadius, y: bbox.y + bbox.height / 2 - chartPieRadius }); | |
pieValue = 100 / 4; | |
chart.prop('series', [{ data: [ | |
{ value: pieValue, label: 'Following Us', fill: chartSerieFillColor[0], groupKey: 'following_us' }, | |
{ value: pieValue, label: 'Not Following Us', fill: chartSerieFillColor[1], groupKey: 'not_following_us' }, | |
{ value: pieValue, label: 'Blocking Us', fill: chartSerieFillColor[2], groupKey: 'blocking_us' }, | |
{ value: pieValue, label: 'Muted By Us', fill: chartSerieFillColor[3], groupKey: 'muted_by_us' } | |
] }]); | |
chart.prop('active-slice', undefined); | |
graph.addCell(chart); | |
chart.toFront(); | |
chartView = paper.findViewByModel(chart); | |
$chartViewDataEl = chartView.$('.data'); | |
chartView.$('.slice-inner-label').each(function () { | |
var $textEl = $(this); | |
$textEl.attr('data-slice', $textEl.parents('.slice').attr('data-slice')); | |
$textEl.appendTo($chartViewDataEl); | |
}); | |
chartView.on('mouseover', function(slice, e) { | |
var $slice = $('.slice[data-serie="' + slice.serieIndex + '"][data-slice="' + slice.sliceIndex + '"]', $chartViewDataEl), | |
elSlice = V($slice[0]); | |
// _.each(this.$('.slice'), function(slice) { V(slice).scale(1); $('.slice-inner-label', $(slice)).css('display', 'none'); }); | |
_.each($('.slice', $chartViewDataEl), function(slice) { V(slice).scale(1); }); | |
$('.slice-inner-label', $chartViewDataEl).css('display', 'none'); | |
elSlice.scale(1.2); | |
chart.prop('active-slice', slice.sliceIndex); | |
// $('.slice-inner-label', $slice).css('display', 'block'); | |
$('.slice-inner-label[data-slice="' + slice.sliceIndex + '"]', $chartViewDataEl).css('display', 'block'); | |
}); | |
} | |
else if (attributes.config.type === 'Twitter Message') { | |
chart.prop('position', { x: bbox.x + bbox.width - chartPieRadius, y: bbox.y + bbox.height / 2 - chartPieRadius }); | |
pieValue = 100 / 5; | |
chart.prop('series', [{ data: [ | |
{ value: pieValue, label: '@Mentions Us', fill: chartSerieFillColor[0], groupKey: 'mentions_us' }, | |
{ value: pieValue, label: 'DMs Us', fill: chartSerieFillColor[1], groupKey: 'dms_us' }, | |
{ value: pieValue, label: 'Blocking Us', fill: chartSerieFillColor[2], groupKey: 'blocking_us' }, | |
{ value: pieValue, label: 'On Send', fill: chartSerieFillColor[3], groupKey: 'on_send' }, | |
{ value: pieValue, label: 'On No Response', fill: chartSerieFillColor[4], groupKey: 'on_no_response' } | |
] }]); | |
chart.prop('active-slice', undefined); | |
graph.addCell(chart); | |
chart.toFront(); | |
chartView = paper.findViewByModel(chart); | |
$chartViewDataEl = chartView.$('.data'); | |
chartView.$('.slice-inner-label').each(function () { | |
var $textEl = $(this); | |
$textEl.attr('data-slice', $textEl.parents('.slice').attr('data-slice')); | |
$textEl.appendTo($chartViewDataEl); | |
}); | |
chartView.on('mouseover', function(slice, e) { | |
var $slice = $('.slice[data-serie="' + slice.serieIndex + '"][data-slice="' + slice.sliceIndex + '"]', $chartViewDataEl), | |
elSlice = V($slice[0]); | |
// _.each(this.$('.slice'), function(slice) { V(slice).scale(1); $('.slice-inner-label', $(slice)).css('display', 'none'); }); | |
_.each($('.slice', $chartViewDataEl), function(slice) { V(slice).scale(1); }); | |
$('.slice-inner-label', $chartViewDataEl).css('display', 'none'); | |
elSlice.scale(1.2); | |
chart.prop('active-slice', slice.sliceIndex); | |
// $('.slice-inner-label', $slice).css('display', 'block'); | |
$('.slice-inner-label[data-slice="' + slice.sliceIndex + '"]', $chartViewDataEl).css('display', 'block'); | |
}); | |
} | |
}); | |
}); | |
paper.on('cell:mouseout', function(cellView, e) { | |
if (linkDownFlag || agentDownFlag || !isAgent(cellView)) return; | |
var $te = $(e.relatedTarget); | |
if (($te.hasClass('handle') && ($te.parents('.halo2').length == 0)) || | |
$te.parents('[model-id=' + cellView.model.id + ']').length > 0) return; | |
if (halo) { | |
halo.remove(); | |
halo = undefined; | |
checkAgentIfConfiguredAndDoIt(cellView); | |
} | |
showAgentSubtitle(cellView); | |
}); | |
paper.$el.on('mouseenter', '.halo2 .handle.config', function() { | |
var modelId = $(this).parents('.halo2').attr('data-model-id'); | |
paper.trigger('cell:mouseover', paper.findViewByModel(paper.getModelById(modelId))); | |
}); | |
paper.$el.on('mouseleave', '.halo .handle', function(e) { | |
if (!halo || linkDownFlag || agentDownFlag) return; | |
var $te = $(e.relatedTarget), | |
cellView = halo.options.cellView; | |
if ($te.parents('[model-id=' + cellView.model.id + ']').length > 0 || | |
($te.hasClass('handle') && ($te.parents('.halo2').length == 0))) return; | |
checkAgentIfConfiguredAndDoIt(cellView); | |
halo.remove(); | |
halo = undefined; | |
showAgentSubtitle(cellView); | |
}); | |
} | |
/** | |
* createInspector() | |
* | |
* @param joint.dia.ElementView cellView | |
*/ | |
function createInspector(cellView) { | |
// No need to re-render inspector if the cellView didn't change. | |
// ------------------------------------------------------------- | |
if (!inspector || inspector.options.cellView !== cellView) { | |
if (inspector) { | |
// Set unsaved changes to the model and clean up the old inspector if there was one. | |
inspector.updateCell(); | |
inspector.remove(); | |
} | |
var $dlgEl = $('#inspector_dialog'), | |
attributes = cellView.model.attributes, | |
config = attributes.config, | |
agentType = config.type, | |
addServiceURL = '', | |
fields = config.fields, | |
inputs = { | |
is_goal: { type: 'toggle', label: 'Set this as goal' } | |
}, | |
$isGoalDivEl; | |
for (var i = 0, n = fields.length; i < n; i ++) { | |
inputs[fields[i]] = {}; | |
} | |
initializeInspectorInputs(inputs, attributes); | |
inspector = new joint.ui.Inspector({ | |
cellView: cellView, | |
inputs: inputs, | |
live: false | |
}); | |
$('[data-field="schedule"]', '#inspector_dialog_header').remove(); | |
$dlgEl.find('.inspector-container').html(inspector.render().el); | |
$dlgEl.find('.modal-title') | |
.html(attributes.attrs.text.text) | |
.after($('[data-field="schedule"]', '.inspector').addClass('pull-right')); | |
$dlgEl.find('.description').html( config.description || '' ); | |
$dlgEl.find('.btn-list-add').addClass('btn btn-xs'); | |
$dlgEl.find('.btn-list-del').addClass('btn btn-xs pull-right').html('×'); | |
if (agentHasField(cellView, 'segment_id')) { | |
$dlgEl.find('[data-field="segment_id"]').append('<a href="' + gOptions.add_segment_url + '" class="btn btn-xs btn-primary">Add New Segment</a>'); | |
} | |
if (agentHasField(cellView, 'service_id')) { | |
switch (agentType) { | |
case 'Facebook Update': | |
case 'Twitter Action': | |
case 'Twitter Message': | |
case 'Twitter Status': | |
addServiceURL = gOptions.add_twitter_service_url; break; | |
case 'Send Email': | |
addServiceURL = gOptions.add_email_service_url; break; | |
} | |
$dlgEl.find('[data-field="service_id"]').append('<a href="' + addServiceURL + '" class="btn btn-xs btn-primary">Add New Service</a>'); | |
} | |
if (agentHasField(cellView, 'message_template_id')) { | |
$dlgEl.find('[data-field="message_template_id"]').append('<a href="' + gOptions.add_message_template_url + '" class="btn btn-xs btn-primary">Add New Message Template</a>'); | |
} | |
if (agentHasField(cellView, 'campaign_list_id')) { | |
$dlgEl.find('[data-field="campaign_list_id"]').append('<a href="' + gOptions.add_campaign_list_url + '" class="btn btn-xs btn-primary">Add New Campaign List</a>'); | |
} | |
if (agentType == 'Twitter Action') { | |
var actionValue = $dlgEl.find('[data-attribute="criteria/action"]').val(); | |
$dlgEl.find('[data-field="criteria/list_name"]').toggle(actionValue == 'list' || actionValue == 'unlist'); | |
} | |
$dlgEl.find('select > option[value=""]').prop('disabled', true); | |
$dlgEl.find('.modal-footer').find('[data-field="is_goal"]').remove(); | |
var dataFieldId, $dataFieldDivEl, $inputEl; | |
$dlgEl.find('[data-type="toggle"]').each(function () { | |
$inputEl = $(this); | |
$dataFieldDivEl = $inputEl.parents('[data-field]'); | |
dataFieldId = $dataFieldDivEl.attr('data-field'); | |
if (dataFieldId === 'is_goal') { | |
$dataFieldDivEl.prependTo($dlgEl.find('.modal-footer')); | |
} | |
$dataFieldDivEl | |
.addClass('checkbox') | |
.css('float', 'left') | |
.css('margin-top', '5px'); | |
$inputEl.attr('id', dataFieldId).insertBefore($('label', $dataFieldDivEl)); | |
$('label', $dataFieldDivEl).attr('for', dataFieldId); | |
$('div.toggle', $dataFieldDivEl).remove(); | |
}); | |
// $('.toggle', $isGoalDivEl).remove(); | |
$dlgEl.modal('show'); | |
} | |
} | |
/** | |
* readableScheduleText() | |
* | |
* @param String text | |
* @return String | |
*/ | |
function readableScheduleText(text) { | |
text = text.toString(); | |
if (!text || text.trim().length === 0) return ''; | |
var matches, | |
timeUnitsSingular = { 'm': 'minute', 'h': 'hour', 'd': 'day' }, | |
timeUnitsPlural = { 'm': 'minutes', 'h': 'hours', 'd': 'days' }; | |
if (matches = text.match(/^every_(\d+)(.+)/)) { | |
text = 'Every ' + ( parseInt(matches[1], 10) > 1 ? matches[1] + ' ' + timeUnitsPlural[matches[2]] : timeUnitsSingular[matches[2]] ); | |
} | |
else if (matches = text.match(/^(\d+)(.+)/)) { | |
text = matches[1] + ' ' + matches[2].toUpperCase(); | |
} | |
else { | |
text = text.charAt(0).toUpperCase() + text.slice(1); | |
} | |
return text; | |
} | |
/** | |
* initializeDefaultConfigValues() | |
* | |
* @param joint.dia.Cell cell | |
*/ | |
function initializeDefaultConfigValues(cell) { | |
var attributes = cell.attributes, | |
agentType = attributes.config.type; | |
if (agentHasField(cell, 'workflow_id')) { | |
attributes.workflow_id = gOptions.workflow_id; | |
} | |
if (agentType === 'Has Facebook' || | |
agentType === 'Has Email' || | |
agentType === 'Has Twitter') { | |
if (agentHasField(cell, 'criteria')) { | |
attributes.criteria = attributes.config.criteria; | |
} | |
} | |
attributes.schedule = attributes.default_schedule; | |
} | |
/** | |
* initializeInspectorInputs() | |
* | |
* @param Object inputs | |
* @param Object attributes | |
*/ | |
function initializeInspectorInputs(inputs, attributes) { | |
var config = attributes.config, | |
criteria = config.criteria, | |
tmp, options, | |
type = config.type; | |
if (type.match(/Segment$/)) { | |
type = type.match(/(.*) Segment$/)[1].toLowerCase(); | |
} | |
for (var field in inputs) { | |
switch (field) { | |
case 'segment_id': | |
tmp = config.dropdowns.segments; | |
options = [{ value: '', content: 'Choose segment..' }]; | |
for (var i = 0, n = tmp.length; i < n; i ++) { | |
options.push({ value: tmp[i].value, content: tmp[i].name }); | |
} | |
inputs[field] = { | |
type: 'select', label: 'Segments', options: options, index: 1 | |
}; | |
// Assume these agents are triggers and let's add another trigger-specific field | |
inputs.only_new = { | |
type: 'toggle', label: ['Only new ', type, ' that matches this segment'].join('') | |
}; | |
break; | |
case 'schedule': | |
tmp = config.dropdowns.schedule; | |
options = []; | |
for (var i = 0, n = tmp.length; i < n; i ++) { | |
options.push({ value: tmp[i], content: readableScheduleText(tmp[i]) }); | |
} | |
inputs[field] = { | |
type: 'select', label: 'Schedule', options: options | |
}; | |
break; | |
case 'service_id': | |
tmp = config.dropdowns.services; | |
if (config.type === 'Twitter Action' || config.type === 'Twitter Status' || config.type === 'Twitter Message') { | |
tmp = config.dropdowns.twitter_services; | |
} | |
else if (config.type === 'Facebook Update') { | |
tmp = config.dropdowns.facebook_services; | |
} | |
else if (config.type === 'Send Email') { | |
tmp = config.dropdowns.email_services; | |
} | |
options = [{ value: '', content: 'Choose service..' }]; | |
for (var i = 0, n = tmp.length; i < n; i ++) { | |
options.push({ value: tmp[i].value, content: tmp[i].name }); | |
} | |
inputs[field] = { | |
type: 'select', label: 'Services', options: options, index: 1 | |
}; | |
break; | |
case 'campaign_list_id': | |
tmp = config.dropdowns.campaigns_list; | |
options = [{ value: '', content: 'Choose campaign..' }]; | |
for (var i in tmp) { | |
options.push({ value: tmp[i].id, content: tmp[i].name }); | |
} | |
inputs[field] = { | |
type: 'select', label: 'Campaigns', options: options, index: 1 | |
}; | |
options = [{ value: '', content: 'Choose stage..' }]; | |
if (attributes.campaign_list_id) { | |
tmp = config.dropdowns.campaigns_list[attributes.campaign_list_id].stages; | |
for (var i in tmp) { | |
options.push({ value: tmp[i].id, content: tmp[i].name }); | |
} | |
} | |
inputs['stage_id'] = { | |
type: 'select', label: 'Stages', options: options, index: 2 | |
}; | |
// Assume this is a campaign list agent and let's add another campaign-specific field | |
inputs.only_new = { | |
type: 'toggle', label: 'Only new list that matches this segment' | |
}; | |
break; | |
case 'message_template_id': | |
tmp = config.dropdowns.message_templates; | |
options = [{ value: '', content: 'Choose message template..' }]; | |
for (var i = 0, n = tmp.length; i < n; i ++) { | |
options.push({ value: tmp[i].message_template.id, content: tmp[i].message_template.name }); | |
} | |
inputs[field] = { | |
type: 'select', label: 'Message Template', options: options | |
}; | |
break; | |
case 'user_ids': | |
tmp = config.dropdowns.users; | |
options = [{ value: '', content: 'Choose a user..' }]; | |
for (var i = 0, n = tmp.length; i < n; i ++) { | |
options.push({ value: tmp[i].user.id, content: tmp[i].user.name + ' (' + tmp[i].user.login + ')' }); | |
} | |
inputs[field] = { | |
type: 'select', label: 'User', options: options | |
}; | |
break; | |
case 'criteria': | |
if (config.type == "Add Field" || config.type == "Modify Field") { | |
inputs.criteria = { | |
type: 'list', | |
item: { | |
type: 'object', | |
properties: { | |
field_name: { type: 'text', label: 'Field Name' }, | |
field_value: { type: 'text', label: 'Field Value' } | |
} | |
}, | |
label: 'Click the {+} button to add a field and value.', | |
attrs: { | |
label: { class: 'custom-label' } | |
}, | |
index: 99 | |
}; | |
} | |
else if (config.type == 'Filter') { | |
inputs.criteria = { type: 'text', label: 'Criteria', index: 99 }; | |
} | |
else if (config.type == 'Twitter Action') { | |
inputs.criteria = { | |
action: { | |
type: 'select', | |
label: 'Action', | |
options: [ | |
{ value: '', content: 'Choose action..' }, | |
{ value: 'follow', content: 'Follow' }, | |
{ value: 'unfollow', content: 'Unfollow' }, | |
{ value: 'list', content: 'List' }, | |
{ value: 'unlist', content: 'Unlist' } | |
], | |
index: 98 | |
}, | |
list_name: { type: 'text', label: 'List Name', index: 99 } | |
}; | |
} | |
else if (config.type == "Split") { | |
inputs.criteriaUI = { | |
type: 'list', | |
item: { | |
type: 'object', | |
properties: { | |
weight_label: { type: 'text', label: 'Label' }, | |
weight: { type: 'text', label: 'Weight' } | |
} | |
}, | |
label: 'Click the {+} button to add a weight.', | |
attrs: { | |
label: { class: 'custom-label' } | |
}, | |
index: 99 | |
}; | |
} | |
else if (config.type == 'Delay') { | |
inputs.criteria = { | |
length: { type: 'text', label: 'Length', attrs: { type: 'number' }, index: 98 }, | |
unit: { | |
type: 'select', | |
label: 'Type', | |
options: [ | |
{ value: '', content: 'Choose..' }, | |
{ value: 'minutes', content: 'Minutes' }, | |
{ value: 'hours', content: 'Hours' }, | |
{ value: 'days', content: 'Days' }, | |
{ value: 'weeks', content: 'Weeks' }, | |
{ value: 'months', content: 'Months' } | |
], | |
index: 99 | |
} | |
}; | |
} | |
else if (config.type == 'Twitter Message') { | |
tmp = config.dropdowns.message_type; | |
options = [{ value: '', content: 'Choose message type..' }]; | |
for (var i = 0, n = tmp.length; i < n; i ++) { | |
options.push({ value: tmp[i], content: tmp[i].replace(/\w/, function(match, capture) { return match.toUpperCase(); }) }); | |
} | |
inputs.criteria = { | |
type: 'select', label: 'Message Type', options: options, index: 99 | |
}; | |
} | |
else if (config.type == 'Limit') { | |
inputs.criteria = { type: 'text', label: 'Limit', index: 99 }; | |
} | |
else if (config.type == "Update Field") { | |
inputs.criteria = { | |
type: 'list', | |
item: { | |
type: 'object', | |
properties: { | |
field_name: { type: 'text', label: 'Field Name' }, | |
field_value: { type: 'text', label: 'Field Value' } | |
} | |
}, | |
label: 'Click the {+} button to add a field and value.', | |
attrs: { | |
label: { class: 'custom-label' } | |
}, | |
index: 99 | |
}; | |
} | |
else if (config.type == 'Has Profile') { | |
tmp = config.dropdowns.services; | |
options = [{ value: '', content: 'Choose..' }]; | |
for (var i = 0, n = tmp.length; i < n; i ++) { | |
options.push({ value: tmp[i], content: tmp[i].replace(/\w/, function(match, capture) { return match.toUpperCase(); }) }); | |
} | |
inputs.criteria = { type: 'select', label: 'Has Profile', options: options, index: 99 }; | |
} | |
else if (config.type == 'Modify Campaign List') { | |
inputs.criteria = { | |
type: 'select', | |
label: 'Action', | |
options: [ | |
{ value: '', content: 'Choose action..' }, | |
{ value: 'add', content: 'Add' }, | |
{ value: 'remove', content: 'Remove' } | |
], | |
index: 99 | |
}; | |
} | |
else { | |
delete inputs.criteria; | |
} | |
break; | |
default: | |
} | |
} | |
} | |
/** | |
* agentHasField() | |
* | |
* @param joint.dia.ElementView|joint.dia.Cell cell | |
* @param String fieldName | |
* @return Bool | |
*/ | |
function agentHasField(cell, fieldName) { | |
var model = cell.model || cell, | |
fields = model.attributes.config.fields; | |
return (fields.indexOf(fieldName) >= 0); | |
} | |
/** | |
* isAgentConfigured() | |
* | |
* @param joint.dia.ElementView cellView | |
* @return Bool | |
*/ | |
function isAgentConfigured(cellView) { | |
if (!cellView || !cellView.model) return false; | |
var attributes = cellView.model.attributes, | |
agentType = attributes.config.type, | |
data, k; | |
if (agentHasField(cellView, 'criteria')) { | |
data = attributes.criteria; | |
if (!data) return false; | |
if (data instanceof Array && data.length === 0) return false; | |
if (agentType == 'Add Field' || agentType == 'Update Field') { | |
for (var i = 0, n = data.length; i < n; i ++) { | |
if (data[i].field_name.toString().match(/^\s*$/) || data[i].field_value.toString().match(/^\s*$/)) { | |
return false; | |
} | |
} | |
} else if (agentType == 'Filter') { | |
if (data.toString().match(/^\s*$/)) return false; | |
} else if (agentType == 'Twitter Action') { | |
if (!data.action || data.action.toString().match(/^\s*$/)) return false; | |
if (data.action.toString().match(/^(list|unlist)$/) && data.list_name.toString().match(/^\s*$/)) return false; | |
} else if (agentType == 'Split') { | |
data = attributes.criteriaUI; | |
for (var i = 0, n = data.length; i < n; i ++) { | |
if (data[i].weight_label.toString().match(/^\s*$/) || data[i].weight.toString().match(/^\s*$/)) { | |
return false; | |
} | |
} | |
} else if (agentType == 'Twitter Message') { | |
if (data.toString().match(/^\s*$/)) return false; | |
} else if (agentType == 'Delay') { | |
if (data.length.toString().match(/^\s*$/) || !data.unit || data.unit.toString().match(/^\s*$/)) return false; | |
} else if (agentType == 'Limit') { | |
if (data.toString().match(/^\s*$/)) return false; | |
} else if (agentType == 'Has Profile') { | |
if (data.toString().match(/^\s*$/)) return false; | |
} else { | |
for (k in data) { | |
if (data[k].toString().match(/^\s*$/)) { | |
return false; | |
} | |
} | |
} | |
} | |
if (agentHasField(cellView, 'segment_id')) { | |
data = attributes.segment_id; | |
if (!data) return false; | |
} | |
if (agentHasField(cellView, 'service_id')) { | |
data = attributes.service_id; | |
if (!data) return false; | |
} | |
if (agentHasField(cellView, 'message_template_id')) { | |
data = attributes.message_template_id; | |
if (!data) return false; | |
} | |
if (agentHasField(cellView, 'campaign_list_id')) { | |
data = attributes.campaign_list_id; | |
if (!data || !attributes.stage_id) return false; | |
} | |
if (agentHasField(cellView, 'user_ids')) { | |
data = attributes.user_ids; | |
if (!data) return false; | |
} | |
return true; | |
} | |
/** | |
* checkAgentIfConfiguredAndDoIt() | |
* | |
* @param joint.dia.ElementView cellView | |
*/ | |
function checkAgentIfConfiguredAndDoIt(cellView) { | |
var modelId = cellView.model.id; | |
if (isAgentConfigured(cellView)) | |
{ | |
// In case agent is configured, remove config link. | |
halo2[modelId] && halo2[modelId].remove(); | |
delete halo2[modelId]; | |
} | |
else | |
{ | |
// This case implies agent is not configured. | |
if (halo2[modelId] === undefined) { | |
var h = new Halo2({ cellView: cellView }); | |
h.render(); | |
halo2[modelId] = h; | |
} | |
} | |
} | |
/** | |
* initializeNavigator() | |
*/ | |
function initializeNavigator() { | |
nav = new joint.ui.Navigator({ | |
paperScroller: paperScroller, | |
width: 200, | |
height: 100, | |
padding: 10, | |
zoomOptions: { max: zoomMax, min: zoomMin } | |
}); | |
nav.$el.appendTo('#navigator'); | |
nav.render(); | |
$('#zoom-in').on('click', function() { | |
paperScroller.zoom(zoomStep, { max: zoomMax }); | |
}); | |
$('#zoom-out').on('click', function() { | |
paperScroller.zoom(-zoomStep, { min: zoomMin }); | |
}); | |
$('#toggle-panning').on('click', function() { | |
}); | |
} | |
/** | |
* clearGraph() | |
*/ | |
function clearGraph() { | |
for (var k in halo2) { | |
halo2[k].remove(); | |
delete halo2[k]; | |
} | |
graph.clear(); | |
} | |
/** | |
* initAgentSubtitle() | |
* | |
* @param joint.dia.ElementView cellView | |
*/ | |
function initAgentSubtitle(cellView) { | |
var subtitle = cellView.model.attributes.subtitle, | |
subtitleAlt = cellView.model.attributes.subtitleAlt, | |
$cellEl = cellView.$el, | |
subtitleTextNode = $cellEl.find('.agent-subtitle'); | |
if (subtitle || subtitleAlt) { | |
if (subtitleTextNode.length == 0) { | |
subtitleTextNode = V('<text class="agent-subtitle" display="null" xml:space="preserve" font-size="14" text-anchor="middle" fill="#fff" y="0.8em" transform="matrix(1 0 0 1 0 0)"></text>').node; | |
cellView.el.appendChild(subtitleTextNode); | |
subtitleTextNode = $(subtitleTextNode); | |
} | |
subtitleTextNode.attr('data-normal-text', subtitle).attr('data-hover-text', subtitleAlt); | |
if (subtitle) { | |
showAgentSubtitle(cellView); | |
} | |
} | |
else { | |
if (subtitleTextNode.length > 0) { | |
subtitleTextNode.remove(); | |
} | |
} | |
} | |
function showAgentSubtitle(cellView, showNormalText) { | |
var $cellEl = cellView.$el, | |
subtitleTextNode = $cellEl.find('.agent-subtitle'), | |
subtitleNormalText = subtitleTextNode.attr('data-normal-text'), | |
subtitleHoverText = subtitleTextNode.attr('data-hover-text'), | |
$textTitleEl = $cellEl.find('text.title'), | |
x, y; | |
if (subtitleTextNode.length == 0) return; | |
if (showNormalText === undefined) { | |
showNormalText = true; | |
} | |
if (showNormalText) { | |
$textTitleEl.show(); | |
subtitleNormalText = subtitleNormalText || ""; | |
x = shapeBigSize[0] / 2; | |
y = shapeBigSize[1] / 2 + $textTitleEl[0].getBBox().height + 5; | |
subtitleTextNode.html(getWordWrapText(subtitleNormalText, { width: shapeBigSize[0] }))[0].transform.translate(x, y); | |
} | |
else if (!showNormalText && subtitleHoverText !== undefined) { | |
$textTitleEl.hide(); | |
x = shapeBigSize[0] / 2; | |
y = shapeBigSize[1] / 2; | |
subtitleTextNode.html(getWordWrapText(subtitleHoverText, { width: shapeBigSize[0] }))[0].transform.translate(x, y); | |
} | |
} | |
/** | |
* showGoalMarker() | |
* | |
* @param joint.dia.ElementView cellView | |
*/ | |
function showGoalMarker(cellView) { | |
cellView.el.appendChild($goalMarkerEl); | |
} | |
/** | |
* initializeMisc() | |
*/ | |
function initializeMisc() { | |
$('#btn_clear').on('click', function() { | |
clearGraph(); | |
}); | |
$('#btn_save').on('click', function() { | |
saveWorkflow(); | |
}); | |
$('#btn_save_close').on('click', function() { | |
saveWorkflow(function (data) { | |
window.location.replace(gOptions.workflows_path); | |
}); | |
}); | |
$('#btn_open_png').on('click', function() { | |
paper.toPNG(function (dataURL) { | |
window.open(dataURL); | |
}); | |
}); | |
$('#inspector_dialog').on('hide.bs.modal', function() { | |
if (inspector) { | |
inspector.remove(); | |
inspector = null; | |
} | |
}); | |
$('#inspector_btn_save').on('click', function() { | |
if (inspector) { | |
inspector.updateCell(); | |
var cellView = inspector.options.cellView, | |
attributes = cellView.model.attributes, | |
agentType = attributes.config.type, | |
tmp; | |
// Special process for Split agent | |
if (agentType === 'Split') { | |
attributes.criteria = {}; | |
for (var i = 0, criteriaUI = attributes.criteriaUI, n = criteriaUI.length; i < n; i ++) { | |
attributes.criteria[criteriaUI[i].weight_label] = criteriaUI[i].weight; | |
} | |
} | |
checkAgentIfConfiguredAndDoIt(cellView); | |
if (isAgentConfigured(cellView)) { | |
if (agentHasField(cellView, 'segment_id')) { | |
attributes.subtitle = $('select[data-attribute="segment_id"] option:selected', '#inspector_dialog').html(); | |
} | |
else { | |
switch (agentType) { | |
case 'Facebook Update': | |
case 'Twitter Message': | |
case 'Twitter Status': | |
attributes.subtitle = $('select[data-attribute="service_id"] option:selected', '#inspector_dialog').html(); | |
break; | |
case 'Send Email': | |
attributes.subtitle = $('select[data-attribute="message_template_id"] option:selected', '#inspector_dialog').html(); | |
break; | |
case 'Twitter Action': | |
attributes.subtitle = $('select[data-attribute="criteria/action"] option:selected', '#inspector_dialog').html(); | |
break; | |
case 'Delay': | |
attributes.subtitle = [attributes.criteria.length, $('select[data-attribute="criteria/unit"] option:selected', '#inspector_dialog').html()].join(' '); | |
break; | |
case 'Limit': | |
attributes.subtitle = attributes.criteria.toString(); | |
break; | |
case 'Has Profile': | |
attributes.subtitle = $('select[data-attribute="criteria"] option:selected', '#inspector_dialog').html(); | |
break; | |
case 'Split': | |
attributes.subtitle = $('[data-attribute="criteriaUI"] .list-item', '#inspector_dialog').length.toString(); | |
break; | |
case 'Campaign List': | |
attributes.subtitleAlt = [$('[data-attribute="campaign_list_id"] option:selected', '#inspector_dialog').html(), $('[data-attribute="stage_id"] option:selected', '#inspector_dialog').html()].join(': '); | |
break; | |
case 'Modify Campaign List': | |
attributes.subtitle = $('select[data-attribute="criteria"] option:selected', '#inspector_dialog').html(); | |
attributes.subtitleAlt = [$('[data-attribute="campaign_list_id"] option:selected', '#inspector_dialog').html(), $('[data-attribute="stage_id"] option:selected', '#inspector_dialog').html()].join(': '); | |
break; | |
default: | |
} | |
} | |
} | |
else { | |
delete attributes.subtitle; | |
} | |
initAgentSubtitle(cellView); | |
if (attributes.is_goal) { | |
for (var i = 0, cells = graph.getCells(), n = cells.length; i < n; i ++) { | |
if (cells[i] === cellView.model) continue; | |
delete cells[i].attributes.is_goal; | |
} | |
showGoalMarker(cellView); | |
} | |
$('#inspector_dialog').modal('hide'); | |
} | |
}); | |
$('#inspector_dialog').on('click', '.btn-list-add', function () { | |
$('.btn-list-del', '#inspector_dialog').addClass('btn btn-xs pull-right').html('×'); | |
if (inspector.options.cellView.model.attributes.config.type == 'Split' && $('.list-item', '#inspector_dialog').length >= 5) { | |
$(this).prop('disabled', true); | |
} | |
}) | |
.on('click', '[data-attribute="criteria/action"]', function() { | |
var value = $(this).val(); | |
$('[data-field="criteria/list_name"]', '#inspector_dialog').toggle(value == 'list' || value == 'unlist'); | |
}) | |
.on('change', '[data-attribute="campaign_list_id"]', function () { | |
var options = '<option value="" selected disabled>Choose stage..</option>', | |
campaign_list_id = $(this).val(); | |
$('[data-field="stage_id"]', '#inspector_dialog').toggle(campaign_list_id != ''); | |
if (campaign_list_id) { | |
for (var i = 0, | |
stages = inspector.options.cellView.model.attributes.config.dropdowns.campaigns_list[campaign_list_id].stages, | |
n = stages.length; | |
i < n; i ++) { | |
options += '<option value="' + stages[i].id + '">' + stages[i].name + '</option>'; | |
} | |
} | |
$('[data-attribute="stage_id"]', '#inspector_dialog').html(options); | |
}); | |
$(document).on('click.btnListDel', '.btn-list-del', function () { | |
if (inspector.options.cellView.model.attributes.config.type == 'Split') { | |
$('.btn-list-add', '#inspector_dialog').prop('disabled', false); | |
} | |
}); | |
} | |
return { | |
shapeSize: shapeSize, | |
iconSize: iconSize, | |
init: function(stencilData, options) { | |
gOptions = options; | |
initializePaper(); | |
initializeStencil(stencilData); | |
initializeHaloAndInspector(); | |
initializeNavigator(); | |
initializeMisc(); | |
}, | |
createCustomShapes: function() { | |
createCustomShapes(); | |
}, | |
/* for debugging */ | |
exposed: function() { | |
return { | |
paper: paper, | |
graph: graph, | |
paperScroller: paperScroller, | |
nav: nav, | |
stencil: stencil, | |
snaplines: snaplines, | |
halo: halo, | |
inspector: inspector, | |
chart: chart, | |
gOptions: gOptions | |
}; | |
} | |
}; | |
}(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment