mushy 0.15.1 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4c7413fc5021f3f75a4bc76d587e8cf608cf16d39c91bab9caf3916d0eebcc97
4
- data.tar.gz: c4480bd98782f580b3949e4f956c9aab3cce8387ccf923a284ae4b113e316bab
3
+ metadata.gz: 88a3578100f93b47791d83299597e4b6a1d1ccabfaa8628eb5172617facf9b95
4
+ data.tar.gz: fa722d8dd776c1e311bea24ad94303785fd93ccc16eeebcd93783f9d25c3e0f5
5
5
  SHA512:
6
- metadata.gz: 0e9a557ea1b36bd47af03d8b392d2f74e7ad2eefa7c83fa3a81130e8cb5b5bda8be8750bdb649bd8b1ead65cb295ed9d45ce6fe0a89c419d3073e68d9e242b4b
7
- data.tar.gz: bb0f6fc0ac8d21049841d27ffa991a39ad3328c16313799926d25a0b6b1646c12705bc5e4206afce2e5c12b4badb42b6ea969fe7ac20842bce1aed5bd88af986
6
+ metadata.gz: 4eafe788eccb281c1e15bdc0cfae4dca68f1146894a7d28569347673f28ef265b5b8aa90f7fb6c21245e1ba15fceac2f2677420cc643dd535c8cd54062c7642d
7
+ data.tar.gz: 2568f50f7cdf5569605d89fe7e088036d48f106d10f2b45c2b29a25038f145d29bb2566f9d7271f642b11307cb5e9259e72ac4fb1f1b3826178e977532e7c8b3
@@ -31,7 +31,17 @@ module Mushy
31
31
  end
32
32
 
33
33
  def self.start file, event
34
- file = "#{file}.mushy" unless file.downcase.end_with?('.mushy')
34
+ original_file = file
35
+ file = [file, "#{Dir.home}/.mushy/#{file}"]
36
+ .map { |x| (x.downcase.end_with?('.mushy') ? x : "#{x}.mushy") }
37
+ .select { |x| File.exist?(x) }
38
+ .first
39
+
40
+ unless file
41
+ puts "#{original_file} does not exist."
42
+ return
43
+ end
44
+
35
45
  flow = File.open(file).read
36
46
  flow = Mushy::Flow.parse flow
37
47
 
@@ -77,31 +87,64 @@ module Mushy
77
87
  end
78
88
 
79
89
  def self.get_flow file
80
- puts "trying to get: #{file}"
81
90
  file = "#{file}.mushy" unless file.downcase.end_with?('.mushy')
82
91
  data = JSON.parse File.open(file).read
83
- data['fluxs']
92
+
93
+ data['fluxs'] = standardize_these data['fluxs']
94
+ data['fluxs'] = organize_as_a_flattened_tree_based_on_parents data['fluxs']
95
+
96
+ data
97
+ rescue
98
+ { fluxs: [] }
99
+ end
100
+
101
+ def self.standardize_these fluxs
102
+ fluxs
84
103
  .reject { |x| x['parents'] }
85
104
  .each { |x| x['parents'] = [x['parent']].select { |y| y } }
86
- data['fluxs']
105
+ fluxs
87
106
  .select { |x| x['parent'] }
88
107
  .each { |x| x.delete 'parent' }
89
- data['fluxs']
108
+ fluxs
90
109
  .select { |x| x['parents'] }
91
110
  .each { |x| x['parents'] = x['parents'].select { |y| y } }
92
- data
93
- rescue
94
- { fluxs: [] }
111
+
112
+ fluxs
113
+ end
114
+
115
+ def self.organize_as_a_flattened_tree_based_on_parents fluxs
116
+ fluxs = fluxs.sort_by { |x| x['parents'].count }
117
+
118
+ new_fluxs = [fluxs.first]
119
+
120
+ loop do
121
+
122
+ next_fluxs = fluxs.select { |x| x['parents'].include? new_fluxs[-1]['id'] }
123
+
124
+ unless next_fluxs.any?
125
+ next_fluxs = [fluxs.reject { |x| new_fluxs.map { |y| y['id'] }.include?(x['id']) }[0]].select { |x| x }
126
+ end
127
+
128
+ new_fluxs = [new_fluxs, next_fluxs].flatten
129
+
130
+ break unless next_fluxs.any?
131
+
132
+ end
133
+
134
+ new_fluxs
95
135
  end
