mushy 0.15.1 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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