disco_app 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/disco_app/components/custom/rules-editor.es6.jsx +77 -20
  3. data/app/assets/javascripts/disco_app/components/ui-kit/ui-layout/ui-empty-state.es6.jsx +3 -3
  4. data/app/assets/javascripts/disco_app/disco_app.js +0 -1
  5. data/app/assets/stylesheets/disco_app/admin/_header.scss +16 -7
  6. data/app/assets/stylesheets/disco_app/admin/_layout.scss +1 -9
  7. data/app/assets/stylesheets/disco_app/admin/_nav.scss +15 -3
  8. data/app/assets/stylesheets/disco_app/disco_app.scss +3 -0
  9. data/app/assets/stylesheets/disco_app/frame/_buttons.scss +1 -1
  10. data/app/assets/stylesheets/disco_app/frame/_forms.scss +1 -1
  11. data/app/assets/stylesheets/disco_app/frame/_type.scss +2 -9
  12. data/app/assets/stylesheets/disco_app/frame.scss +1 -0
  13. data/app/assets/stylesheets/disco_app/ui-kit/_ui-empty-state.scss +27 -0
  14. data/app/assets/stylesheets/disco_app/ui-kit/_ui-footer-help.scss +13 -10
  15. data/app/assets/stylesheets/disco_app/ui-kit/_ui-kit.scss +94 -67
  16. data/app/assets/stylesheets/disco_app/ui-kit/_ui-tabs.scss +15 -3
  17. data/app/jobs/disco_app/concerns/shop_update_job.rb +2 -5
  18. data/app/models/disco_app/concerns/shop.rb +0 -13
  19. data/app/resources/disco_app/admin/resources/concerns/shop_resource.rb +18 -2
  20. data/db/migrate/20160521135510_move_shop_to_synchronises.rb +61 -0
  21. data/lib/disco_app/engine.rb +0 -1
  22. data/lib/disco_app/version.rb +1 -1
  23. data/lib/generators/disco_app/disco_app_generator.rb +42 -3
  24. data/lib/generators/disco_app/{monitorify/templates → templates}/config/newrelic.yml +0 -0
  25. data/lib/generators/disco_app/{monitorify/templates → templates}/initializers/rollbar.rb +0 -0
  26. data/lib/generators/disco_app/templates/root/CHECKS +4 -0
  27. data/lib/tasks/shops.rake +10 -0
  28. data/test/dummy/app/jobs/disco_app/app_uninstalled_job.rb +1 -1
  29. data/test/dummy/app/models/disco_app/shop.rb +1 -1
  30. data/test/dummy/config/database.gitlab-ci.yml +24 -0
  31. data/test/dummy/db/schema.rb +7 -22
  32. data/test/fixtures/disco_app/shops.yml +2 -2
  33. data/test/jobs/disco_app/app_installed_job_test.rb +1 -1
  34. data/test/jobs/disco_app/app_uninstalled_job_test.rb +1 -1
  35. metadata +8 -5
  36. data/lib/generators/disco_app/mailify/mailify_generator.rb +0 -54
  37. data/lib/generators/disco_app/monitorify/monitorify_generator.rb +0 -28
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c93d48179fec89b4944ae9428138e3c12827ba628c525af2742afa9532af6abe
4
- data.tar.gz: 944da37163b8fbfaa4db0cd5626e76a5a5ff1680284fff69cebd0dddd105d754
3
+ metadata.gz: 3e11c5ff7beaece5d87fda19c4d06bcc08ded718b71ce4050a5380c15e638be0
4
+ data.tar.gz: 7a1ceffb9b2c33f6dffe4a31b6877cbab52946cd3d37ad4396270c397dd99805
5
5
  SHA512:
6
- metadata.gz: 23e9f5235c6867c3c77557ed229ddd3de0a3b9d3660ff80a3f06c971ce10d8ab867d30fec229c836542e8865ddb24647282a0cb29049d526e52bc8fd9c641f79
7
- data.tar.gz: b3bce74312f85aff46bca48ed90d53b1344e6e82461321bc962e790c5cd9bbd9f21edb53f4e4359e1a3e7db980d0d4899142307534d190a432e4d26273c825c5
6
+ metadata.gz: 6da76ea6fd5ac63a77fe4acaf4552946416841228994d4cf6b431a094180aa63d6d07a1ef586c71c44eeca0cfc38a4da30d6f0ed1a5b62c54b28b109fcdb485f
7
+ data.tar.gz: 1a96f567be81a5bc6189bb43bb98fd34181009459b2ec085ded5ad820ea662fa7a3780a40e3103a480debe70b74914d224e20cc90a21df3a5c5e949a74801ba4
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Defines a generic RulesEditor class. This class can't be used directly, but
3
3
  * should be inherited, with the inheriting class defining a list of column