96
136
 
97
137
  def self.get_fluxs
98
138
  {
99
139
  fluxs: Mushy::Flux.all.select { |x| x.respond_to? :details }.select { |x| x.details }.map do |flux|
100
140
  details = flux.details
141
+
142
+ details[:documentation] = Documentation.build_from details
143
+
101
144
  details[:config][:incoming_split] = { type: 'text', shrink: true, description: 'Split an incoming event into multiple events by this key, an each event will be processed independently.', default: '' }
102
145
  details[:config][:outgoing_split] = { type: 'text', shrink: true, description: 'Split an outgoing event into multiple events by this key.', default: '' }
103
146
  details[:config][:merge] = { type: 'text', shrink: true, description: 'A comma-delimited list of fields from the event to carry through. Use * to merge all fields.', default: '' }
104
- details[:config][:group] = { type: 'text', shrink: true, description: 'Group events by a field, which is stored in a key. The format is group_by|group_key.', default: '' }
147
+ details[:config][:group] = { type: 'text', shrink: true, description: 'Group events by this key, with the value as the key. If a group key is provided like group_by|group_key, then multiple events with the results under group_key will be returned.', default: '' }
105
148
  details[:config][:limit] = { type: 'integer', shrink: true, description: 'Limit the number of events to this number.', default: '' }
106
149
  details[:config][:join] = { type: 'text', shrink: true, description: 'Join all of the events from this flux into one event, under this name.', default: '' }
107
150
  details[:config][:sort] = { type: 'text', shrink: true, description: 'Sort by this key.', default: '' }
@@ -0,0 +1,37 @@
1
+ module Mushy
2
+ module Builder
3
+ module Documentation
4
+
5
+ def self.build_from config
6
+ basic_usage = "#{config[:description]}"
7
+ if config[:config]&.any?
8
+ rows = config[:config]
9
+ .map { |x| [x[0], x[1][:description], (x[1][:shrink] ? '(optional) ' : '')] }
10
+ .reduce("") { |t, i| "#{t}<tr><td>#{i[0]}</td><td>#{i[2]}#{i[1]}</td></tr>" }
11
+ basic_usage += '<table class="table is-bordered"><thead><tr><td>Field</td><td>Description</td></tr></thead>' + rows + "</table>"
12
+ end
13
+
14
+ {
15
+ "Basic Usage" => basic_usage,
16
+ }.tap do |documentation|
17
+ if config[:examples]
18
+ config[:examples].each do |item|
19
+ documentation[item[0]] = [
20
+ item[1][:description],
21
+ code_sample('Input', item[1][:input]),
22
+ code_sample('Config', item[1][:config]),
23
+ code_sample('Result', item[1][:result]),
24
+ ].select { |x| x }.reduce('') { |t, i| t + i }
25
+ end
26
+ end
27
+ end
28
+ end
29
+
30
+ def self.code_sample title, value
31
+ return nil unless value
32
+ "<div><b>#{title}</b></div><pre><code>#{JSON.pretty_generate(value)}</code></pre>"
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -52,6 +52,49 @@ module Mushy
52
52
  <button v-on:click.prevent.stop="startNew({ setup: setup, configs: configs })" class="button is-link">Add a New Flux To This Flow</button>
53
53
  </div>
54
54
  </div>
55
+
56
+ <div v-bind:class="setup.fluxTypeSelect">
57
+ <div class="modal-background"></div>
58
+ <div class="modal-card">
59
+ <header class="modal-card-head">
60
+ <p class="modal-card-title">Flux Types</p>
61
+ <button class="delete" aria-label="close" v-on:click.prevent.stop="setup.fluxTypeSelect['is-active'] = false"></button>
62
+ </header>
63
+ <section class="modal-card-body">
64
+ <div class="content">
65
+ <div v-for="(fluxType, id) in fluxTypes">
66
+ <div class="level">
67
+ <div class="level-left"><h2>{{fluxType.title || fluxType.name}}</h2></div>
68
+ <div class="level-right">
69
+ <button class="button is-primary level-item" v-on:click.prevent.stop="setup.flux.value = fluxType.name;setup.fluxTypeSelect['is-active'] = false">
70
+ Select
71
+ </button>
72
+ <button class="button level-item" v-on:click.prevent.stop="fluxType.showDetails = true" v-if="fluxType['showDetails'] == false">
73
+ Open
74
+ </button>
75
+ <button class="button level-item" v-on:click.prevent.stop="fluxType.showDetails = false" v-if="fluxType['showDetails']">
76
+ Close
77
+ </button>
78
+ </div>
79
+ </div>
80
+
81
+ <div v-if="fluxType['showDetails']">
82
+ <div class="tabs">
83
+ <ul>
84
+ <li v-for="(a, b) in fluxType.documentation"><a v-on:click.prevent.stop="fluxType.detailsTab = b">{{b}}</a></li>
85
+ </ul>
86
+ </div>
87
+ <div v-for="(a, b) in fluxType.documentation" v-if="fluxType['detailsTab'] == b" v-html="a"></div>
88
+ </div>
89
+ </div>
90
+ </div>
91
+ </section>
92
+ <footer class="modal-card-foot">
93
+ <button class="button is-primary" v-on:click.prevent.stop="setup.fluxTypeSelect['is-active'] = false">Done</button>
94
+ </footer>
95
+ </div>
96
+ </div>
97
+
55
98
  <div class="column" v-if="setup.showFlux">
56
99
  <div class="columns">
57
100
  <div class="column is-half">
@@ -124,7 +167,7 @@ module Mushy
124
167
  },
125
168
  text: {
126
169
  props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'shrink'],
127
- template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><div class="control"><input type="text" :name="id" v-if="value || !shrink" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value);" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'" class="input"></div></div>'
170
+ template: '<div><div class="level"><div class="level-left"><div class="level-item"><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label></div><div class="level-item"> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a></div></div></div> <div class="control"><input type="text" :name="id" v-if="value || !shrink" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value);" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'" class="input"></div></div>'
128
171
  },
129
172
  hide: {
130
173
  props: ['label', 'description'],
@@ -132,19 +175,19 @@ module Mushy
132
175
  },
133
176
  integer: {
134
177
  props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'shrink'],
135
- template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><div class="control"><input type="text" :name="id" v-if="value || !shrink" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value);" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'" class="input"></div></div>'
178
+ template: '<div><div class="level"><div class="level-left"><div class="level-item"><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label></div><div class="level-item"> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a></div></div></div> <div class="control"><input type="text" :name="id" v-if="value || !shrink" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value);" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'" class="input"></div></div>'
136
179
  },
137
180
  email: {
138
181
  props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'shrink'],
139
- template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><div class="control"><input type="email" :name="id" v-if="value || !shrink" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value)" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'" class="input"></div></div>'
182
+ template: '<div><div class="level"><div class="level-left"><div class="level-item"><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label></div><div class="level-item"> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a></div></div></div> <div class="control"><input type="email" :name="id" v-if="value || !shrink" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value)" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'" class="input"></div></div>'
140
183
  },
141
184
  textarea: {
142
185
  props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'shrink'],
143
- template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><div class="control"><textarea :name="id" v-if="value || !shrink" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value)" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'" class="textarea"></textarea></div></div>'
186
+ template: '<div><div class="level"><div class="level-left"><div class="level-item"><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label></div><div class="level-item"> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a></div></div></div> <div class="control"><textarea :name="id" v-if="value || !shrink" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value)" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'" class="textarea"></textarea></div></div>'
144
187
  },
145
188
  json: {
146
189
  props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'shrink'],
