Last active
February 16, 2021 02:24
-
-
Save hasantayyar/694c86f6ae10df9384f340ee14b74595 to your computer and use it in GitHub Desktop.
extracte the state machien svg graph library from aws bundle
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
/*global dagreD3*/ | |
/*global d3*/ | |
/*global WheelEvent*/ | |
/*global window */ | |
(function () { | |
"use strict"; | |
var module = angular.module("WorkflowGraph", []); | |
function intersectRect(node, point) { | |
var x = node.x; | |
var y = node.y; | |
// Rectangle intersection algorithm from: | |
// http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes | |
var dx = point.x - x; | |
var dy = point.y - y; | |
var w = node.width / 2; | |
var h = node.height / 2; | |
var sx, sy; | |
if (Math.abs(dy) * w > Math.abs(dx) * h) { | |
// Intersection is top or bottom of rect. | |
if (dy < 0) { | |
h = -h; | |
} | |
sx = dy === 0 ? 0 : h * dx / dy; | |
sy = h; | |
} else { | |
// Intersection is left or right of rect. | |
if (dx < 0) { | |
w = -w; | |
} | |
sx = w; | |
sy = dx === 0 ? 0 : w * dy / dx; | |
} | |
return [{x: x + sx, y: y + sy}]; | |
} | |
function intersectEllipse(node, rx, ry, point) { | |
// Formulae from: http://mathworld.wolfram.com/Ellipse-LineIntersection.html | |
var cx = node.x; | |
var cy = node.y; | |
var px = cx - point.x; | |
var py = cy - point.y; | |
var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px); | |
var dx = Math.abs(rx * ry * px / det); | |
if (point.x < cx) { | |
dx = -dx; | |
} | |
var dy = Math.abs(rx * ry * py / det); | |
if (point.y < cy) { | |
dy = -dy; | |
} | |
return [{x: cx + dx, y: cy + dy}]; | |
} | |
function intersectCircle(node, rx, point) { | |
return intersectEllipse(node, rx, rx, point); | |
} | |
var renderAnchorNode = function(text) { | |
return function(root, node) { | |
var view = {}; | |
root.classed("anchor", true); | |
root.append("text") | |
.attr("class", "label") | |
.append("tspan") | |
.attr("xml:space", "preserve") | |
.attr("text-anchor", "middle") | |
.attr("alignment-baseline", "central") | |
.text(text); | |
var padding = 20; | |
var bbox = root.node().getBBox(); | |
var width = bbox.width + padding; | |
var height = bbox.height + padding; | |
var r = Math.max(width, height) / 2; | |
root.insert("circle", ":first-child") | |
.classed("shape", true) | |
.attr("x", -bbox.width / 2) | |
.attr("y", -bbox.height / 2) | |
.attr("r", r); | |
node.width = width; | |
node.height = height; | |
view.intersect = function(point) { | |
return intersectCircle(node, r, point); | |
}; | |
return view; | |
}; | |
}; | |
var renderStartNode = renderAnchorNode("Start"); | |
var renderEndNode = renderAnchorNode("End"); | |
var renderStateNode = function(root, node) { | |
root.classed("state", true) | |
.classed(node.state.Type, true) | |
.classed("NotYetStarted", true); | |
if (node.state.Type === "Parallel") { | |
return renderParallelState(root, node); | |
} else { | |
return renderRegularState(root, node); | |
} | |
}; | |
var renderRegularState = function(root, node) { | |
var view = {}; | |
root.append("text") | |
.attr("class", "label") | |
.append("tspan") | |
.attr("xml:space", "preserve") | |
.attr("text-anchor", "middle") | |
.attr("alignment-baseline", "central") | |
.text(node.stateName); | |
var padding = 20; | |
var bbox = root.node().getBBox(); | |
var width = bbox.width + padding; | |
var height = bbox.height + padding; | |
var rect = root.insert("rect", ":first-child") | |
.classed("shape", true) | |
.attr("rx", 5) | |
.attr("ry", 5) | |
.attr("x", -width / 2) | |
.attr("y", -height / 2) | |
.attr("width", width) | |
.attr("height", height); | |
node.width = width; | |
node.height = height; | |
view.intersect = function(point, direction) { | |
return intersectRect(node, point); | |
}; | |
return view; | |
}; | |
function renderParallelState(root, node) { | |
var view = {}; | |
var p = 20; | |
var pt = 40; | |
var o = 20; | |
var s = 20; | |
var branchesRoot = root.append("g").classed("branches", true); | |
var branches = []; | |
var dx = 0; | |
for (var i = 0; i < node.state.Branches.length; i++) { | |
var branchDefinition = node.state.Branches[i]; | |
var branchRoot = branchesRoot.append("g").classed("branch", true); | |
var branchGraph = renderBranch(branchRoot, branchDefinition); | |
var branchBbox = branchRoot.node().getBBox(); | |
branches.push({ | |
dx: dx, | |
height: branchBbox.height, | |
width: branchBbox.width, | |
startNode: branchGraph.node("state-" + branchDefinition.StartAt) | |
}); | |
branchRoot.attr("transform", "translate(" + dx + ",0)"); | |
dx += branchBbox.width + s; | |
} | |
branchesRoot.attr("transform", "translate(" + p + "," + (o + pt) + ")"); | |
var branchesBbox = branchesRoot.node().getBBox(); | |
var bw = branchesBbox.width; | |
var bh = branchesBbox.height; | |
var width = 2 * p + bw; | |
var height = o + pt + bh + p; | |
for (var j = 0; j < branches.length; j++) { | |
var branch = branches[j]; | |
renderArrow(root, [ | |
{ x: width / 2, y: o }, | |
{ x: width / 2, y: o + pt / 2 }, | |
{ | |
x: p + branch.dx + branch.startNode.x, | |
y: o + pt / 2 | |
}, | |
{ | |
x: p + branch.dx + branch.startNode.x, | |
y: o + pt | |
} | |
]); | |
} | |
var rect = root.insert("rect", ":first-child") | |
.classed("shape", true) | |
.attr("rx", Math.min(width, height)/5) | |
.attr("ry", Math.min(width, height)/5) | |
.attr("x", 0) | |
.attr("y", o) | |
.attr("width", width) | |
.attr("height", pt + bh + p); | |
root.attr("transform", "translate(" + (-width / 2) + "," + (-height / 2) + ")"); | |
node.width = width; | |
node.height = height; | |
view.intersect = function(point, direction) { | |
if (direction === "in") { | |
return [ | |
{ x: node.x, y: node.y - node.height / 2 + o}, | |
{ x: node.x, y: node.y - node.height / 2 } | |
]; | |
} | |
return intersectRect(node, point); | |
}; | |
return view; | |
} | |
var idCounter = 0; | |
function uniqueId(prefix) { | |
var id = ++idCounter; | |
return prefix + id; | |
} | |
function renderArrow(root, points, hideArrowHead) { | |
var arrowheadId = uniqueId("arrowhead"); | |
root.append("path") | |
.classed("path", true) | |
.style("fill", "none") | |
.attr("marker-end", "url(#" + arrowheadId + ")") | |
.attr("d", function() { | |
return d3.svg.line() | |
.x(function(d) { return d.x; }) | |
.y(function(d) { return d.y; }) | |
.interpolate("basis") | |
(points); | |
}); | |
if (!hideArrowHead) { | |
root.append("defs") | |
.append("marker") | |
.attr("id", arrowheadId) | |
.attr("viewBox", "0 0 10 10") | |
.attr("refX", 9) | |
.attr("refY", 5) | |
.attr("markerUnits", "strokeWidth") | |
.attr("markerWidth", 8) | |
.attr("markerHeight", 6) | |
.attr("orient", "auto") | |
.append("path") | |
.attr("d", "M 0 0 L 10 5 L 0 10 z"); | |
} | |
} | |
function renderEdge(edgeRoot, edge, fromNode, toNode) { | |
var points = []; | |
if (fromNode.view.intersect) { | |
var nextPoint = edge.points[1]; | |
var outIntersect = fromNode.view.intersect(nextPoint, "out"); | |
for (var i = 0; i < outIntersect.length; i++) { | |
points.push(outIntersect[i]); | |
} | |
} else { | |
points.push(edge.points[0]); | |
} | |
for (var j = 1; j < edge.points.length - 1; j++) { | |
points.push(edge.points[j]); | |
} | |
if (toNode.view.intersect) { | |
var previousPoint = edge.points[edge.points.length - 2]; | |
var inIntersect = toNode.view.intersect(previousPoint, "in").reverse(); | |
for (var k = 0; k < inIntersect.length; k++) { | |
points.push(inIntersect[k]); | |
} | |
} else { | |
points.push(edge.points[edge.points.length - 1]); | |
} | |
renderArrow(edgeRoot, points, toNode.state && toNode.state.Type === "Parallel"); | |
} | |
function createNodesAndEdges(branch, createAnchors) { | |
var g = new dagreD3.graphlib.Graph().setGraph({ ranksep: 25, edgesep: 30, nodesep: 40, rankdir: "TB" }); | |
if (createAnchors) { | |
g.setNode("start", { renderer: renderStartNode }); | |
g.setNode("end", { renderer: renderEndNode }); | |
} | |
for (var stateName in branch.States) { | |
var state = branch.States[stateName]; | |
var id = "state-" + stateName; | |
g.setNode(id, { | |
renderer: renderStateNode, | |
stateName: stateName, | |
state: state, | |
}); | |
var next = getAllNextStates(state); | |
for (var j = 0; j < next.length; j++) { | |
g.setEdge(id, "state-" + next[j], {}); | |
} | |
if (createAnchors && branch.StartAt === stateName) { | |
g.setEdge("start", id, {}); | |
} | |
if (createAnchors && (state.End || state.Type === "Succeed" || state.Type === "Fail")) { | |
g.setEdge(id, "end", {}); | |
} | |
} | |
return g; | |
} | |
function renderBranch(root, branch, createAnchors) { | |
var graph = createNodesAndEdges(branch, createAnchors); | |
// create the nodes | |
var nodeContainers = root.append("g").classed("nodes", true).selectAll("g.node-container") | |
.data($.map(graph.nodes(), function(x) { return graph.node(x); })) | |
.enter() | |
.append("g").classed("node-container", true); | |
nodeContainers.append("g").classed("node", true) | |
.each(function(node) { | |
var nodeRoot = d3.select(this); | |
node.view = node.renderer(nodeRoot, node); | |
}); | |
// compute the layout | |
dagreD3.dagre.layout(graph); | |
// position the nodes | |
nodeContainers.attr("transform", function(node) { | |
return "translate(" + node.x + "," + node.y + ")"; | |
}); | |
// create the edges | |
root.append("g").classed("edges", true).selectAll("g.edge") | |
.data(graph.edges()) | |
.enter() | |
.append("g") | |
.classed("edge", true) | |
.each(function(e) { | |
var edge = graph.edge(e); | |
var fromNode = graph.node(e.v); | |
var toNode = graph.node(e.w); | |
var edgeRoot = d3.select(this); | |
renderEdge(edgeRoot, edge, fromNode, toNode); | |
}); | |
return graph; | |
} | |
function getAllNextStates(state) { | |
var transitions = []; | |
if (state.Next) { | |
transitions.push(state.Next); | |
} | |
if (state.Catch) { | |
for (var i = 0; i < state.Catch.length; i++) { | |
var catchClause = state.Catch[i]; | |
if (catchClause.Next) { | |
transitions.push(catchClause.Next); | |
} | |
} | |
} | |
if (state.Choices) { | |
for (var j = 0; j < state.Choices.length; j++) { | |
var choice = state.Choices[j]; | |
if (choice.Next) { | |
transitions.push(choice.Next); | |
} | |
} | |
} | |
if (state.Default) { | |
transitions.push(state.Default); | |
} | |
return transitions; | |
} | |
/* | |
* Set the size of the svg element according to the options provided and the proportions | |
* of the rendered graph, then scale and center the graph within the svg canvas. | |
* | |
* Options: { | |
* width: number, | |
* height: number, | |
* maxWidth: number, | |
* maxHeight: number | |
* } | |
*/ | |
function fitGraph(svg, options) { | |
var graphRoot = svg.select("g"); | |
// Dagre has a bug that makes it position nodes too close to the borders and they can sometimes | |
// overflow the bounds of the graph by a few pixels. We add some padding to mitigate the issue. | |
var padding = 40; | |
// The dimensions of the rendered graph. | |
var bbox = graphRoot.node().getBBox(); | |
var graphWidth = bbox.width + 2 * padding; | |
var graphHeight = bbox.height + 2 * padding; | |
// Compute the scaling factor to fit the rendered graph within the maximum or target bounds. | |
var scalingX = 1; | |
var scalingY = 1; | |
if (graphWidth > (options.width || options.maxWidth)) { | |
scalingX = (options.width || options.maxWidth) / graphWidth; | |
} | |
if (graphHeight > (options.height || options.maxHeight)) { | |
scalingY = (options.height || options.maxHeight) / graphHeight; | |
} | |
var scaling = Math.min(scalingX, scalingY); | |
// Set the size of the svg element. | |
var svgWidth = options.width || graphWidth * scaling; | |
var svgHeight = options.height || graphHeight * scaling; | |
if (!options.resizeGraph) { | |
svg.attr("width", svgWidth); | |
svg.attr("height", svgHeight); | |
} | |
// Center the graph within the svg canvas. | |
var dx = (svgWidth - (graphWidth * scaling))/2 + padding * scaling; | |
var dy = (svgHeight - (graphHeight * scaling))/2 + padding * scaling; | |
graphRoot.attr("transform", "translate(" + [dx, dy] + ") scale(" + scaling + ")"); | |
svg.call(d3.behavior.drag().on("drag", function() { | |
transformGraph(graphRoot, d3.event.dx, d3.event.dy, 0); | |
})); | |
return { | |
dx: dx, | |
dy: dy, | |
scaling: scaling | |
}; | |
} | |
function transformGraph(graph, translateX, translateY, scaleDiff) { | |
var t = d3.transform(graph.attr("transform")), | |
translate = t.translate, | |
scale = t.scale; | |
var scaling = Math.min(scale[0], scale[1]); | |
graph.attr("transform", "translate ( " + [translate[0] + translateX, translate[1] + translateY] + ") scale(" + scaling * (1 + scaleDiff) + ")"); | |
} | |
/** | |
* Workflow Graph Directive. | |
* | |
* Usage example: | |
* <workflow-graph definition="..." latest-state-instances="..." interactive="true" node-callback="..." /> | |
* | |
* Draws a graph representation of a workflow using the Dagre library. | |
* | |
* Attributes: | |
* definition: (object) The ASL definition. | |
* resize-graph: (boolean) Whether to resize the graph to fit the bounds. | |
* interactive: (boolean) Whether to react to hovers and clicks on the graph elements. | |
* nodeCallback: (function) A function to invoke when a node is clicked. The corresponding node object will be passed as parameter (see createNodesAndEdges()). | |
* latest-state-instances: (object) A map of state names to the latest state instance of that state (see AwsSimpleWorkflowService.computeLatestsStateInstances()). | |
*/ | |
module.directive("workflowGraph", ["$window", function($window) { | |
function getGraphSVGContainer(element) { | |
return d3.select(element.find("svg.sfn-workflow-graph")[0]); | |
} | |
function getGraphRoot(element) { | |
var svg = getGraphSVGContainer(element); | |
return svg.select("g"); | |
} | |
var windowElement = angular.element($window); | |
return { | |
restrict: "E", | |
scope: { | |
definition: "=", | |
latestStateInstances: "=", | |
nodeCallback: "&nodeCallback", | |
interactive: "@", | |
resizeGraph: "@", | |
showLegend: "<" | |
}, | |
transclude: { | |
topControls: "?sfnGraphTopControls", | |
bottomControls: "?sfnGraphBottomControls", | |
}, | |
templateUrl: "/partials/workflowGraph.html", | |
link: function(scope, elem, attrs) { | |
var layoutContainerNode = $(".awsui-app-layout__content"); | |
var parentNode = elem.parent(); | |
scope.centerGraph = function() { | |
resetGraph(); | |
}; | |
scope.zoomInGraph = function() { | |
transformGraph(getGraphRoot(elem), 0, 0, 0.4); | |
}; | |
scope.zoomOutGraph = function() { | |
transformGraph(getGraphRoot(elem), 0, 0, -0.4); | |
}; | |
windowElement.on("resize", resetGraph); | |
scope.$on("$destroy", function() { | |
windowElement.off("resize", resetGraph); | |
}); | |
scope.$on('changeOrientation', resetGraph); | |
function clearGraph() { | |
var svg = getGraphSVGContainer(elem); | |
svg.selectAll("*").remove(); | |
} | |
function showScrollMessage() { | |
var scrollMessage = elem.find(".workflow-graph-scroll-message"); | |
scrollMessage.stop(true); | |
scrollMessage.fadeIn().delay(3000).fadeOut(); | |
} | |
function renderGraph(definition) { | |
var svg = getGraphSVGContainer(elem); | |
svg.selectAll("*").remove(); | |
var graphRoot = svg.append("g"); | |
// Layout and render the graph. | |
renderBranch(graphRoot, definition, true); | |
var fitTransform = fitGraph(svg, { | |
width: elem.parent().width(), | |
maxHeight: parentNode.height(), | |
resizeGraph: scope.resizeGraph | |
}); | |
// enable scroll to zoom while Ctrl or Cmd is pressed | |
svg.call(d3.behavior.zoom().on("zoom", function() { | |
var sourceEvent = d3.event.sourceEvent; | |
if (sourceEvent && (sourceEvent.ctrlKey || sourceEvent.metaKey)) { | |
graphRoot.attr("transform", | |
"translate(" + | |
[fitTransform.dx + d3.event.translate[0], fitTransform.dy + d3.event.translate[1]] + | |
") scale(" + | |
(fitTransform.scaling * d3.event.scale) + ")" | |
); | |
} else if (sourceEvent instanceof WheelEvent){ | |
// Default action is prevented by d3. Allow window to scroll normally | |
var y = layoutContainerNode.scrollTop(); | |
layoutContainerNode.scrollTop(y + sourceEvent.deltaY); | |
showScrollMessage(); | |
} else if (window.MouseWheelEvent && (sourceEvent instanceof window.MouseWheelEvent)) { | |
// IE11 fires a MouseWheelEvent which does not allow scrolling | |
showScrollMessage(); | |
} | |
})); | |
if (scope.interactive) { | |
// Add mouseup events to each STATE node in the graph. | |
svg.select("g.nodes").selectAll(".node.state") | |
.on("mouseup", function(d, event) { | |
var node = d3.select(this); | |
if (!d3.event.handled) { | |
// events are propagated in parent elements, this ensure we only run this for the inner-most element. | |
d3.event.handled = true; | |
if (!node.classed("NotYetStarted")) { | |
graphRoot.selectAll(".node.selected").classed("selected", false); | |
node.classed("selected", true); | |
if (scope.nodeCallback !== null) { | |
scope.$applyAsync(function() { | |
scope.nodeCallback()(d.stateName); | |
}); | |
} | |
} | |
} | |
}) | |
.on("mouseover", function(d, event) { | |
var node = d3.select(this); | |
if (!d3.event.handled) { | |
d3.event.handled = true; | |
graphRoot.selectAll(".node.hovered").classed("hovered", false); | |
node.classed("hovered", true); | |
} | |
}); | |
// Unselect/hover when clicking/hovering out of graph elements. | |
svg.on("mouseup", function(d, event) { | |
if (!d3.event.handled) { | |
graphRoot.selectAll(".node.selected").classed("selected", false); | |
} | |
}) | |
.on("mouseover", function(d, event) { | |
if (!d3.event.handled) { | |
d3.event.handled = true; | |
graphRoot.selectAll(".node.hovered").classed("hovered", false); | |
} | |
}); | |
} | |
} | |
function colorGraph() { | |
if (scope.latestStateInstances) { | |
var svg = getGraphSVGContainer(elem); | |
svg.selectAll(".node.state").each(function(node) { | |
var latestStateInstance = scope.latestStateInstances[node.stateName]; | |
var status = "NotYetStarted"; | |
if (latestStateInstance) { | |
status = latestStateInstance.status; | |
} | |
d3.select(this) | |
.classed("NotYetStarted", false) | |
.classed("Succeeded", false) | |
.classed("Failed", false) | |
.classed("Cancelled", false) | |
.classed("InProgress", false) | |
.classed(status, true); | |
}); | |
} | |
} | |
function resetGraph() { | |
if (scope.definition) { | |
renderGraph(scope.definition); | |
colorGraph(); | |
} | |
} | |
scope.$watch("definition", function() { | |
try { | |
if (scope.definition === "") { | |
clearGraph(); | |
} else if (scope.definition) { | |
renderGraph(scope.definition); | |
} | |
colorGraph(); | |
scope.error = null; | |
} catch (e) { | |
console.error(e); | |
scope.error = e; | |
} | |
}, true); | |
scope.$watch("latestStateInstances", function() { | |
try { | |
colorGraph(); | |
scope.error = null; | |
} catch (e) { | |
console.error(e); | |
scope.error = e; | |
} | |
}, true); | |
} | |
}; | |
}]); | |
}()); | |
(function () { | |
"use strict"; | |
var graphDetailsDirective = angular.module("WorkflowDetails", ["AwsSimpleWorkflowService"]); | |
/** | |
* Workflow details UI. | |
*/ | |
graphDetailsDirective.directive('workflowDetails', function () { | |
return { | |
restrict: "E", | |
scope: { | |
details: "=" | |
}, | |
link: function (scope, element, attrs) { | |
// observe changes in attribute - could also be scope.$watch | |
scope.$watch('details', function (value) { | |
if (value) { | |
scope.details = value; | |
} | |
}); | |
}, | |
templateUrl: "/partials/workflowDetails.html" | |
}; | |
}); | |
}()); | |
(function() { | |
"use strict"; | |
angular.module("WorkflowEditor", []) | |
.directive("workflowEditor", ["$timeout", function($timeout) { | |
function link($scope, element) { | |
$scope.graphClass = "col-s-5"; | |
$scope.codeEditorClass = "col-s-7"; | |
$scope.applyHorizontalOrientation = function() { | |
$scope.graphClass = "col-s-12"; | |
$scope.codeEditorClass = "col-s-12"; | |
// Notify on the next $digest after the new css has been applied to the DOM. | |
$timeout(function() { | |
$scope.$broadcast('changeOrientation'); | |
}); | |
}; | |
$scope.applyVerticalOrientation = function() { | |
$scope.graphClass = "col-s-5"; | |
$scope.codeEditorClass = "col-s-7"; | |
$timeout(function() { | |
$scope.$broadcast('changeOrientation'); | |
}); | |
}; | |
} | |
return { | |
restrict: "E", | |
templateUrl: "/partials/workflowEditor.html", | |
link: link, | |
controller: "workflowEditorController", | |
controllerAs: "workflowEditorCtrl", | |
bindToController: true, | |
transclude: { | |
editorDescription: "?workflowEditorDesciption" | |
}, | |
scope: { | |
editorTitle: "=", | |
definitionString: "=", | |
renderedDefinitionString: "=", | |
validationError: "=", | |
validationErrorMessage: "=", | |
errorMessage: "=?", | |
showSchemaCodeError: "@", | |
loadingGraph: "=", | |
readOnly: "=" | |
} | |
}; | |
}]); | |
}()); | |
(function () { | |
"use strict"; | |
var tabDirective = angular.module("CoreComponents", []); | |
/** | |
* Tab View Directive | |
*/ | |
tabDirective.directive('tabset', function() { | |
return { | |
restrict: 'E', | |
transclude: true, | |
scope: { }, | |
templateUrl: '/partials/tabset.html', | |
bindToController: true, | |
controllerAs: 'tabset', | |
controller: function($scope, $timeout) { | |
var self = this; | |
self.tabs = []; | |
self.addTab = function addTab(tab) { | |
self.tabs.push(tab); | |
if(self.tabs.length === 1) { | |
tab.active = true; | |
} | |
}; | |
self.select = function(selectedTab) { | |
angular.forEach(self.tabs, function(tab) { | |
if(tab.active && tab !== selectedTab) { | |
tab.active = false; | |
} | |
}); | |
selectedTab.active = true; | |
/* IMPORTANT | |
* We flush the angular events to ensure the selected tab is displayed before triggering the callback. | |
*/ | |
$timeout(function() { | |
selectedTab.onClickCallback(); | |
}); | |
}; | |
} | |
}; | |
}); | |
tabDirective.directive('tab', function() { | |
return { | |
restrict: 'E', | |
transclude: true, | |
template: '<div role="tabpanel" class="tabpanel awsui-container" ng-show="active" ng-transclude></div>', | |
require: '^tabset', | |
scope: { | |
heading: '@', | |
onClickCallback: '&' | |
}, | |
link: function(scope, elem, attr, tabsetCtrl) { | |
scope.active = false; | |
tabsetCtrl.addTab(scope); | |
} | |
}; | |
}); | |
}());(function() { | |
"use strict"; | |
var module = angular.module("NewExecutionModal", ["ExecutionModule"]); | |
module.directive("newExecutionModal", [ | |
function() { | |
function link() { } | |
return { | |
restrict: "E", | |
templateUrl: "/partials/newExecutionModal.html", | |
link: link, | |
controller: "newExecutionModalController", | |
controllerAs: "newExecutionModalCtrl", | |
bindToController: true, | |
scope: { | |
visible: "=", | |
stateMachineArn: "@", | |
updateStateMachineSuccess: "=", | |
updateStateMachineSuccessMessage: "=?", | |
input: "=" | |
} | |
}; | |
}]); | |
}()); | |
(function() { | |
"use strict"; | |
var app = angular.module("constants", []); | |
app.constant("ROUTE", { | |
"CREATE_GRAPHENE_WORKFLOW": "statemachines/create" | |
}); | |
// moment js for dependency injection | |
/* global moment */ | |
app.constant("moment", moment); | |
// d3 js for dependency injections | |
/* global d3 */ | |
app.constant("d3", d3); | |
/* global CodeMirror */ | |
app.constant("CodeMirror", CodeMirror); | |
// AWSC for dependency injections | |
/* global AWSC */ | |
if (AWSC.Analytics === undefined || AWSC.Analytics === null) { | |
var knownAWSCAnalyticsMethods = ["configure", "trackClick", "trackView"]; | |
AWSC.Analytics = knownAWSCAnalyticsMethods.reduce(function(fakeAnalyticsObject, methodName) { | |
fakeAnalyticsObject[methodName] = function() {}; | |
return fakeAnalyticsObject; | |
}, {}); | |
} | |
app.constant("AWSC", AWSC); | |
app.constant("METRICTYPES", { | |
"timeUntilGetStartedClicked": "timeUntilGetStartedClicked", | |
"timeUntilRegisteredClicked": "timeUntilRegisteredClicked", | |
"validationFailedCount": "validationFailedCount", | |
"executionStartedCount": "executionStartedCount", | |
"blueprintSelectedPrefix": "blueprintSelected_", | |
"createStateMachineSucceeded": "createStateMachineSucceeded", | |
"iamModalShown": "iamModalShown", | |
"iamRoleListEmpty": "iamRoleListEmpty", | |
"newExecutionPageLoaded": "newExecutionPageLoaded", | |
"detailsPageLoaded": "detailsPageLoaded", | |
"copyToNew": "copyToNew", | |
"language": "language", | |
}); | |
app.constant("TOP_ACTIONS", [ | |
Object.freeze({method: "POST", url: "/states/service/statemachines$", metricLabel: "listStateMachines"}), | |
Object.freeze({method: "POST", url: "/states/service/statemachines/executions/details$", metricLabel: "getExecutionDetails"}), | |
Object.freeze({method: "POST", url: "/states/service/statemachines/executions/start$", metricLabel: "startExecution"}), | |
Object.freeze({method: "POST", url: "/states/service/statemachines/validate$", metricLabel: "validateDefinition"}), | |
Object.freeze({method: "POST", url: "/states/service/statemachines/details$", metricLabel: "describeStateMachine"}), | |
Object.freeze({method: "POST", url: "/states/service/statemachines/executions/history$", metricLabel: "getExecutionHistory"}), | |
Object.freeze({method: "POST", url: "/states/service/statemachines/update$", metricLabel: "updateStateMachine"}), | |
Object.freeze({method: "POST", url: "/states/service/starterpack/createstack$", metricLabel: "cfnCreateStack"}) | |
]); | |
// key code constants usable to compare against event.which | |
app.constant("KEY_CODES", { | |
"ENTER": 13, | |
"SPACE": 32 | |
}); | |
app.constant("CW_ALARM", { | |
"OK": "OK", | |
"ALARM": "ALARM", | |
"WARN": "INSUFFICIENT_DATA" | |
}); | |
app.constant("GRAPH_CONSTANTS", { | |
"ZOOM_SCALE": 0.5 | |
}); | |
app.constant("HISTORY_EVENT_TYPE", { | |
ACTIVITY_FAILED: "ActivityFailed", | |
ACTIVITY_SCHEDULE_FAILED: "ActivityScheduleFailed", | |
ACTIVITY_SCHEDULED: "ActivityScheduled", | |
ACTIVITY_STARTED: "ActivityStarted", | |
ACTIVITY_SUCCEEDED: "ActivitySucceeded", | |
ACTIVITY_TIMED_OUT: "ActivityTimedOut", | |
CHOICE_STATE_ENTERED: "ChoiceStateEntered", | |
CHOICE_STATE_EXITED: "ChoiceStateExited", | |
EXECUTION_FAILED: "ExecutionFailed", | |
EXECUTION_STARTED: "ExecutionStarted", | |
EXECUTION_SUCCEEDED: "ExecutionSucceeded", | |
EXECUTION_ABORTED: "ExecutionAborted", | |
EXECUTION_TIMED_OUT: "ExecutionTimedOut", | |
FAIL_STATE_ENTERED: "FailStateEntered", | |
LAMBDA_FUNCTION_FAILED: "LambdaFunctionFailed", | |
LAMBDA_FUNCTION_SCHEDULE_FAILED: "LambdaFunctionScheduleFailed", | |
LAMBDA_FUNCTION_SCHEDULED: "LambdaFunctionScheduled", | |
LAMBDA_FUNCTION_START_FAILED: "LambdaFunctionStartFailed", | |
LAMBDA_FUNCTION_STARTED: "LambdaFunctionStarted", | |
LAMBDA_FUNCTION_SUCCEEDED: "LambdaFunctionSucceeded", | |
LAMBDA_FUNCTION_TIMED_OUT: "LambdaFunctionTimedOut", | |
SUCCEED_STATE_ENTERED: "SucceedStateEntered", | |
SUCCEED_STATE_EXITED: "SucceedStateExited", | |
TASK_STATE_ABORTED: "TaskStateAborted", | |
TASK_STATE_ENTERED: "TaskStateEntered", | |
TASK_STATE_EXITED: "TaskStateExited", | |
PASS_STATE_ENTERED: "PassStateEntered", | |
PASS_STATE_EXITED: "PassStateExited", | |
PARALLEL_STATE_ABORTED: "ParallelStateAborted", | |
PARALLEL_STATE_ENTERED: "ParallelStateEntered", | |
PARALLEL_STATE_EXITED: "ParallelStateExited", | |
PARALLEL_STATE_FAILED: "ParallelStateFailed", | |
PARALLEL_STATE_STARTED: "ParallelStateStarted", | |
PARALLEL_STATE_SUCCEEDED: "ParallelStateSucceeded", | |
WAIT_STATE_ABORTED: "WaitStateAborted", | |
WAIT_STATE_ENTERED: "WaitStateEntered", | |
WAIT_STATE_EXITED: "WaitStateExited" | |
}); | |
app.constant("STATE_MACHINE_VALIDATION_STATUS", Object.freeze({ | |
INVALID: "Bad", | |
VALID: "Good" | |
})); | |
}()); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment