mushy 0.9.0 → 0.14.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 +4 -4
- data/lib/mushy/builder/api.rb +1 -1
- data/lib/mushy/builder/bulma.rb +11717 -0
- data/lib/mushy/builder/index.rb +137 -50
- data/lib/mushy/flow.rb +8 -1
- data/lib/mushy/flux.rb +1 -0
- data/lib/mushy/fluxs/collection.rb +33 -15
- data/lib/mushy/fluxs/read_json.rb +28 -0
- data/lib/mushy/fluxs/screenshot.rb +2 -2
- data/lib/mushy/fluxs/sense_hat_environmental_sensors.rb +56 -0
- data/lib/mushy/fluxs/sense_hat_led_matrix.rb +283 -0
- data/lib/mushy/fluxs/simple_python_program.rb +40 -0
- data/lib/mushy/fluxs/write_json.rb +29 -0
- data/lib/mushy.rb +10 -3
- data/lib/site.rb +5 -0
- data/mushy.gemspec +1 -1
- metadata +7 -1
data/lib/mushy/builder/index.rb
CHANGED
@@ -4,38 +4,85 @@ module Mushy
|
|
4
4
|
def self.file
|
5
5
|
|
6
6
|
<<-ENDEND
|
7
|
+
<!DOCTYPE html>
|
7
8
|
<html>
|
8
9
|
<head>
|
9
|
-
<
|
10
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
11
|
+
<link rel="stylesheet" href="/bulma.css">
|
10
12
|
<script src="/vue.js"></script>
|
11
13
|
<script src="/axios.js"></script>
|
12
14
|
</head>
|
13
15
|
<body>
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
<
|
20
|
-
|
21
|
-
|
22
|
-
<
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
<div
|
35
|
-
|
36
|
-
|
16
|
+
<div id="app">
|
17
|
+
|
18
|
+
<div class="columns">
|
19
|
+
<div class="column is-one-fifth">
|
20
|
+
<aside class="menu">
|
21
|
+
<p class="menu-label">
|
22
|
+
General
|
23
|
+
</p>
|
24
|
+
<ul class="menu-list">
|
25
|
+
<li><a v-on:click.prevent.stop="setup.showFlux = false;">Fluxs</a></li>
|
26
|
+
<li>
|
27
|
+
<ul>
|
28
|
+
<li v-for="flux in flow.fluxs"><a v-on:click.prevent.stop="editFlux({ flux: flux, setup: setup, configs: configs })">{{flux.name}}</a></li>
|
29
|
+
</ul>
|
30
|
+
</li>
|
31
|
+
</ul>
|
32
|
+
</aside>
|
33
|
+
</div>
|
34
|
+
<div class="column" v-if="setup.showFlux == false">
|
35
|
+
|
36
|
+
<div class="container">
|
37
|
+
<table class="table is-fullwidth">
|
38
|
+
<tr>
|
39
|
+
<th>Name</th>
|
40
|
+
<th>Receives Events From</th>
|
41
|
+
<th>Actions</th>
|
42
|
+
</tr>
|
43
|
+
<tr v-for="flux in flow.fluxs">
|
44
|
+
<td>{{flux.name}}</td>
|
45
|
+
<td>{{flux_name_for(flux.parents, flow.fluxs)}}</td>
|
46
|
+
<td>
|
47
|
+
<button v-on:click.prevent.stop="editFlux({ flux: flux, setup: setup, configs: configs })" class="button is-primary">Edit</button>
|
48
|
+
<button v-on:click.prevent.stop="deleteFlux({ flux: flux, flow: flow })" class="button is-danger">Delete</button>
|
49
|
+
</td>
|
50
|
+
</tr>
|
51
|
+
</table>
|
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
|
+
</div>
|
54
|
+
</div>
|
55
|
+
<div class="column" v-if="setup.showFlux">
|
56
|
+
<div class="columns">
|
57
|
+
<div class="column is-half">
|
58
|
+
<mip-heavy :data="setup"></mip-heavy>
|
59
|
+
<mip-mediumred v-for="(data, id) in configs" v-show="setup.flux.value === id" :data="data" medium="hey"></mip-medium>
|
60
|
+
</div>
|
61
|
+
<div class="column is-half">
|
62
|
+
<mip-mediumgreen v-for="(data, id) in configs" v-show="setup.flux.value === id" :data="data" medium="hey"></mip-medium>
|
63
|
+
|
64
|
+
<div v-bind:class="setup.testResultModal">
|
65
|
+
<div class="modal-background"></div>
|
66
|
+
<div class="modal-card">
|
67
|
+
<header class="modal-card-head">
|
68
|
+
<p class="modal-card-title">Modal title</p>
|
69
|
+
<button class="delete" aria-label="close" v-on:click.prevent.stop="setup.testResultModal['is-active'] = false"></button>
|
70
|
+
</header>
|
71
|
+
<section class="modal-card-body">
|
72
|
+
<div v-if="results.errorMessage">{{results.errorMessage}}</div>
|
73
|
+
<div v-else>{{results.length}} result{{results.length == 1 ? "" : "s"}}</div>
|
74
|
+
<mip-heavy v-for="data in results" :data="data"></mip-heavy>
|
75
|
+
</section>
|
76
|
+
<footer class="modal-card-foot">
|
77
|
+
<button class="button is-success">GO</button>
|
78
|
+
</footer>
|
79
|
+
</div>
|
80
|
+
</div>
|
81
|
+
</div>
|
82
|
+
</div>
|
37
83
|
</div>
|
38
84
|
</div>
|
85
|
+
</div>
|
39
86
|
</body>
|
40
87
|
</html>
|
41
88
|
|
@@ -56,7 +103,7 @@ module Mushy
|
|
56
103
|
var components = {
|
57
104
|
label: {
|
58
105
|
props: ['label', 'description', 'hide_description'],
|
59
|
-
template: '<label :for="id" v-if="label != \\'\\'">{{label || ' + fancyName('id') + '}} <i v-show="description && !hide_description">({{description}})</i></label>'
|
106
|
+
template: '<label :for="id" v-if="label != \\'\\'" class="label">{{label || ' + fancyName('id') + '}} <i v-show="description && !hide_description">({{description}})</i></label>'
|
60
107
|
},
|
61
108
|
h1: {
|
62
109
|
props: ['label', 'description', 'hide_description'],
|
@@ -76,7 +123,7 @@ module Mushy
|
|
76
123
|
},
|
77
124
|
text: {
|
78
125
|
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'shrink'],
|
79
|
-
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><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\\'"></div>'
|
126
|
+
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>'
|
80
127
|
},
|
81
128
|
hide: {
|
82
129
|
props: ['label', 'description'],
|
@@ -84,19 +131,19 @@ module Mushy
|
|
84
131
|
},
|
85
132
|
integer: {
|
86
133
|
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'shrink'],
|
87
|
-
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><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\\'"></div>'
|
134
|
+
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>'
|
88
135
|
},
|
89
136
|
email: {
|
90
137
|
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'shrink'],
|
91
|
-
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><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\\'"></div>'
|
138
|
+
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>'
|
92
139
|
},
|
93
140
|
textarea: {
|
94
141
|
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'shrink'],
|
95
|
-
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></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\\'"></textarea></div>'
|
142
|
+
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>'
|
96
143
|
},
|
97
144
|
json: {
|
98
145
|
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'shrink'],
|
99
|
-
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></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\\'"></textarea></div>'
|
146
|
+
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>'
|
100
147
|
},
|
101
148
|
jsonview: {
|
102
149
|
data: function() {
|
@@ -107,19 +154,19 @@ module Mushy
|
|
107
154
|
};
|
108
155
|
},
|
109
156
|
props: ['label', 'placeholder', 'disabled', 'readonly', 'value', 'description', 'view'],
|
110
|
-
template: '<div><mip-h4 :id="id" :label="label" :description="description"></mip-h4> <pre><code>{{show(view, value)}}</code></pre><button :disabled="view==\\'beautiful\\'" v-on:click.prevent.stop="view=toggle(view)">View Pretty</button><button :disabled="view!=\\'beautiful\\'" v-on:click.prevent.stop="view=toggle(view)">View Smaller</button><button v-on:click.prevent.stop="copy(view, value)">Copy</button></div>'
|
157
|
+
template: '<div><mip-h4 :id="id" :label="label" :description="description"></mip-h4> <pre><code>{{show(view, value)}}</code></pre><button :disabled="view==\\'beautiful\\'" v-on:click.prevent.stop="view=toggle(view)" class="button ml-3 is-success">View Pretty</button><button :disabled="view!=\\'beautiful\\'" v-on:click.prevent.stop="view=toggle(view)" class="button ml-3 is-success">View Smaller</button><button v-on:click.prevent.stop="copy(view, value)" class="button ml-3 is-primary">Copy</button></div>'
|
111
158
|
},
|
112
159
|
radio: {
|
113
160
|
props: ['label', 'value', 'options', 'description', 'shrink'],
|
114
|
-
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></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>'
|
161
|
+
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>'
|
115
162
|
},
|
116
163
|
select: {
|
117
164
|
props: ['label', 'value', 'options', 'description', 'shrink'],
|
118
|
-
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><select :name="id" v-if="value || !shrink" v-on:input="$emit(\\'update:value\\', $event.target.value)"><option v-for="option in options" v-bind:value="option" :selected="value == option">{{option}}</option></select></div>'
|
165
|
+
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>'
|
119
166
|
},
|
120
167
|
selectrecord: {
|
121
168
|
props: ['label', 'value', 'options', 'description', 'shrink'],
|
122
|
-
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><select :name="id" v-if="value || !shrink" v-on:input="$emit(\\'update:value\\', $event.target.value)"><option v-for="option in options" v-bind:value="option.id" :selected="value == option.id">{{option.name}}</option></select></div>'
|
169
|
+
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>'
|
123
170
|
},
|
124
171
|
selectmanyrecords: {
|
125
172
|
data: function() {
|
@@ -145,15 +192,15 @@ module Mushy
|
|
145
192
|
};
|
146
193
|
},
|
147
194
|
props: ['label', 'value', 'options', 'description', 'shrink'],
|
148
|
-
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></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> <select :name="id" v-if="value || !shrink" v-on:input="selectedValue=$event.target.value;"><option v-for="option in options" v-bind:value="option.id">{{option.name}}</option></select></div>'
|
195
|
+
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>'
|
149
196
|
},
|
150
197
|
boolean: {
|
151
198
|
props: ['label', 'value', 'options', 'description', 'shrink'],
|
152
|
-
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink && !value">[^]</a><select :name="id" v-if="(value != undefined && value != null && value != \\'\\') || !shrink" v-on:input="$emit(\\'update:value\\', $event.target.value)"><option v-for="option in [true, false]" v-bind:value="option" :selected="value == option">{{option}}</option></select></div>'
|
199
|
+
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>'
|
153
200
|
},
|
154
201
|
table: {
|
155
202
|
props: ['value', 'description'],
|
156
|
-
template: '<table><tr><th v-for="(d, i) in value[0]">{{' + fancyName('i') + '}}</th></tr><tr v-for="v in value"><td v-for="(d, i) in v">{{d}}</td></tr></table>'
|
203
|
+
template: '<table class="table"><tr><th v-for="(d, i) in value[0]">{{' + fancyName('i') + '}}</th></tr><tr v-for="v in value"><td v-for="(d, i) in v">{{d}}</td></tr></table>'
|
157
204
|
},
|
158
205
|
editgrid: {
|
159
206
|
data: function() {
|
@@ -171,7 +218,7 @@ module Mushy
|
|
171
218
|
};
|
172
219
|
},
|
173
220
|
props: ['value', 'editors', 'label', 'description', 'shrink'],
|
174
|
-
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></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"><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>'
|
221
|
+
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>'
|
175
222
|
},
|
176
223
|
keyvalue: {
|
177
224
|
data: function() {
|
@@ -186,11 +233,21 @@ module Mushy
|
|
186
233
|
};
|
187
234
|
},
|
188
235
|
props: ['value', 'label', 'editors', 'description', 'shrink'],
|
189
|
-
template: '<div><mip-label :id="id" :label="label" :description="description" :hide_description="shrink"></mip-label> <a href="#" v-on:click.prevent.stop="shrink=false" v-show="shrink">[^]</a><table v-if="JSON.stringify(value) != \\'{}\\' || !shrink"><tr v-for="(v, k) in value"><td>{{k}}</td><td>{{v}}</td><td><button v-on:click.prevent.stop="removeRecord(value, k)">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">{{actionText(editors[0].field.value, value)}} {{editors[0].field.value}}</button></td></tr></table></div>'
|
236
|
+
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>'
|
190
237
|
},
|
191
238
|
button: {
|
192
|
-
|
193
|
-
|
239
|
+
data: function() {
|
240
|
+
return {
|
241
|
+
buttonStyles: function(x) {
|
242
|
+
var colors = {};
|
243
|
+
if (x.color && x.color != '')
|
244
|
+
colors[x.color] = true;
|
245
|
+
return colors;
|
246
|
+
}
|
247
|
+
};
|
248
|
+
},
|
249
|
+
props: ['click', 'description', 'name', 'color'],
|
250
|
+
template: '<button v-on:click.prevent.stop="click(pull(this), thisComponent())" class="button" v-bind:class="buttonStyles(this)">{{name || id}}</button>'
|
194
251
|
}
|
195
252
|
};
|
196
253
|
|
@@ -198,8 +255,9 @@ module Mushy
|
|
198
255
|
{
|
199
256
|
var props = JSON.parse(JSON.stringify(components[property].props));
|
200
257
|
props.push('id');
|
258
|
+
const theData = components[property].data ?? function() { return {}; };
|
201
259
|
Vue.component('mip-' + property, {
|
202
|
-
data:
|
260
|
+
data: function () {
|
203
261
|
var foundIt = this.$parent;
|
204
262
|
var counter = 0;
|
205
263
|
while (foundIt.$parent.constructor.name == "VueComponent" && counter < 10)
|
@@ -207,18 +265,22 @@ module Mushy
|
|
207
265
|
foundIt = foundIt.$parent;
|
208
266
|
counter += 1;
|
209
267
|
}
|
210
|
-
|
268
|
+
var dataToReturn = {
|
211
269
|
console: console,
|
212
270
|
pull: function(x) { return thingToData(foundIt.data); },
|
213
271
|
thisComponent: function() { return foundIt.data; },
|
214
|
-
}
|
272
|
+
};
|
273
|
+
var data = theData();
|
274
|
+
for(var p in data)
|
275
|
+
dataToReturn[p] = data[p];
|
276
|
+
return dataToReturn;
|
215
277
|
},
|
216
278
|
props: props,
|
217
279
|
template: components[property].template
|
218
280
|
});
|
219
281
|
}
|
220
282
|
|
221
|
-
var thingTemplate = '<div>';
|
283
|
+
var thingTemplate = '<div v-bind:class="{ \\\'ml-3\\\': data.foghat==\\\'free\\\', \\\'column\\\': data.foghat!=\\\'free\\\', \\\'is-full\\\': data.foghat!=\\\'half\\\' && data.foghat!=\\\'free\\\', \\\'is-half\\\': data.foghat==\\\'half\\\' }">';
|
222
284
|
for (var property in components)
|
223
285
|
thingTemplate = thingTemplate + '<mip-' + property + ' v-if="data.type == \\'' + property + '\\'" :id="id" ' + components[property].props.map(function(x){ return ':' + x + '.sync="data.' + x + '"';}).join(' ') + '></mip-' + property + '>'
|
224
286
|
thingTemplate = thingTemplate + '</div>';
|
@@ -229,7 +291,7 @@ module Mushy
|
|
229
291
|
console: console,
|
230
292
|
}
|
231
293
|
},
|
232
|
-
props: ['data', 'value', 'id', 'model'],
|
294
|
+
props: ['data', 'value', 'id', 'model', 'foghat'],
|
233
295
|
template: thingTemplate
|
234
296
|
});
|
235
297
|
|
@@ -240,7 +302,27 @@ module Mushy
|
|
240
302
|
}
|
241
303
|
},
|
242
304
|
props: ['data'],
|
243
|
-
template: '<div><mip-thing v-for="(d, id) in data" :data="d" :id="id"></mip-thing></div>',
|
305
|
+
template: '<div class="columns is-multiline"><mip-thing v-for="(d, id) in data" :data="d" :id="id"></mip-thing></div>',
|
306
|
+
});
|
307
|
+
|
308
|
+
Vue.component('mip-mediumgreen', {
|
309
|
+
data: function () {
|
310
|
+
return {
|
311
|
+
console: console,
|
312
|
+
}
|
313
|
+
},
|
314
|
+
props: ['data', 'medium'],
|
315
|
+
template: '<div class="columns is-multiline"><mip-thing v-for="(d, id) in data" :data="d" :id="id" v-if="d.medium == medium"></mip-thing></div>',
|
316
|
+
});
|
317
|
+
|
318
|
+
Vue.component('mip-mediumred', {
|
319
|
+
data: function () {
|
320
|
+
return {
|
321
|
+
console: console,
|
322
|
+
}
|
323
|
+
},
|
324
|
+
props: ['data', 'medium'],
|
325
|
+
template: '<div class="columns is-multiline"><mip-thing v-for="(d, id) in data" :data="d" :id="id" v-if="d.medium != medium"></mip-thing></div>',
|
244
326
|
});
|
245
327
|
|
246
328
|
var app = null;
|
@@ -304,6 +386,10 @@ module Mushy
|
|
304
386
|
|
305
387
|
var setup = {
|
306
388
|
showFlux: false,
|
389
|
+
testResultModal: {
|
390
|
+
"modal": true,
|
391
|
+
"is-active": false,
|
392
|
+
},
|
307
393
|
id: { type: 'hide', value: '' },
|
308
394
|
name: { type: 'text', value: '' },
|
309
395
|
flux: { type: 'select', value: fluxdata.fluxs[0].name, options: options},
|
@@ -312,18 +398,18 @@ module Mushy
|
|
312
398
|
|
313
399
|
for (var key in configs)
|
314
400
|
{
|
315
|
-
configs[key].save = { type: 'button', name: 'Save Changes', click: function(config) {
|
401
|
+
configs[key].save = { type: 'button', name: 'Save Changes', foghat: 'free', color: 'is-primary', click: function(config) {
|
316
402
|
saveTheFlux({ app: app, config: config });
|
317
403
|
saveTheFlow({ setup: app.setup, flow: app.flow });
|
318
404
|
app.setup.showFlux = false;
|
319
405
|
}
|
320
406
|
};
|
321
|
-
configs[key].cancel = { type: 'button', name: 'Ignore Changes', click: function() {
|
407
|
+
configs[key].cancel = { type: 'button', name: 'Ignore Changes', foghat: 'free', color: 'is-warning', click: function() {
|
322
408
|
app.setup.showFlux = false;
|
323
409
|
}
|
324
410
|
};
|
325
411
|
|
326
|
-
configs[key].test_event = { type: 'json', value: '{}', default: '{}' };
|
412
|
+
configs[key].test_event = { type: 'json', value: '{}', default: '{}', medium: 'hey' };
|
327
413
|
|
328
414
|
configs[key].run_test = { type: 'button', name: 'Test Run This Flux', click: function(c, hey) {
|
329
415
|
var previousName = hey.run_test.name;
|
@@ -334,6 +420,7 @@ module Mushy
|
|
334
420
|
the_setup.event = c.test_event;
|
335
421
|
axios.post('/run', { config: c, setup: the_setup })
|
336
422
|
.then(function(r){
|
423
|
+
app.setup.testResultModal["is-active"] = true;
|
337
424
|
var index = 1;
|
338
425
|
for (var key in r.data.result)
|
339
426
|
{
|
data/lib/mushy/flow.rb
CHANGED
@@ -29,9 +29,16 @@ module Mushy
|
|
29
29
|
flux.id = record[:id] || record['id'] || flux.id
|
30
30
|
flux.type = type
|
31
31
|
flux.config = SymbolizedHash.new(record[:config] || record['config'])
|
32
|
+
flux.flow = Mushy::Flow.new
|
32
33
|
flux
|
33
34
|
end
|
34
35
|
|
36
|
+
def build_flux record
|
37
|
+
Mushy::Flow.build_flux(record).tap do |flux|
|
38
|
+
flux.flow = self
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
35
42
|
def self.parse data
|
36
43
|
data = JSON.parse data
|
37
44
|
|
@@ -40,7 +47,7 @@ module Mushy
|
|
40
47
|
|
41
48
|
flow = new
|
42
49
|
|
43
|
-
flow.fluxs = data_fluxs.map { |s| build_flux s }
|
50
|
+
flow.fluxs = data_fluxs.map { |s| flow.build_flux s }
|
44
51
|
|
45
52
|
fluxs_with_parent_ids = flow.fluxs.reduce({}) { |t, i| t[i.id] = []; t }
|
46
53
|
data_fluxs.map { |r| fluxs_with_parent_ids[r['id']] = r['parents'] || [] }
|
data/lib/mushy/flux.rb
CHANGED
@@ -2,8 +2,6 @@ module Mushy
|
|
2
2
|
|
3
3
|
class Collection < Flux
|
4
4
|
|
5
|
-
attr_accessor :collection
|
6
|
-
|
7
5
|
def self.details
|
8
6
|
{
|
9
7
|
name: 'Collection',
|
@@ -11,9 +9,14 @@ module Mushy
|
|
11
9
|
config: {
|
12
10
|
id: {
|
13
11
|
description: 'The path to the unique id in the body of the element.',
|
14
|
-
type: '
|
15
|
-
value: {
|
12
|
+
type: 'text',
|
13
|
+
value: '{{id}}',
|
16
14
|
},
|
15
|
+
collection_name: {
|
16
|
+
description: 'The name of the collection to interact with.',
|
17
|
+
type: 'text',
|
18
|
+
value: 'records',
|
19
|
+
},
|
17
20
|
operation: {
|
18
21
|
description: 'Perform this operation.',
|
19
22
|
type: 'select',
|
@@ -24,31 +27,26 @@ module Mushy
|
|
24
27
|
}
|
25
28
|
end
|
26
29
|
|
27
|
-
def initialize
|
28
|
-
self.collection = {}
|
29
|
-
super
|
30
|
-
end
|
31
|
-
|
32
30
|
def process event, config
|
33
31
|
self.send(config[:operation].to_sym, event, config)
|
34
32
|
end
|
35
33
|
|
36
34
|
def get_the_id event, config
|
37
|
-
|
35
|
+
config[:id]
|
38
36
|
end
|
39
37
|
|
40
38
|
def all event, config
|
41
|
-
|
39
|
+
the_collection(config).values
|
42
40
|
end
|
43
41
|
|
44
42
|
def delete event, config
|
45
|
-
|
43
|
+
the_collection(config).delete get_the_id(event, config)
|
46
44
|
event[config[:operation_performed]] = 'deleted' if config[:operation_performed]
|
47
45
|
event
|
48
46
|
end
|
49
47
|
|
50
48
|
def upsert event, config
|
51
|
-
if
|
49
|
+
if the_collection(config)[get_the_id(event, config)]
|
52
50
|
update event, config
|
53
51
|
else
|
54
52
|
insert event, config
|
@@ -56,18 +54,38 @@ module Mushy
|
|
56
54
|
end
|
57
55
|
|
58
56
|
def update event, config
|
59
|
-
item =
|
57
|
+
item = the_collection(config)[get_the_id(event, config)]
|
60
58
|
event.each { |k, v| item[k] = v } if item
|
61
59
|
event[config[:operation_performed]] = (item ? 'updated' : 'not exist') if config[:operation_performed]
|
62
60
|
event
|
63
61
|
end
|
64
62
|
|
65
63
|
def insert event, config
|
66
|
-
|
64
|
+
the_collection(config)[get_the_id(event, config)] = event
|
67
65
|
event[config[:operation_performed]] = 'inserted' if config[:operation_performed]
|
68
66
|
event
|
69
67
|
end
|
70
68
|
|
69
|
+
def the_collection config
|
70
|
+
Mushy::Collection.guard_the_flow self.flow
|
71
|
+
the_collection_name = config[:collection_name]
|
72
|
+
|
73
|
+
get_the_collection the_collection_name
|
74
|
+
end
|
75
|
+
|
76
|
+
def get_the_collection name
|
77
|
+
found_collection = self.flow.collection_data[name]
|
78
|
+
return found_collection if found_collection
|
79
|
+
self.flow.collection_data[name] = SymbolizedHash.new
|
80
|
+
end
|
81
|
+
|
82
|
+
def self.guard_the_flow flow
|
83
|
+
return if flow.respond_to?(:collection_data)
|
84
|
+
|
85
|
+
flow.instance_eval { class << self; self end }.send(:attr_accessor, :collection_data)
|
86
|
+
flow.collection_data = {}
|
87
|
+
end
|
88
|
+
|
71
89
|
end
|
72
90
|
|
73
91
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'csv'
|
2
|
+
|
3
|
+
module Mushy
|
4
|
+
|
5
|
+
class ReadJson < Flux
|
6
|
+
|
7
|
+
def self.details
|
8
|
+
{
|
9
|
+
name: 'ReadJson',
|
10
|
+
description: 'Read JSON and output it as an event.',
|
11
|
+
config: {
|
12
|
+
json: {
|
13
|
+
description: 'The JSON contents that will be returned as an event.',
|
14
|
+
type: 'text',
|
15
|
+
value: 'json',
|
16
|
+
},
|
17
|
+
},
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
def process event, config
|
22
|
+
return nil unless config[:json].to_s != ''
|
23
|
+
JSON.parse config[:json]
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
@@ -4,8 +4,8 @@ module Mushy
|
|
4
4
|
|
5
5
|
def self.details
|
6
6
|
details = Browser.details
|
7
|
-
details[
|
8
|
-
details[
|
7
|
+
details[:name] = 'Screenshot'
|
8
|
+
details[:description] = 'Take a screenshot of the browser.'
|
9
9
|
|
10
10
|
details[:config].merge!(Mushy::WriteFile.file_saving_config.tap do |x|
|
11
11
|
x[x.keys.first][:value] = 'file.jpg'
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Mushy
|
2
|
+
|
3
|
+
class SenseHatEnvironmentalSensors < SimplePythonProgram
|
4
|
+
|
5
|
+
def self.details
|
6
|
+
{
|
7
|
+
name: 'SenseHatEnvironmentalSensors',
|
8
|
+
description: 'Pull values from the Sense HAT environmental sensors.',
|
9
|
+
config: Mushy::SimplePythonProgram.default_config,
|
10
|
+
}.tap do |c|
|
11
|
+
measurements
|
12
|
+
.sort_by { |x| default_measurements.include?(x) ? 0 : 1 }
|
13
|
+
.each do |measurement|
|
14
|
+
c[:config][measurement] = {
|
15
|
+
description: "Pull #{measurement}.",
|
16
|
+
type: 'boolean',
|
17
|
+
shrink: true,
|
18
|
+
value: default_measurements.include?(measurement) ? 'true' : '',
|
19
|
+
}
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.measurements
|
25
|
+
[
|
26
|
+
:humidity,
|
27
|
+
:temperature,
|
28
|
+
:temperature_from_humidity,
|
29
|
+
:temperature_from_pressure,
|
30
|
+
:pressure,
|
31
|
+
]
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.default_measurements
|
35
|
+
[:humidity, :temperature, :pressure]
|
36
|
+
end
|
37
|
+
|
38
|
+
def python_program event, config
|
39
|
+
values = self.class.measurements
|
40
|
+
.select { |x| config[x] == 'true' }
|
41
|
+
.reduce({}) { |t, i| t[i] = "get_#{i}"; t}
|
42
|
+
.map { |m| "\"#{m[0]}\": sense.#{m[1]}()" }
|
43
|
+
.join(',')
|
44
|
+
|
45
|
+
<<PYTHON
|
46
|
+
from sense_hat import SenseHat
|
47
|
+
import json
|
48
|
+
sense = SenseHat()
|
49
|
+
value = json.dumps({#{values}})
|
50
|
+
print(value)
|
51
|
+
PYTHON
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|