147
- template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><textarea :name="id" v-if="value || !shrink" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value)" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'" class="textarea"></textarea></div>'
190
+ template: '<div><div class="level"><div class="level-left"><div class="level-item"><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label></div><div class="level-item"> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a></div></div></div> <textarea :name="id" v-if="value || !shrink" :placeholder="placeholder" v-bind:value="value" v-on:input="$emit(\\'update:value\\', $event.target.value)" :disabled="disabled == \\'true\\'" :readonly="readonly == \\'true\\'" class="textarea"></textarea></div>'
148
191
  },
149
192
  jsonview: {
150
193
  data: function() {
@@ -159,15 +202,15 @@ module Mushy
159
202
  },
160
203
  radio: {
161
204
  props: ['label', 'value', 'options', 'description', 'shrink'],
162
- template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><div v-for="option in options"><input type="radio" :name="id" v-bind:value="option" v-if="value || !shrink" v-on:input="$emit(\\'update:value\\', $event.target.value)" :checked="value == option"> <label for="option">{{option}}</label></div></div>'
205
+ template: '<div><div class="level"><div class="level-left"><div class="level-item"><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label></div><div class="level-item"> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a></div></div></div> <div v-for="option in options"><input type="radio" :name="id" v-bind:value="option" v-if="value || !shrink" v-on:input="$emit(\\'update:value\\', $event.target.value)" :checked="value == option"> <label for="option">{{option}}</label></div></div>'
163
206
  },
164
207
  select: {
165
208
  props: ['label', 'value', 'options', 'description', 'shrink'],
166
- template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><div class="control"><select :name="id" v-if="value || !shrink" v-on:input="$emit(\\'update:value\\', $event.target.value)" class="select"><option v-for="option in options" v-bind:value="option" :selected="value == option">{{option}}</option></select></div></div>'
209
+ template: '<div><div class="level"><div class="level-left"><div class="level-item"><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label></div><div class="level-item"> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a></div></div></div> <div class="control"><select :name="id" v-if="value || !shrink" v-on:input="$emit(\\'update:value\\', $event.target.value)" class="select"><option v-for="option in options" v-bind:value="option" :selected="value == option">{{option}}</option></select></div></div>'
167
210
  },
168
211
  selectrecord: {
169
212
  props: ['label', 'value', 'options', 'description', 'shrink'],
170
- template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><div class="control"><select :name="id" v-if="value || !shrink" v-on:input="$emit(\\'update:value\\', $event.target.value)" class="select"><option v-for="option in options" v-bind:value="option.id" :selected="value == option.id">{{option.name}}</option></select></div></div>'
213
+ template: '<div><div class="level"><div class="level-left"><div class="level-item"><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label></div><div class="level-item"> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a></div></div></div> <div class="control"><select :name="id" v-if="value || !shrink" v-on:input="$emit(\\'update:value\\', $event.target.value)" class="select"><option v-for="option in options" v-bind:value="option.id" :selected="value == option.id">{{option.name}}</option></select></div></div>'
171
214
  },
172
215
  selectmanyrecords: {
173
216
  data: function() {
@@ -193,11 +236,11 @@ module Mushy
193
236
  };
194
237
  },
195
238
  props: ['label', 'value', 'options', 'description', 'shrink'],
196
- template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a> <span v-for="option in options" v-if="value && value.includes(option.id)">{{option.name}} <a href="#" v-on:click.prevent.stop="remove(option.id, value);$emit(\\'update:value\\', value)">[X]</a> </span> <a href="#" v-on:click.prevent.stop="doit(selectedValue, value);$emit(\\'update:value\\', value)">ADD</a> <div class="control"><select :name="id" v-if="value || !shrink" v-on:input="selectedValue=$event.target.value;" class="select"><option v-for="option in options" v-bind:value="option.id">{{option.name}}</option></select></div></div>'
239
+ template: '<div><div class="level"><div class="level-left"><div class="level-item"><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label></div><div class="level-item"> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a></div></div></div> <span v-for="option in options" v-if="value && value.includes(option.id)">{{option.name}} <a href="#" v-on:click.prevent.stop="remove(option.id, value);$emit(\\'update:value\\', value)">[X]</a> </span> <a href="#" v-on:click.prevent.stop="doit(selectedValue, value);$emit(\\'update:value\\', value)">ADD</a> <div class="control"><select :name="id" v-if="value || !shrink" v-on:input="selectedValue=$event.target.value;" class="select"><option v-for="option in options" v-bind:value="option.id">{{option.name}}</option></select></div></div>'
197
240
  },
