@@ -7,220 +7,6 @@ |
||
| 7 | 7 |
#= require jquery.json-editor |
| 8 | 8 |
#= require latlon_and_geo |
| 9 | 9 |
#= require spectrum |
| 10 |
-#= require ./worker-checker |
|
| 11 |
-#= require_self |
|
| 12 |
- |
|
| 13 |
-window.setupJsonEditor = ($editors = $(".live-json-editor")) ->
|
|
| 14 |
- JSONEditor.prototype.ADD_IMG = '<%= image_path 'json-editor/add.png' %>' |
|
| 15 |
- JSONEditor.prototype.DELETE_IMG = '<%= image_path 'json-editor/delete.png' %>' |
|
| 16 |
- editors = [] |
|
| 17 |
- $editors.each -> |
|
| 18 |
- $editor = $(this) |
|
| 19 |
- jsonEditor = new JSONEditor($editor, $editor.data('width') || 400, $editor.data('height') || 500)
|
|
| 20 |
- jsonEditor.doTruncation true |
|
| 21 |
- jsonEditor.showFunctionButtons() |
|
| 22 |
- editors.push jsonEditor |
|
| 23 |
- return editors |
|
| 24 |
- |
|
| 25 |
-hideSchedule = -> |
|
| 26 |
- $(".schedule-region .can-be-scheduled").hide()
|
|
| 27 |
- $(".schedule-region .cannot-be-scheduled").show()
|
|
| 28 |
- |
|
| 29 |
-showSchedule = (defaultSchedule = null) -> |
|
| 30 |
- if defaultSchedule? |
|
| 31 |
- $(".schedule-region select").val(defaultSchedule).change()
|
|
| 32 |
- $(".schedule-region .can-be-scheduled").show()
|
|
| 33 |
- $(".schedule-region .cannot-be-scheduled").hide()
|
|
| 34 |
- |
|
| 35 |
-hideLinks = -> |
|
| 36 |
- $(".link-region .select2-container").hide()
|
|
| 37 |
- $(".link-region .propagate-immediately").hide()
|
|
| 38 |
- $(".link-region .cannot-receive-events").show()
|
|
| 39 |
- |
|
| 40 |
-showLinks = -> |
|
| 41 |
- $(".link-region .select2-container").show()
|
|
| 42 |
- $(".link-region .propagate-immediately").show()
|
|
| 43 |
- $(".link-region .cannot-receive-events").hide()
|
|
| 44 |
- showEventDescriptions() |
|
| 45 |
- |
|
| 46 |
-hideControlLinks = -> |
|
| 47 |
- $(".control-link-region").hide()
|
|
| 48 |
- |
|
| 49 |
-showControlLinks = -> |
|
| 50 |
- $(".control-link-region").show()
|
|
| 51 |
- |
|
| 52 |
-hideEventCreation = -> |
|
| 53 |
- $(".event-related-region").hide()
|
|
| 54 |
- |
|
| 55 |
-showEventCreation = -> |
|
| 56 |
- $(".event-related-region").show()
|
|
| 57 |
- |
|
| 58 |
-showEventDescriptions = -> |
|
| 59 |
- if $("#agent_source_ids").val()
|
|
| 60 |
- $.getJSON "/agents/event_descriptions", { ids: $("#agent_source_ids").val().join(",") }, (json) =>
|
|
| 61 |
- if json.description_html? |
|
| 62 |
- $(".event-descriptions").show().html(json.description_html)
|
|
| 63 |
- else |
|
| 64 |
- $(".event-descriptions").hide()
|
|
| 65 |
- else |
|
| 66 |
- $(".event-descriptions").html("").hide()
|
|
| 67 |
- |
|
| 68 |
-$(document).ready -> |
|
| 69 |
- $('.navbar .dropdown.dropdown-hover').hover \
|
|
| 70 |
- -> $(this).addClass('open'),
|
|
| 71 |
- -> $(this).removeClass('open')
|
|
| 72 |
- |
|
| 73 |
- # JSON Editor |
|
| 74 |
- window.jsonEditor = setupJsonEditor()[0] |
|
| 75 |
- |
|
| 76 |
- # Flash |
|
| 77 |
- if $(".flash").length
|
|
| 78 |
- setTimeout((-> $(".flash").slideUp(-> $(".flash").remove())), 5000)
|
|
| 79 |
- |
|
| 80 |
- # Help popovers |
|
| 81 |
- $('.hover-help').popover(trigger: 'hover', html: true)
|
|
| 82 |
- |
|
| 83 |
- # Agent Navigation |
|
| 84 |
- $agentNavigate = $('#agent-navigate')
|
|
| 85 |
- |
|
| 86 |
- # initialize typeahead listener |
|
| 87 |
- $agentNavigate.bind "typeahead:selected", (event, object, name) -> |
|
| 88 |
- item = object['value'] |
|
| 89 |
- $agentNavigate.typeahead('val', '')
|
|
| 90 |
- if agentPaths[item] |
|
| 91 |
- $(".spinner").show()
|
|
| 92 |
- navigationData = agentPaths[item] |
|
| 93 |
- if !(navigationData instanceof Object) || !navigationData.method || navigationData.method == 'GET' |
|
| 94 |
- window.location = navigationData.url || navigationData |
|
| 95 |
- else |
|
| 96 |
- $("<a href='#{navigationData.url}' data-method='#{navigationData.method}'></a>").appendTo($("body")).click()
|
|
| 97 |
- |
|
| 98 |
- # substring matcher for typeahead |
|
| 99 |
- substringMatcher = (strings)-> |
|
| 100 |
- findMatches = (query, callback) -> |
|
| 101 |
- matches = [] |
|
| 102 |
- substrRegex = new RegExp(query, "i") |
|
| 103 |
- $.each strings, (i, str) -> |
|
| 104 |
- matches.push value: str if substrRegex.test(str) |
|
| 105 |
- callback(matches.slice(0,6)) |
|
| 106 |
- |
|
| 107 |
- $agentNavigate.typeahead |
|
| 108 |
- minLength: 1, |
|
| 109 |
- highlight: true, |
|
| 110 |
- , |
|
| 111 |
- source: substringMatcher(agentNames) |
|
| 112 |
- |
|
| 113 |
- |
|
| 114 |
- # Pressing '/' selects the search box. |
|
| 115 |
- $("body").on "keypress", (e) ->
|
|
| 116 |
- if e.keyCode == 47 # The '/' key |
|
| 117 |
- if e.target.nodeName == "BODY" |
|
| 118 |
- e.preventDefault() |
|
| 119 |
- $agentNavigate.focus() |
|
| 120 |
- |
|
| 121 |
- # Agent Show |
|
| 122 |
- fetchLogs = (e) -> |
|
| 123 |
- agentId = $(e.target).closest("[data-agent-id]").data("agent-id")
|
|
| 124 |
- e.preventDefault() |
|
| 125 |
- $("#logs .spinner").show()
|
|
| 126 |
- $("#logs .refresh, #logs .clear").hide()
|
|
| 127 |
- $.get "/agents/#{agentId}/logs", (html) =>
|
|
| 128 |
- $("#logs .logs").html html
|
|
| 129 |
- $("#logs .spinner").stop(true, true).fadeOut ->
|
|
| 130 |
- $("#logs .refresh, #logs .clear").show()
|
|
| 131 |
- |
|
| 132 |
- clearLogs = (e) -> |
|
| 133 |
- if confirm("Are you sure you want to clear all logs for this Agent?")
|
|
| 134 |
- agentId = $(e.target).closest("[data-agent-id]").data("agent-id")
|
|
| 135 |
- e.preventDefault() |
|
| 136 |
- $("#logs .spinner").show()
|
|
| 137 |
- $("#logs .refresh, #logs .clear").hide()
|
|
| 138 |
- $.post "/agents/#{agentId}/logs/clear", { "_method": "DELETE" }, (html) =>
|
|
| 139 |
- $("#logs .logs").html html
|
|
| 140 |
- $("#show-tabs li a.recent-errors").removeClass 'recent-errors'
|
|
| 141 |
- $("#logs .spinner").stop(true, true).fadeOut ->
|
|
| 142 |
- $("#logs .refresh, #logs .clear").show()
|
|
| 143 |
- |
|
| 144 |
- $(".agent-show #show-tabs a[href='#logs'], #logs .refresh").on "click", fetchLogs
|
|
| 145 |
- $(".agent-show #logs .clear").on "click", clearLogs
|
|
| 146 |
- |
|
| 147 |
- if tab = window.location.href.match(/tab=(\w+)\b/i)?[1] |
|
| 148 |
- if tab in ["details", "logs"] |
|
| 149 |
- $(".agent-show .nav-pills li a[href='##{tab}']").click()
|
|
| 150 |
- |
|
| 151 |
- # Editing Agents |
|
| 152 |
- $("#agent_source_ids").on "change", showEventDescriptions
|
|
| 153 |
- |
|
| 154 |
- $("#agent_type").on "change", ->
|
|
| 155 |
- if window.jsonEditor? |
|
| 156 |
- $("#agent-spinner").fadeIn();
|
|
| 157 |
- $("#agent_source_ids").select2("val", {});
|
|
| 158 |
- $(".event-descriptions").html("").hide()
|
|
| 159 |
- $.getJSON "/agents/type_details", { type: $(@).val() }, (json) =>
|
|
| 160 |
- if json.can_be_scheduled |
|
| 161 |
- showSchedule(json.default_schedule) |
|
| 162 |
- else |
|
| 163 |
- hideSchedule() |
|
| 164 |
- |
|
| 165 |
- if json.can_receive_events |
|
| 166 |
- showLinks() |
|
| 167 |
- else |
|
| 168 |
- hideLinks() |
|
| 169 |
- |
|
| 170 |
- if json.can_control_other_agents |
|
| 171 |
- showControlLinks() |
|
| 172 |
- else |
|
| 173 |
- hideControlLinks() |
|
| 174 |
- |
|
| 175 |
- if json.can_create_events |
|
| 176 |
- showEventCreation() |
|
| 177 |
- else |
|
| 178 |
- hideEventCreation() |
|
| 179 |
- |
|
| 180 |
- $(".description").html(json.description_html) if json.description_html?
|
|
| 181 |
- |
|
| 182 |
- $('.oauthable-form').html(json.form) if json.form?
|
|
| 183 |
- |
|
| 184 |
- if $("#agent_options").hasClass("showing-default") || $("#agent_options").val().match(/\A\s*(\{\s*\}|)\s*\Z/g)
|
|
| 185 |
- window.jsonEditor.json = json.options |
|
| 186 |
- window.jsonEditor.rebuild() |
|
| 187 |
- |
|
| 188 |
- $("#agent-spinner").stop(true, true).fadeOut();
|
|
| 189 |
- |
|
| 190 |
- $("#agent_type").change() if $("#agent_type").length
|
|
| 191 |
- |
|
| 192 |
- # Select2 Selects |
|
| 193 |
- $(".select2").select2(width: 'resolve')
|
|
| 194 |
- |
|
| 195 |
- if $(".schedule-region")
|
|
| 196 |
- if $(".schedule-region").data("can-be-scheduled") == true
|
|
| 197 |
- showSchedule() |
|
| 198 |
- else |
|
| 199 |
- hideSchedule() |
|
| 200 |
- |
|
| 201 |
- if $(".link-region")
|
|
| 202 |
- if $(".link-region").data("can-receive-events") == true
|
|
| 203 |
- showLinks() |
|
| 204 |
- else |
|
| 205 |
- hideLinks() |
|
| 206 |
- |
|
| 207 |
- if $(".control-link-region")
|
|
| 208 |
- if $(".control-link-region").data("can-control-other-agents") == true
|
|
| 209 |
- showControlLinks() |
|
| 210 |
- else |
|
| 211 |
- hideControlLinks() |
|
| 212 |
- |
|
| 213 |
- if $(".event-related-region")
|
|
| 214 |
- if $(".event-related-region").data("can-create-events") == true
|
|
| 215 |
- showEventCreation() |
|
| 216 |
- else |
|
| 217 |
- hideEventCreation() |
|
| 218 |
- |
|
| 219 |
- $('.selectable-text').each ->
|
|
| 220 |
- $(this).click -> |
|
| 221 |
- range = document.createRange() |
|
| 222 |
- range.setStartBefore(this.firstChild) |
|
| 223 |
- range.setEndAfter(this.lastChild) |
|
| 224 |
- sel = window.getSelection() |
|
| 225 |
- sel.removeAllRanges(); |
|
| 226 |
- sel.addRange(range) |
|
| 10 |
+#= require_tree ./components |
|
| 11 |
+#= require_tree ./pages |
|
| 12 |
+#= require_self |
@@ -0,0 +1,30 @@ |
||
| 1 |
+$ -> |
|
| 2 |
+ # Flash |
|
| 3 |
+ if $(".flash").length
|
|
| 4 |
+ setTimeout((-> $(".flash").slideUp(-> $(".flash").remove())), 5000)
|
|
| 5 |
+ |
|
| 6 |
+ # Help popovers |
|
| 7 |
+ $('.hover-help').popover(trigger: 'hover', html: true)
|
|
| 8 |
+ |
|
| 9 |
+ # Pressing '/' selects the search box. |
|
| 10 |
+ $("body").on "keypress", (e) ->
|
|
| 11 |
+ if e.keyCode == 47 # The '/' key |
|
| 12 |
+ if e.target.nodeName == "BODY" |
|
| 13 |
+ e.preventDefault() |
|
| 14 |
+ $agentNavigate.focus() |
|
| 15 |
+ |
|
| 16 |
+ # Select2 Selects |
|
| 17 |
+ $(".select2").select2(width: 'resolve')
|
|
| 18 |
+ |
|
| 19 |
+ # Helper for selecting text when clicked |
|
| 20 |
+ $('.selectable-text').each ->
|
|
| 21 |
+ $(this).click -> |
|
| 22 |
+ range = document.createRange() |
|
| 23 |
+ range.setStartBefore(this.firstChild) |
|
| 24 |
+ range.setEndAfter(this.lastChild) |
|
| 25 |
+ sel = window.getSelection() |
|
| 26 |
+ sel.removeAllRanges(); |
|
| 27 |
+ sel.addRange(range) |
|
| 28 |
+ |
|
| 29 |
+ # Agent navbar dropdown |
|
| 30 |
+ $('.navbar .dropdown.dropdown-hover').hover (-> $(this).addClass('open')), (-> $(this).removeClass('open'))
|
@@ -0,0 +1,14 @@ |
||
| 1 |
+window.setupJsonEditor = ($editors = $(".live-json-editor")) ->
|
|
| 2 |
+ JSONEditor.prototype.ADD_IMG = '<%= image_path 'json-editor/add.png' %>' |
|
| 3 |
+ JSONEditor.prototype.DELETE_IMG = '<%= image_path 'json-editor/delete.png' %>' |
|
| 4 |
+ editors = [] |
|
| 5 |
+ $editors.each -> |
|
| 6 |
+ $editor = $(this) |
|
| 7 |
+ jsonEditor = new JSONEditor($editor, $editor.data('width') || 400, $editor.data('height') || 500)
|
|
| 8 |
+ jsonEditor.doTruncation true |
|
| 9 |
+ jsonEditor.showFunctionButtons() |
|
| 10 |
+ editors.push jsonEditor |
|
| 11 |
+ return editors |
|
| 12 |
+ |
|
| 13 |
+$ -> |
|
| 14 |
+ window.jsonEditor = setupJsonEditor()[0] |
@@ -0,0 +1,29 @@ |
||
| 1 |
+$ -> |
|
| 2 |
+ $agentNavigate = $('#agent-navigate')
|
|
| 3 |
+ |
|
| 4 |
+ # initialize typeahead listener |
|
| 5 |
+ $agentNavigate.bind "typeahead:selected", (event, object, name) -> |
|
| 6 |
+ item = object['value'] |
|
| 7 |
+ $agentNavigate.typeahead('val', '')
|
|
| 8 |
+ if window.agentPaths[item] |
|
| 9 |
+ $(".spinner").show()
|
|
| 10 |
+ navigationData = window.agentPaths[item] |
|
| 11 |
+ if !(navigationData instanceof Object) || !navigationData.method || navigationData.method == 'GET' |
|
| 12 |
+ window.location = navigationData.url || navigationData |
|
| 13 |
+ else |
|
| 14 |
+ $("<a href='#{navigationData.url}' data-method='#{navigationData.method}'></a>").appendTo($("body")).click()
|
|
| 15 |
+ |
|
| 16 |
+ # substring matcher for typeahead |
|
| 17 |
+ substringMatcher = (strings) -> |
|
| 18 |
+ findMatches = (query, callback) -> |
|
| 19 |
+ matches = [] |
|
| 20 |
+ substrRegex = new RegExp(query, "i") |
|
| 21 |
+ $.each strings, (i, str) -> |
|
| 22 |
+ matches.push value: str if substrRegex.test(str) |
|
| 23 |
+ callback(matches.slice(0,6)) |
|
| 24 |
+ |
|
| 25 |
+ $agentNavigate.typeahead |
|
| 26 |
+ minLength: 1, |
|
| 27 |
+ highlight: true, |
|
| 28 |
+ , |
|
| 29 |
+ source: substringMatcher(window.agentNames) |
@@ -0,0 +1,14 @@ |
||
| 1 |
+class @Utils |
|
| 2 |
+ @navigatePath: (path) -> |
|
| 3 |
+ path = "/" + path unless path.match(/^\//) |
|
| 4 |
+ window.location.href = path |
|
| 5 |
+ |
|
| 6 |
+ @currentPath: -> |
|
| 7 |
+ window.location.href.replace(/https?:\/\/.*?\//g, '') |
|
| 8 |
+ |
|
| 9 |
+ @registerPage: (klass, options = {}) ->
|
|
| 10 |
+ if options.forPathsMatching? |
|
| 11 |
+ if Utils.currentPath().match(options.forPathsMatching) |
|
| 12 |
+ window.currentPage = new klass() |
|
| 13 |
+ else |
|
| 14 |
+ new klass() |
@@ -1,3 +1,5 @@ |
||
| 1 |
+# This is not included in the core application.js bundle. |
|
| 2 |
+ |
|
| 1 | 3 |
$ -> |
| 2 | 4 |
svg = document.querySelector('.agent-diagram svg.diagram')
|
| 3 | 5 |
overlay = document.querySelector('.agent-diagram .overlay')
|
@@ -2,6 +2,8 @@ |
||
| 2 | 2 |
#= require rickshaw |
| 3 | 3 |
#= require_self |
| 4 | 4 |
|
| 5 |
+# This is not included in the core application.js bundle. |
|
| 6 |
+ |
|
| 5 | 7 |
window.renderGraph = ($chart, data, peaks, name) -> |
| 6 | 8 |
graph = new Rickshaw.Graph |
| 7 | 9 |
element: $chart.find(".chart").get(0)
|
@@ -0,0 +1,126 @@ |
||
| 1 |
+class @AgentEditPage |
|
| 2 |
+ constructor: -> |
|
| 3 |
+ $("#agent_source_ids").on "change", @showEventDescriptions
|
|
| 4 |
+ @showCorrectRegionsOnStartup() |
|
| 5 |
+ |
|
| 6 |
+ # The type selector is only available on the new agent form. |
|
| 7 |
+ if $("#agent_type").length
|
|
| 8 |
+ $("#agent_type").on "change", => @handleTypeChange(false)
|
|
| 9 |
+ @handleTypeChange(true) |
|
| 10 |
+ |
|
| 11 |
+ handleTypeChange: (firstTime) -> |
|
| 12 |
+ $(".event-descriptions").html("").hide()
|
|
| 13 |
+ type = $('#agent_type').val()
|
|
| 14 |
+ |
|
| 15 |
+ if type == 'Agent' |
|
| 16 |
+ $(".agent-settings").hide()
|
|
| 17 |
+ $(".description").hide()
|
|
| 18 |
+ else |
|
| 19 |
+ $(".agent-settings").show()
|
|
| 20 |
+ $("#agent-spinner").fadeIn()
|
|
| 21 |
+ $("#agent_source_ids").select2("val", {})
|
|
| 22 |
+ $(".model-errors").hide() unless firstTime
|
|
| 23 |
+ $.getJSON "/agents/type_details", { type: type }, (json) =>
|
|
| 24 |
+ if json.can_be_scheduled |
|
| 25 |
+ if firstTime |
|
| 26 |
+ @showSchedule() |
|
| 27 |
+ else |
|
| 28 |
+ @showSchedule(json.default_schedule) |
|
| 29 |
+ else |
|
| 30 |
+ @hideSchedule() |
|
| 31 |
+ |
|
| 32 |
+ if json.can_receive_events |
|
| 33 |
+ @showLinks() |
|
| 34 |
+ else |
|
| 35 |
+ @hideLinks() |
|
| 36 |
+ |
|
| 37 |
+ if json.can_control_other_agents |
|
| 38 |
+ @showControlLinks() |
|
| 39 |
+ else |
|
| 40 |
+ @hideControlLinks() |
|
| 41 |
+ |
|
| 42 |
+ if json.can_create_events |
|
| 43 |
+ @showEventCreation() |
|
| 44 |
+ else |
|
| 45 |
+ @hideEventCreation() |
|
| 46 |
+ |
|
| 47 |
+ $(".description").show().html(json.description_html) if json.description_html?
|
|
| 48 |
+ |
|
| 49 |
+ $('.oauthable-form').html(json.form) if json.form?
|
|
| 50 |
+ |
|
| 51 |
+ unless firstTime |
|
| 52 |
+ window.jsonEditor.json = json.options |
|
| 53 |
+ window.jsonEditor.rebuild() |
|
| 54 |
+ |
|
| 55 |
+ $("#agent-spinner").stop(true, true).fadeOut();
|
|
| 56 |
+ |
|
| 57 |
+ hideSchedule: -> |
|
| 58 |
+ $(".schedule-region .can-be-scheduled").hide()
|
|
| 59 |
+ $(".schedule-region .cannot-be-scheduled").show()
|
|
| 60 |
+ |
|
| 61 |
+ showSchedule: (defaultSchedule = null) -> |
|
| 62 |
+ if defaultSchedule? |
|
| 63 |
+ $(".schedule-region select").val(defaultSchedule).change()
|
|
| 64 |
+ $(".schedule-region .can-be-scheduled").show()
|
|
| 65 |
+ $(".schedule-region .cannot-be-scheduled").hide()
|
|
| 66 |
+ |
|
| 67 |
+ hideLinks: -> |
|
| 68 |
+ $(".link-region .select2-container").hide()
|
|
| 69 |
+ $(".link-region .propagate-immediately").hide()
|
|
| 70 |
+ $(".link-region .cannot-receive-events").show()
|
|
| 71 |
+ |
|
| 72 |
+ showLinks: -> |
|
| 73 |
+ $(".link-region .select2-container").show()
|
|
| 74 |
+ $(".link-region .propagate-immediately").show()
|
|
| 75 |
+ $(".link-region .cannot-receive-events").hide()
|
|
| 76 |
+ @showEventDescriptions() |
|
| 77 |
+ |
|
| 78 |
+ hideControlLinks: -> |
|
| 79 |
+ $(".control-link-region").hide()
|
|
| 80 |
+ |
|
| 81 |
+ showControlLinks: -> |
|
| 82 |
+ $(".control-link-region").show()
|
|
| 83 |
+ |
|
| 84 |
+ hideEventCreation: -> |
|
| 85 |
+ $(".event-related-region").hide()
|
|
| 86 |
+ |
|
| 87 |
+ showEventCreation: -> |
|
| 88 |
+ $(".event-related-region").show()
|
|
| 89 |
+ |
|
| 90 |
+ showEventDescriptions: -> |
|
| 91 |
+ if $("#agent_source_ids").val()
|
|
| 92 |
+ $.getJSON "/agents/event_descriptions", { ids: $("#agent_source_ids").val().join(",") }, (json) =>
|
|
| 93 |
+ if json.description_html? |
|
| 94 |
+ $(".event-descriptions").show().html(json.description_html)
|
|
| 95 |
+ else |
|
| 96 |
+ $(".event-descriptions").hide()
|
|
| 97 |
+ else |
|
| 98 |
+ $(".event-descriptions").html("").hide()
|
|
| 99 |
+ |
|
| 100 |
+ showCorrectRegionsOnStartup: -> |
|
| 101 |
+ if $(".schedule-region")
|
|
| 102 |
+ if $(".schedule-region").data("can-be-scheduled") == true
|
|
| 103 |
+ @showSchedule() |
|
| 104 |
+ else |
|
| 105 |
+ @hideSchedule() |
|
| 106 |
+ |
|
| 107 |
+ if $(".link-region")
|
|
| 108 |
+ if $(".link-region").data("can-receive-events") == true
|
|
| 109 |
+ @showLinks() |
|
| 110 |
+ else |
|
| 111 |
+ @hideLinks() |
|
| 112 |
+ |
|
| 113 |
+ if $(".control-link-region")
|
|
| 114 |
+ if $(".control-link-region").data("can-control-other-agents") == true
|
|
| 115 |
+ @showControlLinks() |
|
| 116 |
+ else |
|
| 117 |
+ @hideControlLinks() |
|
| 118 |
+ |
|
| 119 |
+ if $(".event-related-region")
|
|
| 120 |
+ if $(".event-related-region").data("can-create-events") == true
|
|
| 121 |
+ @showEventCreation() |
|
| 122 |
+ else |
|
| 123 |
+ @hideEventCreation() |
|
| 124 |
+ |
|
| 125 |
+$ -> |
|
| 126 |
+ Utils.registerPage(AgentEditPage, forPathsMatching: /^agents/) |
@@ -0,0 +1,35 @@ |
||
| 1 |
+class @AgentShowPage |
|
| 2 |
+ constructor: -> |
|
| 3 |
+ $(".agent-show #show-tabs a[href='#logs'], #logs .refresh").on "click", @fetchLogs
|
|
| 4 |
+ $(".agent-show #logs .clear").on "click", @clearLogs
|
|
| 5 |
+ |
|
| 6 |
+ # Trigger tabs when navigated to. |
|
| 7 |
+ if tab = window.location.href.match(/tab=(\w+)\b/i)?[1] |
|
| 8 |
+ if tab in ["details", "logs"] |
|
| 9 |
+ $(".agent-show .nav-pills li a[href='##{tab}']").click()
|
|
| 10 |
+ |
|
| 11 |
+ fetchLogs: (e) -> |
|
| 12 |
+ agentId = $(e.target).closest("[data-agent-id]").data("agent-id")
|
|
| 13 |
+ e.preventDefault() |
|
| 14 |
+ $("#logs .spinner").show()
|
|
| 15 |
+ $("#logs .refresh, #logs .clear").hide()
|
|
| 16 |
+ $.get "/agents/#{agentId}/logs", (html) =>
|
|
| 17 |
+ $("#logs .logs").html html
|
|
| 18 |
+ $("#logs .spinner").stop(true, true).fadeOut ->
|
|
| 19 |
+ $("#logs .refresh, #logs .clear").show()
|
|
| 20 |
+ |
|
| 21 |
+ clearLogs: (e) -> |
|
| 22 |
+ if confirm("Are you sure you want to clear all logs for this Agent?")
|
|
| 23 |
+ agentId = $(e.target).closest("[data-agent-id]").data("agent-id")
|
|
| 24 |
+ e.preventDefault() |
|
| 25 |
+ $("#logs .spinner").show()
|
|
| 26 |
+ $("#logs .refresh, #logs .clear").hide()
|
|
| 27 |
+ $.post "/agents/#{agentId}/logs/clear", { "_method": "DELETE" }, (html) =>
|
|
| 28 |
+ $("#logs .logs").html html
|
|
| 29 |
+ $("#show-tabs li a.recent-errors").removeClass 'recent-errors'
|
|
| 30 |
+ $("#logs .spinner").stop(true, true).fadeOut ->
|
|
| 31 |
+ $("#logs .refresh, #logs .clear").show()
|
|
| 32 |
+ |
|
| 33 |
+$ -> |
|
| 34 |
+ Utils.registerPage(AgentShowPage, forPathsMatching: /^agents\/\d+/) |
|
| 35 |
+ |
@@ -3,6 +3,8 @@ |
||
| 3 | 3 |
#= require ace/mode-markdown.js |
| 4 | 4 |
#= require_self |
| 5 | 5 |
|
| 6 |
+# This is not included in the core application.js bundle. |
|
| 7 |
+ |
|
| 6 | 8 |
$ -> |
| 7 | 9 |
editor = ace.edit("ace-credential-value")
|
| 8 | 10 |
editor.getSession().setTabSize(2) |
@@ -1,6 +1,5 @@ |
||
| 1 | 1 |
module Agents |
| 2 | 2 |
class AdiosoAgent < Agent |
| 3 |
- |
|
| 4 | 3 |
cannot_receive_events! |
| 5 | 4 |
|
| 6 | 5 |
default_schedule "every_1d" |
@@ -1,5 +1,5 @@ |
||
| 1 | 1 |
<% if @agent.errors.any? %> |
| 2 |
- <div class="row well"> |
|
| 2 |
+ <div class="row well model-errors"> |
|
| 3 | 3 |
<h2><%= pluralize(@agent.errors.count, "error") %> prohibited this Agent from being saved:</h2> |
| 4 | 4 |
<% @agent.errors.full_messages.each do |msg| %> |
| 5 | 5 |
<p class='text-warning'><%= msg %></p> |
@@ -21,99 +21,103 @@ |
||
| 21 | 21 |
<% if @agent.new_record? %> |
| 22 | 22 |
<div class="form-group type-select"> |
| 23 | 23 |
<%= f.label :type %> |
| 24 |
- <%= f.select :type, options_for_select(Agent.types.map(&:to_s).sort.map {|type| [type.gsub(/^.*::/, ''), type] }, @agent.type), {}, :class => 'select2 form-control' %>
|
|
| 24 |
+ <%= f.select :type, options_for_select([['Select an Agent Type', 'Agent']] + Agent.types.map(&:to_s).sort.map {|type| [type.gsub(/^.*::/, ''), type] }, @agent.type), {}, :class => 'select2 form-control' %>
|
|
| 25 | 25 |
</div> |
| 26 | 26 |
<% end %> |
| 27 |
+ </div> |
|
| 27 | 28 |
|
| 28 |
- <div class="form-group type-select"> |
|
| 29 |
- <%= f.label :name %> |
|
| 30 |
- <%= f.text_field :name, :class => 'form-control' %> |
|
| 31 |
- </div> |
|
| 32 |
- |
|
| 33 |
- <div class='oauthable-form'> |
|
| 34 |
- <%= render partial: 'oauth_dropdown', locals: { agent: @agent } %>
|
|
| 35 |
- </div> |
|
| 29 |
+ <div class="agent-settings"> |
|
| 30 |
+ <div class="col-md-8"> |
|
| 31 |
+ <div class="form-group"> |
|
| 32 |
+ <%= f.label :name %> |
|
| 33 |
+ <%= f.text_field :name, :class => 'form-control' %> |
|
| 34 |
+ </div> |
|
| 36 | 35 |
|
| 37 |
- <div class="form-group"> |
|
| 38 |
- <%= f.label :schedule, :class => 'control-label' %> |
|
| 39 |
- <div class="schedule-region" data-can-be-scheduled="<%= @agent.can_be_scheduled? %>"> |
|
| 40 |
- <div class="can-be-scheduled"> |
|
| 41 |
- <%= f.select :schedule, options_for_select(Agent::SCHEDULES.map {|s| [s.humanize.titleize, s] }, @agent.schedule), {}, :class => 'form-control' %>
|
|
| 42 |
- </div> |
|
| 43 |
- <span class='cannot-be-scheduled text-info'>This type of Agent cannot be scheduled.</span> |
|
| 36 |
+ <div class='oauthable-form'> |
|
| 37 |
+ <%= render partial: 'oauth_dropdown', locals: { agent: @agent } %>
|
|
| 44 | 38 |
</div> |
| 45 |
- </div> |
|
| 46 | 39 |
|
| 47 |
- <div class="controller-region" data-has-controllers="<%= !@agent.controllers.empty? %>"> |
|
| 48 | 40 |
<div class="form-group"> |
| 49 |
- <%= f.label :controllers %> |
|
| 50 |
- <span class="glyphicon glyphicon-question-sign hover-help" data-content="Other than the system-defined schedule above, this agent may be run or controlled by these user-defined Agents."></span> |
|
| 51 |
- <div class="controller-list"> |
|
| 52 |
- <%= agent_controllers(@agent) || 'None' %> |
|
| 41 |
+ <%= f.label :schedule, :class => 'control-label' %> |
|
| 42 |
+ <div class="schedule-region" data-can-be-scheduled="<%= @agent.can_be_scheduled? %>"> |
|
| 43 |
+ <div class="can-be-scheduled"> |
|
| 44 |
+ <%= f.select :schedule, options_for_select(Agent::SCHEDULES.map {|s| [s.humanize.titleize, s] }, @agent.schedule), {}, :class => 'form-control' %>
|
|
| 45 |
+ </div> |
|
| 46 |
+ <span class='cannot-be-scheduled text-info'>This type of Agent cannot be scheduled.</span> |
|
| 53 | 47 |
</div> |
| 54 | 48 |
</div> |
| 55 |
- </div> |
|
| 56 | 49 |
|
| 57 |
- <div class="control-link-region" data-can-control-other-agents="<%= @agent.can_control_other_agents? %>"> |
|
| 58 |
- <div class="can-control-other-agents"> |
|
| 50 |
+ <div class="controller-region" data-has-controllers="<%= !@agent.controllers.empty? %>"> |
|
| 59 | 51 |
<div class="form-group"> |
| 60 |
- <%= f.label :control_targets %> |
|
| 61 |
- <% eventControlTargets = current_user.agents.select(&:can_be_scheduled?) %> |
|
| 62 |
- <%= f.select(:control_target_ids, |
|
| 63 |
- options_for_select(eventControlTargets.map {|s| [s.name, s.id] },
|
|
| 64 |
- @agent.control_target_ids), |
|
| 65 |
- {}, { multiple: true, size: 5, class: 'select2 form-control' }) %>
|
|
| 52 |
+ <%= f.label :controllers %> |
|
| 53 |
+ <span class="glyphicon glyphicon-question-sign hover-help" data-content="Other than the system-defined schedule above, this agent may be run or controlled by these user-defined Agents."></span> |
|
| 54 |
+ <div class="controller-list"> |
|
| 55 |
+ <%= agent_controllers(@agent) || 'None' %> |
|
| 56 |
+ </div> |
|
| 66 | 57 |
</div> |
| 67 | 58 |
</div> |
| 68 |
- </div> |
|
| 69 | 59 |
|
| 70 |
- <div class='event-related-region' data-can-create-events="<%= @agent.can_create_events? %>"> |
|
| 71 |
- <div class="form-group"> |
|
| 72 |
- <%= f.label :keep_events_for, "Keep events" %> |
|
| 73 |
- <span class="glyphicon glyphicon-question-sign hover-help" data-content="In order to conserve disk space, you can choose to have events created by this Agent expire after a certain period of time. Make sure you keep them long enough to allow any subsequent Agents to make use of them."></span> |
|
| 74 |
- <%= f.select :keep_events_for, options_for_select(Agent::EVENT_RETENTION_SCHEDULES, @agent.keep_events_for), {}, :class => 'form-control' %>
|
|
| 60 |
+ <div class="control-link-region" data-can-control-other-agents="<%= @agent.can_control_other_agents? %>"> |
|
| 61 |
+ <div class="can-control-other-agents"> |
|
| 62 |
+ <div class="form-group"> |
|
| 63 |
+ <%= f.label :control_targets %> |
|
| 64 |
+ <% eventControlTargets = current_user.agents.select(&:can_be_scheduled?) %> |
|
| 65 |
+ <%= f.select(:control_target_ids, |
|
| 66 |
+ options_for_select(eventControlTargets.map {|s| [s.name, s.id] },
|
|
| 67 |
+ @agent.control_target_ids), |
|
| 68 |
+ {}, { multiple: true, size: 5, class: 'select2 form-control' }) %>
|
|
| 69 |
+ </div> |
|
| 70 |
+ </div> |
|
| 75 | 71 |
</div> |
| 76 |
- </div> |
|
| 77 | 72 |
|
| 78 |
- <div class="form-group"> |
|
| 79 |
- <%= f.label :sources %> |
|
| 80 |
- <div class="link-region" data-can-receive-events="<%= @agent.can_receive_events? %>"> |
|
| 81 |
- <% eventSources = (current_user.agents - [@agent]).find_all { |a| a.can_create_events? } %>
|
|
| 82 |
- <%= f.select(:source_ids, |
|
| 83 |
- options_for_select(eventSources.map {|s| [s.name, s.id] },
|
|
| 84 |
- @agent.source_ids), |
|
| 85 |
- {}, { :multiple => true, :size => 5, :class => 'select2 form-control' }) %>
|
|
| 86 |
- <span class='cannot-receive-events text-info'>This type of Agent cannot receive events.</span> |
|
| 87 |
- <%= f.label :propagate_immediately, :class => 'propagate-immediately' do %>Propagate immediately |
|
| 88 |
- <%= f.check_box :propagate_immediately %> |
|
| 89 |
- <% end %> |
|
| 73 |
+ <div class='event-related-region' data-can-create-events="<%= @agent.can_create_events? %>"> |
|
| 74 |
+ <div class="form-group"> |
|
| 75 |
+ <%= f.label :keep_events_for, "Keep events" %> |
|
| 76 |
+ <span class="glyphicon glyphicon-question-sign hover-help" data-content="In order to conserve disk space, you can choose to have events created by this Agent expire after a certain period of time. Make sure you keep them long enough to allow any subsequent Agents to make use of them."></span> |
|
| 77 |
+ <%= f.select :keep_events_for, options_for_select(Agent::EVENT_RETENTION_SCHEDULES, @agent.keep_events_for), {}, :class => 'form-control' %>
|
|
| 78 |
+ </div> |
|
| 90 | 79 |
</div> |
| 91 |
- </div> |
|
| 92 | 80 |
|
| 93 |
- <% if current_user.scenario_count > 0 %> |
|
| 94 | 81 |
<div class="form-group"> |
| 95 |
- <%= f.label :scenarios %> |
|
| 96 |
- <span class="glyphicon glyphicon-question-sign hover-help" data-content="Use Scenarios to group sets of Agents, both for organization, and to make them easy to export and share."></span> |
|
| 97 |
- <%= f.select(:scenario_ids, |
|
| 98 |
- options_for_select(current_user.scenarios.pluck(:name, :id), @agent.scenario_ids), |
|
| 99 |
- {}, { :multiple => true, :size => 5, :class => 'select2 form-control' }) %>
|
|
| 82 |
+ <%= f.label :sources %> |
|
| 83 |
+ <div class="link-region" data-can-receive-events="<%= @agent.can_receive_events? %>"> |
|
| 84 |
+ <% eventSources = (current_user.agents - [@agent]).find_all { |a| a.can_create_events? } %>
|
|
| 85 |
+ <%= f.select(:source_ids, |
|
| 86 |
+ options_for_select(eventSources.map {|s| [s.name, s.id] },
|
|
| 87 |
+ @agent.source_ids), |
|
| 88 |
+ {}, { :multiple => true, :size => 5, :class => 'select2 form-control' }) %>
|
|
| 89 |
+ <span class='cannot-receive-events text-info'>This type of Agent cannot receive events.</span> |
|
| 90 |
+ <%= f.label :propagate_immediately, :class => 'propagate-immediately' do %>Propagate immediately |
|
| 91 |
+ <%= f.check_box :propagate_immediately %> |
|
| 92 |
+ <% end %> |
|
| 93 |
+ </div> |
|
| 100 | 94 |
</div> |
| 101 |
- <% end %> |
|
| 102 | 95 |
|
| 103 |
- </div> |
|
| 96 |
+ <% if current_user.scenario_count > 0 %> |
|
| 97 |
+ <div class="form-group"> |
|
| 98 |
+ <%= f.label :scenarios %> |
|
| 99 |
+ <span class="glyphicon glyphicon-question-sign hover-help" data-content="Use Scenarios to group sets of Agents, both for organization, and to make them easy to export and share."></span> |
|
| 100 |
+ <%= f.select(:scenario_ids, |
|
| 101 |
+ options_for_select(current_user.scenarios.pluck(:name, :id), @agent.scenario_ids), |
|
| 102 |
+ {}, { :multiple => true, :size => 5, :class => 'select2 form-control' }) %>
|
|
| 103 |
+ </div> |
|
| 104 |
+ <% end %> |
|
| 104 | 105 |
|
| 105 |
- <!-- Form controls full width --> |
|
| 106 |
- <div class="col-md-12"> |
|
| 107 |
- <div class="form-group"> |
|
| 108 |
- <%= f.label :options %> |
|
| 109 |
- <span class="glyphicon glyphicon-question-sign hover-help" data-content="In this JSON hash, interpolation is available in almost all values using the Liquid templating language.<p>Available template variables include the following:<dl><dt><code>message</code>, <code>url</code>, etc.</dt><dd>Refers to the corresponding key's value of each incoming event's payload.</dd><dt><code>agent</code></dt><dd>Refers to the agent that created each incoming event. It has attributes like <code>type</code>, <code>name</code> and <code>options</code>, so <code>{{agent.type}}</code> will expand to <code>WebsiteAgent</code> if an incoming event is created by that agent.</dd></dl></p><p>To access user credentials, use the <code>credential</code> tag like this: <code>{% credential <em>bare_key_name</em> %}</code></p>"></span>
|
|
| 110 |
- <textarea rows="15" id="agent_options" name="agent[options]" class="form-control live-json-editor <%= (@agent.new_record? && @agent.options == {}) ? "showing-default" : "" %>">
|
|
| 111 |
- <%= Utils.jsonify((@agent.new_record? && @agent.options == {}) ? @agent.default_options : @agent.options) %>
|
|
| 112 |
- </textarea> |
|
| 113 | 106 |
</div> |
| 114 | 107 |
|
| 115 |
- <div class="form-group"> |
|
| 116 |
- <%= f.submit "Save", :class => "btn btn-primary" %> |
|
| 108 |
+ <!-- Form controls full width --> |
|
| 109 |
+ <div class="col-md-12"> |
|
| 110 |
+ <div class="form-group"> |
|
| 111 |
+ <%= f.label :options %> |
|
| 112 |
+ <span class="glyphicon glyphicon-question-sign hover-help" data-content="In this JSON hash, interpolation is available in almost all values using the Liquid templating language.<p>Available template variables include the following:<dl><dt><code>message</code>, <code>url</code>, etc.</dt><dd>Refers to the corresponding key's value of each incoming event's payload.</dd><dt><code>agent</code></dt><dd>Refers to the agent that created each incoming event. It has attributes like <code>type</code>, <code>name</code> and <code>options</code>, so <code>{{agent.type}}</code> will expand to <code>WebsiteAgent</code> if an incoming event is created by that agent.</dd></dl></p><p>To access user credentials, use the <code>credential</code> tag like this: <code>{% credential <em>bare_key_name</em> %}</code></p>"></span>
|
|
| 113 |
+ <textarea rows="15" id="agent_options" name="agent[options]" class="form-control live-json-editor"> |
|
| 114 |
+ <%= Utils.jsonify((@agent.new_record? && @agent.options == {}) ? @agent.default_options : @agent.options) %>
|
|
| 115 |
+ </textarea> |
|
| 116 |
+ </div> |
|
| 117 |
+ |
|
| 118 |
+ <div class="form-group"> |
|
| 119 |
+ <%= f.submit "Save", :class => "btn btn-primary" %> |
|
| 120 |
+ </div> |
|
| 117 | 121 |
</div> |
| 118 | 122 |
</div> |
| 119 | 123 |
</div> |
@@ -35,22 +35,21 @@ |
||
| 35 | 35 |
</div> |
| 36 | 36 |
|
| 37 | 37 |
<script> |
| 38 |
- var agentPaths = {};
|
|
| 39 |
- var agentNames = []; |
|
| 38 |
+ window.agentPaths = {};
|
|
| 39 |
+ window.agentNames = []; |
|
| 40 | 40 |
<% if current_user.present? -%> |
| 41 | 41 |
var myAgents = <%= Utils.jsonify(current_user.agents.pluck(:name, :id).inject({}) {|m, a| m[a.first] = agent_path(a.last); m }) %>;
|
| 42 | 42 |
var myScenarios = <%= Utils.jsonify(current_user.scenarios.pluck(:name, :id).inject({}) {|m, s| m[s.first + " Scenario"] = scenario_path(s.last); m }) %>;
|
| 43 |
- $.extend(agentPaths, myAgents); |
|
| 44 |
- $.extend(agentPaths, myScenarios); |
|
| 45 |
- agentPaths["All Agents Index"] = <%= Utils.jsonify agents_path %>; |
|
| 46 |
- agentPaths["New Agent"] = <%= Utils.jsonify new_agent_path %>; |
|
| 47 |
- agentPaths["Account"] = <%= Utils.jsonify edit_user_registration_path %>; |
|
| 48 |
- agentPaths["Events Index"] = <%= Utils.jsonify events_path %>; |
|
| 49 |
- agentPaths["View Agent Diagram"] = <%= Utils.jsonify diagram_path %>; |
|
| 50 |
- agentPaths["Run Event Propagation"] = { url: <%= Utils.jsonify propagate_agents_path %>, method: 'POST' };
|
|
| 43 |
+ $.extend(window.agentPaths, myAgents); |
|
| 44 |
+ $.extend(window.agentPaths, myScenarios); |
|
| 45 |
+ window.agentPaths["All Agents Index"] = <%= Utils.jsonify agents_path %>; |
|
| 46 |
+ window.agentPaths["New Agent"] = <%= Utils.jsonify new_agent_path %>; |
|
| 47 |
+ window.agentPaths["Account"] = <%= Utils.jsonify edit_user_registration_path %>; |
|
| 48 |
+ window.agentPaths["Events Index"] = <%= Utils.jsonify events_path %>; |
|
| 49 |
+ window.agentPaths["View Agent Diagram"] = <%= Utils.jsonify diagram_path %>; |
|
| 50 |
+ window.agentPaths["Run Event Propagation"] = { url: <%= Utils.jsonify propagate_agents_path %>, method: 'POST' };
|
|
| 51 | 51 |
|
| 52 |
- |
|
| 53 |
- $.each(agentPaths, function(name, v) { agentNames.push(name); });
|
|
| 52 |
+ $.each(window.agentPaths, function(name, v) { window.agentNames.push(name); });
|
|
| 54 | 53 |
<% end -%> |
| 55 | 54 |
</script> |
| 56 | 55 |
</body> |