4
- * types and correponding relations and condition data types, like so:
4
+ * types and corresponding relations and condition data types, like so:
5
5
  *
6
6
  * class MyRulesEditor extends RulesEditor {};
7
7
  * MyRulesEditor.defaultProps = {
@@ -9,13 +9,7 @@
9
9
  * title: {
10
10
  * label: 'Product title',
11
11
  * column: 'title',
12
- * relations: {
13
- * is_equal_to: {
14
- * label: 'is equal to',
15
- * relation: 'is_equal_to',
16
- * type: 'text'
17
- * }
18
- * }
12
+ * relations: RulesEditor.buildRelationsObj([RulesEditor.EQUALS_STRING])
19
13
  * }
20
14
  * }
21
15
  */
@@ -29,13 +23,11 @@ class RulesEditor extends React.Component {
29
23
  super(props);
30
24
  this.state = {
31
25
  rules: props.rules.map((rule, i) => {
32
- return {
26
+ return Object.assign({}, rule, {
33
27
  column: Object.keys(this.props.columns).filter((columnKey) => {
34
28
  return this.props.columns[columnKey].column == rule.column;
35
- })[0],
36
- relation: rule.relation,
37
- condition: rule.condition
38
- }
29
+ })[0]
30
+ });
39
31
  })
40
32
  }
41
33
  }
@@ -119,6 +111,19 @@ class RulesEditor extends React.Component {
119
111
  });
120
112
  }
121
113
 
114
+ /**
115
+ * Handle a change in a rule's variables
116
+ *
117
+ * @param index
118
+ * @param name
119
+ * @param value
120
+ */
121
+ onRuleVariableChange(index, name, value) {
122
+ this.updateRule(index, {
123
+ [name]: value
124
+ });
125
+ }
126
+
122
127
  /**
123
128
  * Given the column we're changing to and the current rule, return the next
124
129
  * relation value.
@@ -165,10 +170,21 @@ class RulesEditor extends React.Component {
165
170
  * @param updates
166
171
  */