198
241
  boolean: {
199
242
  props: ['label', 'value', 'options', 'description', 'shrink'],
200
- template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><div class="control"><select :name="id" v-if="(value != undefined && value != null && value != \\'\\') || !shrink" v-on:input="$emit(\\'update:value\\', $event.target.value)" class="select"><option v-for="option in [true, false]" v-bind:value="option" :selected="value == option">{{option}}</option></select></div></div>'
243
+ template: '<div><div class="level"><div class="level-left"><div class="level-item"><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label></div><div class="level-item"> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a></div></div></div> <div class="control"><select :name="id" v-if="(value != undefined && value != null && value != \\'\\') || !shrink" v-on:input="$emit(\\'update:value\\', $event.target.value)" class="select"><option v-for="option in [true, false]" v-bind:value="option" :selected="value == option">{{option}}</option></select></div></div>'
201
244
  },
202
245
  table: {
203
246
  props: ['value', 'description'],
@@ -219,7 +262,7 @@ module Mushy
219
262
  };
220
263
  },
221
264
  props: ['value', 'editors', 'label', 'description', 'shrink'],
222
- template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && value.length == 0">[^]</a><table v-if="value.length > 0 || !shrink" class="table"><tr><th v-for="(d, i) in value[0]">{{' + fancyName('i') + '}}</th></tr><tr v-for="(v, z) in value"><td v-for="(d, i) in v">{{d}}</td><td><a href="#" v-on:click.prevent.stop="removeRecord(v, value, z)">[x]</a></td></tr><tr><td v-for="editor in editors"><mip-thing :data="editor.field" :id="editor.id"></mip-thing></td><td><a href="#" v-on:click.prevent.stop="addRecord(editors, value)">[Add]</a></td></tr></table></div>'
265
+ template: '<div><div class="level"><div class="level-left"><div class="level-item"><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label></div><div class="level-item"> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && value.length == 0">[^]</a></div></div></div> <table v-if="value.length > 0 || !shrink" class="table"><tr><th v-for="(d, i) in value[0]">{{' + fancyName('i') + '}}</th></tr><tr v-for="(v, z) in value"><td v-for="(d, i) in v">{{d}}</td><td><a href="#" v-on:click.prevent.stop="removeRecord(v, value, z)">[x]</a></td></tr><tr><td v-for="editor in editors"><mip-thing :data="editor.field" :id="editor.id"></mip-thing></td><td><a href="#" v-on:click.prevent.stop="addRecord(editors, value)">[Add]</a></td></tr></table></div>'
223
266
  },
224
267
  keyvalue: {
225
268
  data: function() {
@@ -234,7 +277,7 @@ module Mushy
234
277
  };
235
278
  },
236
279
  props: ['value', 'label', 'editors', 'description', 'shrink'],
237
- template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink">[^]</a><table v-if="JSON.stringify(value) != \\'{}\\' || !shrink" class="table"><tr v-for="(v, k) in value"><td>{{k}}</td><td>{{v}}</td><td><button v-on:click.prevent.stop="removeRecord(value, k)" class="button">Remove {{k}}</button></td></tr><tr><td v-for="editor in editors"><mip-thing :data="editor.field" :id="editor.id"></mip-thing></td><td><button v-on:click.prevent.stop="addRecord(editors, value)" v-show="editors[0].field.value" class="button">{{actionText(editors[0].field.value, value)}} {{editors[0].field.value}}</button></td></tr></table></div>'
280
+ template: '<div><div class="level"><div class="level-left"><div class="level-item"><mip-label :id="id" :label="label" :description="description" :hide_description="shrink && !value"></mip-label></div><div class="level-item"> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink">[^]</a></div></div></div> <table v-if="JSON.stringify(value) != \\'{}\\' || !shrink" class="table"><tr v-for="(v, k) in value"><td>{{k}}</td><td>{{v}}</td><td><button v-on:click.prevent.stop="removeRecord(value, k)" class="button">Remove {{k}}</button></td></tr><tr><td v-for="editor in editors"><mip-thing :data="editor.field" :id="editor.id"></mip-thing></td><td><button v-on:click.prevent.stop="addRecord(editors, value)" v-show="editors[0].field.value" class="button">{{actionText(editors[0].field.value, value)}} {{editors[0].field.value}}</button></td></tr></table></div>'
238
281
  },
239
282
  button: {
240
283
  data: function() {
@@ -337,12 +380,18 @@ module Mushy
337
380
  fluxdata = fluxdata.data;
338
381
  flowdata = flowdata.data;
339
382
 
383
+ fluxdata.fluxs.map(function(x) {
384
+ x['showDetails'] = false;
385
+ x['detailsTab'] = Object.getOwnPropertyNames(x.documentation)[0];
386
+ } );
387
+
340
388
  var configs = {};
341
389
  fluxdata.fluxs.map(function(x){
342
390
  configs[x.name] = x.config;
343
391
  });
344
392
 
345
393
  var options = [''];
394
+ fluxTypesWithDetails = fluxdata.fluxs;
346
395
  fluxTypes = fluxdata.fluxs.map(function(x){ return x.name });
347
396
  for(var type in fluxTypes)
348
397
  options.push(fluxTypes[type]);
@@ -391,9 +440,18 @@ module Mushy
391
440
  "modal": true,
392
441
  "is-active": false,
393
442
  },
443
+ fluxTypeSelect: {
444
+ "modal": true,
445
+ "is-active": false,
446
+ },
394
447
  id: { type: 'hide', value: '' },
395
448
  name: { type: 'text', value: '' },
396
449
  flux: { type: 'select', value: fluxdata.fluxs[0].name, options: options},
450
+ open_flux: { type: 'button', name: 'Select a Flux', foghat: 'free', medium: 'hey', color: 'is-primary',
451
+ click: function() {
452
+ Vue.set(app.setup.fluxTypeSelect, 'is-active', true);
453
+ }
454
+ },
397
455
  parents: { type: 'selectmanyrecords', label: 'Receive Events From', value: '', options: flowdata.fluxs },
398
456
  };
399
457
 
@@ -507,6 +565,7 @@ module Mushy
507
565
  });
508
566
  },
509
567
  configs: configs,
568
+ fluxTypes: fluxTypesWithDetails,
510
569
  setup: setup,
511
570
  flux_name_for: function(ids, fluxes) {
512
571
  var fluxs = fluxes.filter(function(x){ return ids.includes(x.id) });
data/lib/mushy/flux.rb CHANGED
@@ -119,7 +119,11 @@ module Mushy
119
119
  def group_these_results results, event, by
120
120
  group_by = by.split('|')[0]
121
121
  result_key = by.split('|')[1]
122
- results.group_by { |x| x[group_by] }.map { |k, v| SymbolizedHash.new( { result_key => v } ) }
122
+ grouped_results = results.group_by { |x| x[group_by] }
123
+
124
+ return grouped_results unless result_key
125
+
126
+ grouped_results.map { |k, v| SymbolizedHash.new( { result_key => v } ) }
123
127
  end
124
128
 
125
129
  def outgoing_split_these_results results, event, by
@@ -19,6 +19,28 @@ module Mushy
19
19
  value: '',
20
20
  },
21
21
  },