167
172
  updateRule(index, updates) {
173
+ let updatedRule = Object.assign({}, this.state.rules[index], updates);
174
+
175
+ // Ensure only valid variables are present in the rule
176
+ const columnPath = this.props.columns[updatedRule.column].column;
177
+ const columnVariables = RulesEditor.getColumnPathVariables(columnPath);
178
+ Object.keys(updatedRule).forEach(function (key) {
179
+ if ('$' === key[0] && -1 === columnVariables.indexOf(key)) {
180
+ delete updatedRule[key];
181
+ }
182
+ });
183
+
168
184
  this.setState({
169
185
  rules: [
170
186
  ...this.state.rules.slice(0, index),
171
- Object.assign({}, this.state.rules[index], updates),
187
+ updatedRule,
172
188
  ...this.state.rules.slice(index + 1)
173
189
  ]
174
190
  });
@@ -190,6 +206,7 @@ class RulesEditor extends React.Component {
190
206
  onColumnChange={this.onRuleColumnChange.bind(this, i)}
191
207
  onRelationChange={this.onRuleRelationChange.bind(this, i)}
192
208
  onConditionChange={this.onRuleConditionChange.bind(this, i)}
209
+ onVariableChange={this.onRuleVariableChange.bind(this, i)}
193
210
  ruleCount={rules.length}
194
211
  blankOk = {this.props.blankOk}
195
212
  />
@@ -198,11 +215,9 @@ class RulesEditor extends React.Component {
198
215
  // Convert the current rules JSON into a format using the correct column
199
216
  // format used by our more advanced key checker.
200
217
  const rulesJSON = JSON.stringify(this.state.rules.map((rule, i) => {
201
- return {
202
- column: this.props.columns[rule.column].column,
203
- relation: rule.relation,
204
- condition: rule.condition
205
- }
218
+ return Object.assign({}, rule, {
219
+ column: this.props.columns[rule.column].column
220
+ });
206
221
  }));
207
222
 
208
223
  return(
@@ -220,6 +235,23 @@ class RulesEditor extends React.Component {
220
235
  );
221
236
  }
222
237
 
238
+ /**
239
+ * Get the variable names present in a column definition
240
+ *
241
+ * @param column
242
+ * @returns {Array.<String>}
243
+ */
244
+ static getColumnPathVariables(column) {
245
+ return column.split(/[^$a-z_A-Z]/).filter((key) => '$' === key[0]);
246
+ }
247
+
248
+ /**
249
+ * Return a relations object, which is just the passed array
250
+ * turned into an object which is keyed by the `relation` value
251
+ *
252
+ * @param relations
253
+ * @returns {{}}
254
+ */
223
255
  static buildRelationsObj(relations) {
224
256
  var relationsObj = {};
225
257
 
@@ -264,7 +296,7 @@ RulesEditor.LESS_THAN = {
264
296
  type: 'numeric'
265
297
  };
266
298
 
267
- const RulesEditorRule = ({ rule, columns, onRemove, onColumnChange, onRelationChange, onConditionChange, ruleCount, blankOk }) => {
299
+ const RulesEditorRule = ({ rule, columns, onRemove, onColumnChange, onVariableChange, onRelationChange, onConditionChange, ruleCount, blankOk }) => {
268
300
  const { column, relation, condition } = rule;
269
301
 
270
302
  const currentColumn = columns[column];
@@ -293,6 +325,16 @@ const RulesEditorRule = ({ rule, columns, onRemove, onColumnChange, onRelationCh
293
325
  );
294
326
  }
295
327
 
328
+ const columnVariables = RulesEditor.getColumnPathVariables(currentColumn.column);
329
+
330
+ let variablesEditor = columnVariables.map(function(name) {
331
+ return (
332
+ <div className="next-grid__cell" key={name}>
333
+ <RulesEditorVariableInput name={name} value={rule[name]} onChange={onVariableChange.bind(this, name)} />
334
+ </div>
335
+ );
336
+ });
337
+
296
338
  return (
297
339
  <div>
298
340
  <div className="next-grid next-grid--no-padding next-grid--compact">
@@ -301,6 +343,7 @@ const RulesEditorRule = ({ rule, columns, onRemove, onColumnChange, onRelationCh
301
343
  <div className="next-grid__cell">
302
344
  <RulesEditorColumnSelect currentColumnName={column} columns={columns} onChange={onColumnChange} />
303
345
  </div>
346
+ {variablesEditor}
304
347
  <div className="next-grid__cell">
305
348
  <RulesEditorRelationSelect currentRelationName={relation} relations={currentColumn.relations} onChange={onRelationChange} />
306
349
  </div>
@@ -325,6 +368,20 @@ const RulesEditorColumnSelect = ({ currentColumnName, columns, onChange }) => {
325
368
  return <InputSelect options={options} value={currentColumnName} onChange={onChange} label="Field" labelHidden={true} />;
326
369
  };
327
370
 
371
+ const RulesEditorVariableInput = ({ name, value, onChange }) => {
372
+
373
+ const handleChange = (e) => {
374
+ onChange && onChange(e);
375
+ };
376
+
377
+ let label = name.substr(1).trim().replace( /([A-Z])/g, " $1" );
378
+ label = label.charAt(0).toUpperCase() + label.substr(1);
379
+
380
+ return (
381
+ <InputText value={value} onChange={handleChange} label={label} labelHidden={true} placeholder={label} required={true} />
382
+ );
383
+ };
384
+
328
385
  const RulesEditorRelationSelect = ({ currentRelationName, relations, onChange }) => {
329
386
  const options = Object.keys(relations).map((relationName) => {
330
387
  return { label: relations[relationName].label, value: relationName }
@@ -4,7 +4,7 @@ const UIEmptyState = ({ title, subtitle, image, href, label }) => {
4
4
  if(image) {
5
5
  imageSubsection = (
6
6
  <div className="ui-empty-state__subsection">
7
- <div className="ui-empty-state__items ui-empty-state__items--odd-queries ui-empty-state__items--quantity-queries">
7
+ <div className="ui-empty-state__items">
8
8
  <div className="ui-empty-state__item">
9
9
  <div className="ui-empty-state__subitems">
10
10
  <div className="ui-empty-state__subitem">
@@ -21,8 +21,8 @@ const UIEmptyState = ({ title, subtitle, image, href, label }) => {
21
21
  <div className="ui-empty-state">
22
22
  <div className="ui-empty-state__section">
23
23
  <div className="ui-empty-state__subsection">
24
- <h1 className="next-heading next-heading--xl">{title}</h1>
25
- <h2 className="next-heading next-heading--subdued">{subtitle}</h2>
24
+ <h1 className="ui-empty-state__title">{title}</h1>
25
+ <h2 className="ui-empty-state__subtitle">{subtitle}</h2>
26
26
  </div>
27
27
  {imageSubsection}
28
28
  <div className="ui-empty-state__subsection">
@@ -5,6 +5,5 @@
5
5
  */
6
6
  //= require react
7
7
  //= require react_ujs
8
- //= require bootstrap-sprockets
9
8
  //= require disco_app/shopify-turbolinks
10
9
  //= require ./ui-kit
@@ -9,7 +9,7 @@
9
9
  position: fixed;
10
10
  top: 0;
11
11
  z-index: 198;
12
- left: 230px;
12
+ left: 240px;
13
13
  right: 0;
14
14
  height: 56px;
15
15
  max-width: 100vw;
@@ -37,6 +37,12 @@
37
37
  }
38
38
 
39
39
  .header__main {
40
+ color: rgba(0,0,0,0.9);
41
+ font-size: 1.42857rem;
42
+ line-height: 1.71429rem;
43
+ font-weight: 400;
44
+ z-index: 2;
45
+ overflow: hidden;
40
46
  -webkit-box-flex: 1;
41
47
  -webkit-flex: 1 0 0%;
42
48
  -ms-flex: 1 0 0%;
@@ -45,16 +51,19 @@
45
51
  -webkit-order: 1;
46
52
  -ms-flex-order: 1;
47
53
  order: 1;
48
- font-size: 24px;
49
- text-align: left;
54
+ display: -webkit-box;
55
+ display: -webkit-flex;
56
+ display: -ms-flexbox;
57
+ display: flex;
58
+ -webkit-box-align: center;
59
+ -webkit-align-items: center;
60
+ -ms-flex-align: center;
61
+ align-items: center;
50
62
  margin: 0;
51
63
  padding: 10px 0;
52
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
53
- font-weight: 300;
64
+ text-align: left;
54
65
  white-space: nowrap;
55
66
  text-overflow: ellipsis;
56
- overflow: hidden;
57
- z-index: 2;
58
67
  }
59
68
 
60
69
  .breadcrumb {
@@ -3,14 +3,6 @@
3
3
  // Styles for admin layout.
4
4
  // --------------------------------------------------
5
5
 
6
- body {
7
- line-height: 18px;
8
- font-size: 13px;
9
- color: #31373d;
10
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
11
- text-rendering: optimizeLegibility;
12
- }
13
-
14
6
  html, body {
15
7
  height: 100%;
16
8
  margin: 0;
@@ -25,7 +17,7 @@ html, body {
25
17
  }
26
18
 
27
19
  #content {
28
- padding: 56px 0 0 230px;
20
+ padding: 56px 0 0 240px;
29
21
  width: 100%;
30
22
  box-sizing: border-box;
31
23
  outline: 0;
@@ -5,7 +5,7 @@
5
5
 
6
6
  .next-nav {
7
7
  z-index: 221;
8
- width: 230px;
8
+ width: 240px;
9
9
  position: fixed;
10
10
  top: 0;
11
11
  left: 0;
@@ -29,7 +29,7 @@
29
29
 
30
30
  .next-nav__panel--primary {
31
31
  z-index: 1;
32
- width: 230px;
32
+ width: 240px;
33
33
  background-color: #31373d;
34
34
  -webkit-transition: background-color 200ms ease;
35
35
  transition: background-color 200ms ease;
@@ -110,6 +110,15 @@
110
110
  }
111
111
 
112
112
  .next-nav__link {
113
+ color: rgba(0,0,0,0.9);
114
+ font-size: 1.07143rem;
115
+ line-height: 1.42857rem;
116
+ font-weight: 400;
117
+ text-transform: initial;
118
+ letter-spacing: initial;
119
+ -webkit-font-smoothing: antialiased;
120
+ -moz-osx-font-smoothing: grayscale;
121
+ font-weight: 500;
113
122
  color: #c3cfd8;
114
123
  padding: 0 10px 0 20px;
115
124
  height: 40px;
@@ -123,9 +132,12 @@
123
132
  align-items: center;
124
133
  background-color: transparent;
125
134
  border: none;
126
- font-size: 13px;
127
135
  cursor: pointer;
128
136
  line-height: normal;
137
+
138
+ @media screen and (min-width: 640px) {
139
+ font-size: 1rem;
140
+ }
129
141
  }
130
142
 
131
143
  .next-nav__link:hover, .next-nav__link:focus, .next-nav__link:active, .next-nav__link.next-nav__link--is-selected {
@@ -2,6 +2,9 @@
2
2
  // Styles for Disco applications.
3
3
  // --------------------------------------------------
4
4
 
5
+ // Variables
6
+ $font-family: -apple-system, "BlinkMacSystemFont", "San Francisco", "Roboto", "Segoe UI", "Helvetica Neue", sans-serif;
7
+
5
8
  // Mixins and utilities.
6
9
  @import 'mixins/flexbox';
7
10
 
@@ -13,7 +13,7 @@
13
13
 
14
14
  white-space: nowrap;
15
15
  vertical-align: middle;
16
- font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
16
+ font-family: $font-family;
17
17
  font-size: 13px;
18
18
 
19
19
  -webkit-user-select: none;
@@ -10,7 +10,7 @@ input[type="text"],
10
10
  input[type="url"], {
11
11
  vertical-align: top;
12
12
  height: 32px;
13
- font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
13
+ font-family: $font-family;
14
14
  font-size: 13px;
15
15
  padding: 5px;
16
16
  margin: 0;
@@ -2,16 +2,9 @@
2
2
  // Type
3
3
  // --------------------------------------------------
4
4
 
5
- @font-face {
6
- font-family: 'ProximaNovaLight';
7
- src: local('ProximaNovaLight'), local('ProximaNova-Light');
8
- font-weight: normal;
9
- font-style: normal;
10
- }
11
-
12
5
  // Base
13
6
  html, body {
14
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
7
+ font-family: $font-family;
15
8
  font-size: 13px;
16
9
  }
17
10
 
@@ -20,7 +13,7 @@ h1 {
20
13
  font-size: 24px;
21
14
  line-height: 32px;
22
15
  height: 32px;
23
- font-family: ProximaNovaLight,"Helvetica Neue",Helvetica,Arial,sans-serif;
16
+ font-family: $font-family;
24
17
  font-weight: 300;
25
18
  margin: 0;
26
19
  padding: 0;
@@ -1,4 +1,5 @@
1
1
  // Set variables
2
+ $font-family: -apple-system, "BlinkMacSystemFont", "San Francisco", "Roboto", "Segoe UI", "Helvetica Neue", sans-serif;
2
3
  $sidebar-width: 197px;
3
4
  $header-height: 57px;
4
5
 
@@ -16,6 +16,33 @@
16
16
  }
17
17
  }
18
18
 
19
+ .ui-empty-state__title {
20
+ color: rgba(0,0,0,0.9);
21
+ font-size: 1.92857rem;
22
+ line-height: 2.57143rem;
23
+ font-weight: 400;
24
+ margin: 0 0 20px;
25
+
26
+ @media (min-width: 640px) {
27
+ font-size: 2.35714rem;
28
+ line-height: 3.14286rem;
29
+ }
30
+ }
31
+
32
+ .ui-empty-state__subtitle {
33
+ color: rgba(0,0,0,0.9);
34
+ font-size: 1.14286rem;
35
+ line-height: 1.71429rem;
36
+ font-weight: 400;
37
+ color: rgba(0,0,0,0.56);
38
+ margin: 0 0 20px;
39
+
40
+ @media (min-width: 640px) {
41
+ font-size: 1.42857rem;
42
+ line-height: 2rem;
43
+ }
44
+ }
45
+
19
46
  .ui-empty-state__section {
20
47
  padding: 60px 0;
21
48
  }
@@ -5,21 +5,24 @@
5
5
  // --------------------------------------------------
6
6
 
7
7
  .ui-footer-help {
8
- margin: 40px 0;
8
+ margin: 1.71429rem 0;
9
9
  text-align: center;
10
10
  width: 100%;
11
11
  }
12
12
 
13
13
  .ui-footer-help__content {
14
- @include inline-flex();
15
- @include align-items(center);
16
-
14
+ color: rgba(0,0,0,0.56);
15
+ display: -webkit-inline-box;
16
+ display: -webkit-inline-flex;
17
+ display: -ms-inline-flexbox;
18
+ display: inline-flex;
19
+ -webkit-box-align: center;
20
+ -webkit-align-items: center;
21
+ -ms-flex-align: center;
22
+ align-items: center;
23
+ text-align: left;
24
+ margin: 0 auto;
25
+ padding: 1.14286rem;
17
26
  border: 1px solid #d3dbe2;
18
27
  border-radius: 3px;
19
- color: #798c9c;
20
-
21
- font-size: 13px;
22
- margin: 0 auto;
23
- padding: 20px;
24
- text-align: left;
25
28
  }