22
+ examples: {
23
+ "Successful Call" => {
24
+ description: 'This will run the ls command and return the full bash result.',
25
+ input: {
26
+ command: "ls",
27
+ },
28
+ result: {
29
+ "text": "bin\nblue_heart.png\nthe_output.txt\n",
30
+ "success": true,
31
+ "exit_code": 0
32
+ }
33
+ },
34
+ "Failed Call" => {
35
+ description: 'This is an example of what happens when the command fails.',
36
+ input: { command: 'rm file_that_does_not_exist.txt' },
37
+ result: {
38
+ "text": "",
39
+ "success": false,
40
+ "exit_code": 256
41
+ }
42
+ },
43
+ }
22
44
  }
23
45
  end
24
46
 
@@ -75,6 +75,124 @@ module Mushy
75
75
  value: '',
76
76
  },
77
77
  },
78
+ examples: {
79
+ "Successful Call" => {
80
+ description: 'This will open https://www.google.com and return the result.',
81
+ config: {
82
+ url: "https://www.google.com",
83
+ },
84
+ result: {
85
+ "url": "https://www.google.com/",
86
+ "status": 200,
87
+ "title": "Google",
88
+ "cookies": [
89
+ {
90
+ "name": "1P_JAR",
91
+ "value": "2021-10-06-12",
92
+ "domain": ".google.com",
93
+ "path": "/",
94
+ "expires": 1636117150.583117,
95
+ "size": 19,
96
+ "httpOnly": false,
97
+ "secure": true,
98
+ "session": false,
99
+ "sameSite": "None",
100
+ "priority": "Medium"
101
+ },
102
+ ],
103
+ "headers": {},
104
+ "time": 1.486214604,
105
+ "body": "<html itemscope=\"\" itemtype=\"http://schema.org/WebPage\" lang=\"en\">...</html>"
106
+ }
107
+ },
108
+ "Login To a Site" => {
109
+ description: 'This will open https://www.yoursitepleasethankyou.com, login using javascript, and then return the state of the browser after logging in.',
110
+ input: {
111
+ url: "https://www.yoursitepleasethankyou.com",
112
+ username: "MYUSERNAME",
113
+ password: "MYPASSWORD",
114
+ },
115
+ config: {
116
+ url: "{{url}}",
117
+ timeout: 10,
118
+ execute: "$('#username').val('{{username}}');
119
+ $('#next').click();
120
+ $('#password').val('{{password}}');
121
+ $('#login').click();"
122
+ },
123
+ result: {
124
+ "url": "https://yoursitepleasethankyou/",
125
+ "status": 200,
126
+ "title": "",
127
+ "cookies": [
128
+ {
129
+ "name": "session_id",
130
+ "value": "1jfujsx5xbnuxmsjmgjhzfpi",
131
+ "domain": ".yoursitepleasethankyou",
132
+ "path": "/",
133
+ "expires": -1,
134
+ "size": 41,
135
+ "httpOnly": true,
136
+ "secure": true,
137
+ "session": true,
138
+ "sameSite": "Lax",
139
+ "priority": "Medium"
140
+ }
141
+ ],
142
+ "headers": {},
143
+ "time": 4.633920809,
144
+ "body": "<html xmlns=\"http://www.w3.org/1999/xhtml\"><head></head>...</html>"
145
+ }
146
+ },
147
+ "Access a Page After Logging In" => {
148
+ description: 'This will open a page using cookies from the previous request. Note that the cookies came from another browser flux event.',
149
+ input: {
150
+ "url": "https://yoursitepleasethankyou/",
151
+ "cookies": [
152
+ {
153
+ "name": "session_id",
154
+ "value": "1jfujsx5xbnuxmsjmgjhzfpi",
155
+ "domain": ".yoursitepleasethankyou",
156
+ "path": "/",
157
+ "expires": -1,
158
+ "size": 41,
159
+ "httpOnly": true,
160
+ "secure": true,
161
+ "session": true,
162
+ "sameSite": "Lax",
163
+ "priority": "Medium"
164
+ }
165
+ ],
166
+ },
167
+ config: {
168
+ url: "https://www.yoursitepleasethankyou.com/myaccount",
169
+ carry_cookies_from: "{{cookies}}"
170
+ },
171
+ result: {
172
+ "url": "https://yoursitepleasethankyou/",
173
+ "status": 200,
174
+ "title": "",
175
+ "cookies": [
176
+ {
177
+ "name": "session_id",
178
+ "value": "1jfujsx5xbnuxmsjmgjhzfpi",
179
+ "domain": ".yoursitepleasethankyou",
180
+ "path": "/",
181
+ "expires": -1,
182
+ "size": 41,
183
+ "httpOnly": true,
184
+ "secure": true,
185
+ "session": true,
186
+ "sameSite": "Lax",
187
+ "priority": "Medium"
188
+ }
189
+ ],
190
+ "headers": {},
191
+ "time": 4.633920809,
192
+ "body": "<html><head></head>Your name is John Doe...</html>"
193
+ }
194
+ }
195
+ }
78
196
  }
79
197
  end
80
198
 
@@ -7,6 +7,7 @@ module Mushy
7
7
  def self.details
8
8
  {
9
9
  name: 'BuildCsv',
10
+ title: "Build CSV",
10
11
  description: 'Build a CSV.',
11
12
  config: {
12
13
  input_path: {
@@ -30,6 +31,27 @@ module Mushy
30
31
  value: true,
31
32
  },
32
33
  },
34
+ examples: {
35
+ "Build a Simple CSV" => {
36
+ description: 'Converts a set of records to a CSV.',
37
+ input: {
38
+ things: [
39
+ { name: "Apple", color:"Red" },
40
+ { name: "Banana", color: "Yellow" },
41
+ { name: "Pear", color: "Green" }
42
+ ]
43
+ },
44
+ config: {
45
+ input_path: "things",
46
+ output_path: "records",
47
+ headers: { name: "Name", color: "Color" },
48
+ header_row: true
49
+ },
50
+ result: {
51
+ records: "Name,Color\nApple,Red\nBanana,Yellow\nPear,Green\n"
52
+ }
53
+ },
54
+ }
33
55
  }
34
56
  end
35
57
 
@@ -5,9 +5,20 @@ module Mushy
5
5
  def self.details
6
6
  {
7
7
  name: 'Cli',
8
+ title: 'Command Line Interface',
8
9
  description: 'Accept CLI arguments from the run command.',
9
10
  config: {
10
11
  },
12
+ examples: {
13
+ "Calling From The Command Line" => {
14
+ description: 'Calling the CLI with command-line arguments.',
15
+ input: "mushy start file first:John last:Doe",
16
+ result: {
17
+ "first": "John",
18
+ "last": "Doe"
19
+ }
20
+ },
21
+ }
11
22
  }
12
23
  end
13
24
 
@@ -13,6 +13,20 @@ module Mushy
13
13
  value: '',
14
14
  },
15
15
  },
16
+ examples: {
17
+ "Example" => {
18
+ description: 'Using this Flux to build a document',
19
+ input: {
20
+ people: [ { name: "John" }, { name: "Jane" } ]
21
+ },
22
+ config: {
23
+ document: '{% for person in people %} {{ person.name }} {% endfor %}'
24
+ },
25
+ result: {
26
+ document: ' John Jane ',
27
+ }
28
+ },
29
+ }
16
30
  }
17
31
  end
18
32
 
@@ -5,6 +5,7 @@ module Mushy
5
5
  def self.details
6
6
  {
7
7
  name: 'Environment',
8
+ title: 'Environment Variables',
8
9
  description: 'Pull environment variables.',
9
10
  config: {
10
11
  variables: {
@@ -13,6 +14,17 @@ module Mushy
13
14
  value: {},
14
15
  },
15
16
  },
17
+ examples: {
18
+ "Example" => {
19
+ description: 'Get environmental variables.',
20
+ config: {
21
+ variables: { text_domain: 'TEXTDOMAIN' }
22
+ },
23
+ result: {
24
+ text_domain: 'Linux-PAM',
25
+ }
26
+ },
27
+ }
16
28
  }
17
29
  end
18
30