hippo-fw 0.9.7 → 0.9.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (146) hide show
  1. checksums.yaml +4 -4
  2. data/.eslintrc.js +0 -3
  3. data/.nvmrc +1 -2
  4. data/.ruby-version +1 -1
  5. data/Rakefile +1 -1
  6. data/client/hippo/access/login-dialog.jsx +2 -0
  7. data/client/hippo/boot.jsx +12 -0
  8. data/client/hippo/components/asset.jsx +5 -1
  9. data/client/hippo/components/asset.scss +1 -0
  10. data/client/hippo/components/data-list.jsx +6 -4
  11. data/client/hippo/components/data-table.jsx +7 -6
  12. data/client/hippo/components/data-table/header-cell.jsx +2 -0
  13. data/client/hippo/components/date-time.jsx +12 -2
  14. data/client/hippo/components/form/api.js +12 -0
  15. data/client/hippo/components/form/fields.jsx +8 -1
  16. data/client/hippo/components/form/fields/checkbox-wrapper.jsx +2 -0
  17. data/client/hippo/components/form/fields/date-wrapper.jsx +2 -0
  18. data/client/hippo/components/form/fields/form-field.scss +2 -0
  19. data/client/hippo/components/form/fields/label.jsx +2 -0
  20. data/client/hippo/components/form/fields/react-tags.scss +170 -0
  21. data/client/hippo/components/form/fields/select-wrapper.jsx +2 -0
  22. data/client/hippo/components/form/fields/tags-wrapper.jsx +46 -0
  23. data/client/hippo/components/form/fields/text-wrapper.jsx +9 -1
  24. data/client/hippo/components/form/fields/textarea-wrapper.jsx +15 -0
  25. data/client/hippo/components/form/wrapper.jsx +21 -1
  26. data/client/hippo/components/help.jsx +21 -0
  27. data/client/hippo/components/master-detail.jsx +2 -0
  28. data/client/hippo/components/network-activity-overlay.jsx +3 -1
  29. data/client/hippo/components/popout-window.jsx +126 -0
  30. data/client/hippo/components/query-builder.jsx +9 -117
  31. data/client/hippo/components/query-builder/boolean-picker.jsx +28 -0
  32. data/client/hippo/components/query-builder/clause-filter.jsx +58 -0
  33. data/client/hippo/components/query-builder/clause.jsx +98 -0
  34. data/client/hippo/components/query-builder/date-picker.jsx +23 -0
  35. data/client/hippo/components/query-builder/query-builder.scss +7 -0
  36. data/client/hippo/components/record-finder.jsx +2 -0
  37. data/client/hippo/components/record-finder/query-layer.jsx +5 -1
  38. data/client/hippo/components/save-button.jsx +7 -1
  39. data/client/hippo/components/screen.jsx +2 -0
  40. data/client/hippo/components/text-editor.jsx +4 -5
  41. data/client/hippo/components/text-editor/display-modes/Button.jsx +5 -2
  42. data/client/hippo/components/text-editor/display-modes/ToggleEdit.jsx +2 -1
  43. data/client/hippo/components/text-editor/display-modes/ToggleInsert.jsx +2 -1
  44. data/client/hippo/components/text-editor/display-modes/ToggleLayout.jsx +2 -1
  45. data/client/hippo/components/text-editor/display-modes/TogglePreview.jsx +2 -1
  46. data/client/hippo/components/text-editor/display-modes/ToggleResize.jsx +2 -1
  47. data/client/hippo/components/text-editor/display-modes/index.js +7 -7
  48. data/client/hippo/components/text-editor/image-plugin/Component/Display/index.js +4 -2
  49. data/client/hippo/components/text-editor/image-plugin/Component/Form/index.js +2 -0
  50. data/client/hippo/components/text-editor/renderer.jsx +2 -0
  51. data/client/hippo/components/text-editor/text-editor.scss +13 -4
  52. data/client/hippo/components/time-zone-select.jsx +2 -0
  53. data/client/hippo/components/tool-tip.jsx +2 -0
  54. data/client/hippo/extensions/base.js +2 -0
  55. data/client/hippo/extensions/hippo.js +2 -0
  56. data/client/hippo/lib/__mocks__/request-assets.js +1 -2
  57. data/client/hippo/lib/bootstrap.js +2 -0
  58. data/client/hippo/lib/computed-properties.js +24 -0
  59. data/client/hippo/lib/date-range.js +13 -2
  60. data/client/hippo/lib/request-assets.js +3 -2
  61. data/client/hippo/lib/smooth-scroll.js +2 -0
  62. data/client/hippo/lib/util.js +1 -2
  63. data/client/hippo/models/asset.js +2 -0
  64. data/client/hippo/models/base.js +5 -2
  65. data/client/hippo/models/collection.js +2 -0
  66. data/client/hippo/models/config.js +3 -1
  67. data/client/hippo/models/pub_sub.js +2 -0
  68. data/client/hippo/models/pub_sub/channel.js +2 -0
  69. data/client/hippo/models/pub_sub/map.js +2 -0
  70. data/client/hippo/models/query.js +21 -12
  71. data/client/hippo/models/query/array-result.js +52 -16
  72. data/client/hippo/models/query/clause.js +11 -4
  73. data/client/hippo/models/query/field.js +2 -1
  74. data/client/hippo/models/query/info.js +7 -1
  75. data/client/hippo/models/query/operator.js +2 -0
  76. data/client/hippo/models/query/result.js +2 -0
  77. data/client/hippo/models/query/types.js +4 -0
  78. data/client/hippo/models/sync.js +2 -0
  79. data/client/hippo/models/system-setting.js +1 -15
  80. data/client/hippo/models/tenant.js +23 -7
  81. data/client/hippo/react/Root.jsx +2 -0
  82. data/client/hippo/react/component-not-found.jsx +2 -0
  83. data/client/hippo/screens/definition.js +2 -0
  84. data/client/hippo/screens/group.js +2 -0
  85. data/client/hippo/screens/instance.js +5 -1
  86. data/client/hippo/screens/system-settings.jsx +19 -5
  87. data/client/hippo/screens/system-settings/mailer-config.jsx +4 -2
  88. data/client/hippo/screens/system-settings/system-settings.scss +1 -1
  89. data/client/hippo/screens/system-settings/tenant.jsx +4 -2
  90. data/client/hippo/screens/user-management.jsx +2 -0
  91. data/client/hippo/screens/user-management/edit-form.jsx +2 -0
  92. data/client/hippo/testing/screens.js +10 -2
  93. data/client/hippo/user.js +4 -0
  94. data/client/hippo/workspace/index.jsx +3 -1
  95. data/client/hippo/workspace/menu-group.jsx +2 -0
  96. data/client/hippo/workspace/menu-option.jsx +2 -0
  97. data/client/hippo/workspace/menu.jsx +6 -3
  98. data/client/hippo/workspace/navbar.jsx +2 -0
  99. data/client/hippo/workspace/screen.jsx +2 -0
  100. data/client/hippo/workspace/styles.scss +5 -1
  101. data/command-reference-files/initial/.eslintrc.js +0 -3
  102. data/command-reference-files/initial/Gemfile +1 -1
  103. data/config/routes.rb +3 -1
  104. data/db/seed.rb +1 -1
  105. data/hippo-fw.gemspec +2 -2
  106. data/lib/hippo/api/controller_base.rb +2 -1
  107. data/lib/hippo/api/handlers/asset.rb +3 -2
  108. data/lib/hippo/api/handlers/tenant.rb +4 -6
  109. data/lib/hippo/api/helper_methods.rb +5 -7
  110. data/lib/hippo/api/route_set.rb +3 -2
  111. data/lib/hippo/asset.rb +4 -0
  112. data/lib/hippo/command/console.rb +1 -1
  113. data/lib/hippo/concerns/asset_uploader.rb +9 -4
  114. data/lib/hippo/concerns/queries.rb +3 -3
  115. data/lib/hippo/extension.rb +14 -4
  116. data/lib/hippo/extension/definition.rb +5 -1
  117. data/lib/hippo/logger.rb +26 -27
  118. data/lib/hippo/mailer.rb +19 -7
  119. data/lib/hippo/system_settings.rb +10 -4
  120. data/lib/hippo/templates/liquid.rb +1 -0
  121. data/lib/hippo/templates/liquid/pluralize.rb +16 -0
  122. data/lib/hippo/tenant.rb +17 -1
  123. data/lib/hippo/user.rb +10 -9
  124. data/lib/hippo/version.rb +1 -1
  125. data/lib/hippo/webpack.rb +22 -2
  126. data/package-lock.json +5462 -883
  127. data/package.json +9 -11
  128. data/spec/client/access/login-dialog.spec.jsx +2 -2
  129. data/spec/client/components/__snapshots__/query-builder.spec.jsx.snap +1 -1
  130. data/spec/client/components/__snapshots__/record-finder.spec.jsx.snap +1 -1
  131. data/spec/client/components/master-detail.spec.jsx +2 -1
  132. data/spec/client/components/query-builder.spec.jsx +3 -3
  133. data/spec/client/extension/base.spec.js +2 -0
  134. data/spec/client/models/base.spec.js +5 -3
  135. data/spec/client/models/query.spec.js +18 -6
  136. data/spec/client/models/sync.spec.js +2 -1
  137. data/spec/client/models/system-setting.spec.js +0 -12
  138. data/spec/client/screens/user-management.spec.jsx +1 -2
  139. data/spec/client/test-models.js +10 -0
  140. data/spec/server/api/tenant_change_spec.rb +1 -2
  141. data/spec/server/asset_spec.rb +2 -2
  142. data/templates/js/config-data.js +1 -1
  143. data/templates/spec/factories/model.rb +1 -1
  144. data/views/hippo_root_view.erb +1 -3
  145. metadata +17 -6
  146. data/client/hippo/components/text-editor/display-modes/SaveState.jsx +0 -17
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import { isNil } from 'lodash';
3
+ import CheckBox from 'grommet/components/CheckBox';
4
+ import { observer } from 'mobx-react';
5
+ import { action } from 'mobx';
6
+
7
+ @observer
8
+ export default class BooleanPicker extends React.PureComponent {
9
+
10
+ @action.bound onChange(ev) {
11
+ this.props.clause.value = ev.target.checked;
12
+ }
13
+
14
+ componentWillMount() {
15
+ if (isNil(this.props.clause.value)) {
16
+ this.props.clause.value = false;
17
+ }
18
+ }
19
+
20
+ render() {
21
+ const { props: { clause } } = this;
22
+
23
+ return (
24
+ <CheckBox checked={!!clause.value} onChange={this.onChange} />
25
+ );
26
+ }
27
+
28
+ }
@@ -0,0 +1,58 @@
1
+ import React from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { observer } from 'mobx-react';
4
+ import { action } from 'mobx';
5
+ import RadioButton from 'grommet/components/RadioButton';
6
+ import DownIcon from 'grommet/components/icons/base/Down';
7
+ import { BaseModel } from '../../models/base';
8
+ import ClauseModel from '../../models/query/clause';
9
+
10
+
11
+ @observer
12
+ export class Radio extends React.PureComponent {
13
+
14
+ static propTypes = {
15
+ name: PropTypes.string.isRequired,
16
+ onSelect: PropTypes.func.isRequired,
17
+ model: PropTypes.instanceOf(BaseModel).isRequired,
18
+ clause: PropTypes.instanceOf(ClauseModel).isRequired,
19
+ }
20
+
21
+ @action.bound
22
+ onChange() {
23
+ this.props.clause[this.props.name] = this.props.model;
24
+ this.props.onSelect();
25
+ }
26
+
27
+ render() {
28
+ const { model } = this.props;
29
+ return (
30
+ <RadioButton
31
+ id={model.id}
32
+ name={model.id}
33
+ label={model.label}
34
+ onChange={this.onChange}
35
+ checked={(this.props.clause[this.props.name] === model)}
36
+ />
37
+ );
38
+ }
39
+
40
+ }
41
+
42
+ @observer
43
+ export class ClauseFilter extends React.PureComponent {
44
+
45
+ static propTypes = {
46
+ clause: PropTypes.instanceOf(ClauseModel).isRequired,
47
+ }
48
+
49
+ render() {
50
+ const { clause } = this.props;
51
+ return (
52
+ <span>
53
+ <DownIcon /> {clause.field.label} {clause.operator.label}
54
+ </span>
55
+ );
56
+ }
57
+
58
+ }
@@ -0,0 +1,98 @@
1
+ import React from 'react';
2
+ import { defaults } from 'lodash';
3
+ import PropTypes from 'prop-types';
4
+ import { observer } from 'mobx-react';
5
+ import { action } from 'mobx';
6
+ import Box from 'grommet/components/Box';
7
+ import Menu from 'grommet/components/Menu';
8
+ import TextInput from 'grommet/components/TextInput';
9
+ import ClauseModel from '../../models/query/clause';
10
+ import { Radio, ClauseFilter } from './clause-filter';
11
+ import BooleanPicker from './boolean-picker';
12
+ import DatePicker from './date-picker';
13
+
14
+ const defaultHandlers = {
15
+ boolean: BooleanPicker,
16
+ date: DatePicker,
17
+ };
18
+
19
+ @observer
20
+ export default class Clause extends React.PureComponent {
21
+
22
+ static defaultProps = {
23
+ typeHandlers: {},
24
+ }
25
+
26
+ static propTypes = {
27
+ clause: PropTypes.instanceOf(ClauseModel).isRequired,
28
+ typeHandlers: PropTypes.object,
29
+ }
30
+
31
+ @action.bound
32
+ onSelect() {
33
+ this.menuRef._onClose();
34
+ }
35
+
36
+ @action.bound
37
+ onValueChange(ev) {
38
+ this.props.clause.value = ev.target.value;
39
+ }
40
+
41
+ @action.bound
42
+ setMenuRef(ref) {
43
+ this.menuRef = ref;
44
+ }
45
+
46
+ get handlers() {
47
+ return defaults(this.props.typeHandlers, defaultHandlers);
48
+ }
49
+
50
+ renderInputTag() {
51
+ const Tag = this.handlers[this.props.clause.field.dataType];
52
+
53
+ if (Tag) {
54
+ return <Tag clause={this.props.clause} />;
55
+ }
56
+ return (
57
+ <TextInput
58
+ autoFocus
59
+ style={{ flex: 1 }}
60
+ value={this.props.clause.value || ''}
61
+ onDOMChange={this.onValueChange}
62
+ />
63
+ );
64
+ }
65
+
66
+ render() {
67
+ const { props: { clause } } = this;
68
+
69
+ return (
70
+ <Box className="clause" direction='row' pad={{ between: 'small' }} align="center">
71
+ <Menu
72
+ ref={this.setMenuRef}
73
+ size='large'
74
+ pad='small'
75
+ closeOnClick={false} icon={<ClauseFilter clause={clause} />}
76
+ >
77
+ <Box direction='row' pad="small">
78
+ <Box size="small" pad={{ between: 'small' }}>
79
+ {clause.query.info.queryableFields.map(f =>
80
+ <Radio
81
+ key={f.id} model={f} clause={clause}
82
+ onSelect={this.onSelect} name='field' />)}
83
+ </Box>
84
+ <Box size="small" pad={{ between: 'small' }}>
85
+ {clause.validOperators.map(o =>
86
+ <Radio
87
+ key={o.id} model={o} clause={clause}
88
+ onSelect={this.onSelect} name='operator'
89
+ />)}
90
+ </Box>
91
+ </Box>
92
+ </Menu>
93
+ {this.renderInputTag()}
94
+ </Box>
95
+ );
96
+ }
97
+
98
+ }
@@ -0,0 +1,23 @@
1
+ import React from 'react';
2
+ import { observer } from 'mobx-react';
3
+ import { action } from 'mobx';
4
+ import DateTime from '../date-time';
5
+
6
+ @observer
7
+ export default class DatePicker extends React.PureComponent {
8
+
9
+ @action.bound onChange({ target: { value: dates } }) {
10
+ this.props.clause.value = `${dates[0].toISOString()}...${dates[1].toISOString()}`;
11
+ }
12
+
13
+ render() {
14
+ return (
15
+ <DateTime
16
+ format="M d Y"
17
+ options={{ enableTime: false, mode: 'range' }}
18
+ onChange={this.onChange}
19
+ />
20
+ );
21
+ }
22
+
23
+ }
@@ -0,0 +1,7 @@
1
+ .query-builder {
2
+ .clause {
3
+ :last-child {
4
+ flex: 1;
5
+ }
6
+ }
7
+ }
@@ -16,6 +16,7 @@ import QueryLayer from './record-finder/query-layer';
16
16
  @inject('formState')
17
17
  @observer
18
18
  export default class RecordFinder extends React.PureComponent {
19
+
19
20
  static propTypes = {
20
21
  query: PropTypes.instanceOf(Query).isRequired,
21
22
  name: PropTypes.string.isRequired,
@@ -89,4 +90,5 @@ export default class RecordFinder extends React.PureComponent {
89
90
  </Field>
90
91
  );
91
92
  }
93
+
92
94
  }
@@ -16,6 +16,7 @@ import QueryBuilder from '../query-builder';
16
16
 
17
17
  @observer
18
18
  export default class QueryLayer extends React.PureComponent {
19
+
19
20
  static propTypes = {
20
21
  title: PropTypes.string.isRequired,
21
22
  onClose: PropTypes.func.isRequired,
@@ -32,7 +33,9 @@ export default class QueryLayer extends React.PureComponent {
32
33
  }
33
34
 
34
35
  render() {
35
- const { visible, query, onClose, title } = this.props;
36
+ const {
37
+ visible, query, onClose, title,
38
+ } = this.props;
36
39
  if (!visible) { return null; }
37
40
 
38
41
  return (
@@ -67,4 +70,5 @@ export default class QueryLayer extends React.PureComponent {
67
70
  </Layer>
68
71
  );
69
72
  }
73
+
70
74
  }
@@ -13,6 +13,7 @@ import { BaseModel } from '../models/base';
13
13
 
14
14
  @observer
15
15
  export default class SaveButton extends React.PureComponent {
16
+
16
17
  static propTypes = {
17
18
  busy: PropTypes.bool,
18
19
  model: PropTypes.instanceOf(BaseModel),
@@ -39,7 +40,11 @@ export default class SaveButton extends React.PureComponent {
39
40
 
40
41
  render() {
41
42
  // eslint-disable-next-line no-unused-vars
42
- const { label, icon, props: { busyLabel, busy, model, label: _, ...props } } = this;
43
+ const {
44
+ label, icon, props: {
45
+ label: _, busyLabel: __, busy, model: ___, ...props
46
+ },
47
+ } = this;
43
48
 
44
49
  return (
45
50
  <Button
@@ -52,4 +57,5 @@ export default class SaveButton extends React.PureComponent {
52
57
  />
53
58
  );
54
59
  }
60
+
55
61
  }
@@ -7,6 +7,7 @@ import ScreenInstance from '../screens/instance';
7
7
 
8
8
  @observer
9
9
  export default class Screen extends React.Component {
10
+
10
11
  static Instance = ScreenInstance;
11
12
 
12
13
  static defaultProps = {
@@ -35,4 +36,5 @@ export default class Screen extends React.Component {
35
36
  </div>
36
37
  );
37
38
  }
39
+
38
40
  }
@@ -24,14 +24,15 @@ const editorInstance = new Editor({
24
24
 
25
25
  @observer
26
26
  export default class TextEditor extends React.PureComponent {
27
+
27
28
  static defaultProps = {
28
29
  assets: observable.array(),
29
30
  }
30
31
 
31
32
  static propTypes = {
32
33
  defaultContent: PropTypes.object,
34
+ onChange: PropTypes.func.isRequired,
33
35
  assets: MobxPropTypes.observableArray,
34
- onComplete: PropTypes.func.isRequired,
35
36
  }
36
37
 
37
38
  componentWillMount() {
@@ -40,14 +41,11 @@ export default class TextEditor extends React.PureComponent {
40
41
  editorInstance.trigger.editable.add(this.content);
41
42
  }
42
43
 
43
- @action.bound
44
- onSave() {
45
- this.props.onComplete({ content: this.content });
46
- }
47
44
 
48
45
  @action.bound
49
46
  onEditStateChange(state) {
50
47
  this.content = state;
48
+ this.props.onChange(state);
51
49
  }
52
50
 
53
51
  render() {
@@ -77,4 +75,5 @@ export default class TextEditor extends React.PureComponent {
77
75
  </Provider>
78
76
  );
79
77
  }
78
+
80
79
  }
@@ -1,8 +1,11 @@
1
1
  import React from 'react'; // eslint-disable-line no-unused-vars
2
2
  import Button from 'grommet/components/Button';
3
+ import cn from 'classnames';
3
4
 
4
- const DisplayModeButton = ({ label, icon, onClick, active, disabled }) => (
5
- <span className={active ? 'active' : ''}>
5
+ const DisplayModeButton = ({
6
+ className, label, icon, onClick, active, disabled,
7
+ }) => (
8
+ <span className={cn(className, { active })}>
6
9
  <Button
7
10
  plain
8
11
  secondary={active}
@@ -7,8 +7,9 @@ import { createStructuredSelector } from 'reselect';
7
7
  import EditIcon from 'grommet/components/icons/base/Edit';
8
8
  import Button from './Button';
9
9
 
10
- const Inner = ({ isEditMode: isedm, editMode: edm }) => (
10
+ const Inner = ({ className, isEditMode: isedm, editMode: edm }) => (
11
11
  <Button
12
+ className={className}
12
13
  icon={<EditIcon />}
13
14
  label="Edit"
14
15
  active={isedm}
@@ -6,8 +6,9 @@ import { isInsertMode } from 'ory-editor-core/lib/selector/display';
6
6
  import { createStructuredSelector } from 'reselect';
7
7
  import Button from './Button';
8
8
 
9
- const Inner = ({ isInsertMode: isinm, insertMode: inm }) => (
9
+ const Inner = ({ className, isInsertMode: isinm, insertMode: inm }) => (
10
10
  <Button
11
+ className={className}
11
12
  icon={<AddIcon />}
12
13
  label="Add"
13
14
  active={isinm}
@@ -6,8 +6,9 @@ import { isLayoutMode } from 'ory-editor-core/lib/selector/display';
6
6
  import { createStructuredSelector } from 'reselect';
7
7
  import Button from './Button';
8
8
 
9
- const Inner = ({ isLayoutMode: islm, layoutMode: lm }) => (
9
+ const Inner = ({ className, isLayoutMode: islm, layoutMode: lm }) => (
10
10
  <Button
11
+ className={className}
11
12
  icon={<GridIcon />}
12
13
  label="Layout"
13
14
  active={islm}
@@ -6,8 +6,9 @@ import { isPreviewMode } from 'ory-editor-core/lib/selector/display';
6
6
  import { createStructuredSelector } from 'reselect';
7
7
  import Button from './Button';
8
8
 
9
- const Inner = ({ isPreviewMode: ispvm, previewMode: pvm }) => (
9
+ const Inner = ({ className, isPreviewMode: ispvm, previewMode: pvm }) => (
10
10
  <Button
11
+ className={className}
11
12
  icon={<Devices />}
12
13
  label="Preview"
13
14
  active={ispvm}
@@ -6,8 +6,9 @@ import { isResizeMode } from 'ory-editor-core/lib/selector/display';
6
6
  import { createStructuredSelector } from 'reselect';
7
7
  import Button from './Button';
8
8
 
9
- const Inner = ({ isResizeMode: isrsm, resizeMode: rsm }) => (
9
+ const Inner = ({ className, isResizeMode: isrsm, resizeMode: rsm }) => (
10
10
  <Button
11
+ className={className}
11
12
  icon={<ResizeIcon />}
12
13
  label="Resize"
13
14
  active={isrsm}
@@ -6,23 +6,23 @@ import ToggleInsert from './ToggleInsert';
6
6
  import ToggleLayout from './ToggleLayout';
7
7
  import TogglePreview from './TogglePreview';
8
8
  import ToggleResize from './ToggleResize';
9
- import SaveState from './SaveState';
9
+
10
10
 
11
11
  const Inner = (props: any) => (
12
12
  <Provider {...props}>
13
13
  <Header
14
14
  wrap
15
+
15
16
  margin="small"
16
17
  justify="end"
17
18
  pad={{ horizontal: 'small' }}
18
19
  >
19
- <ToggleInsert />
20
- <ToggleEdit />
21
- <ToggleLayout />
22
- <ToggleResize />
23
- <TogglePreview />
20
+ <ToggleInsert className="insert" />
21
+ <ToggleEdit className="edit" />
22
+ <ToggleLayout className="layout" />
23
+ <ToggleResize className="resize" />
24
+ <TogglePreview className="preview" />
24
25
  {props.children}
25
- <SaveState onSave={props.onSave} />
26
26
  </Header>
27
27
  </Provider>
28
28
  );
@@ -23,6 +23,7 @@ const iconStyle = {
23
23
  @inject('assets')
24
24
  @observer
25
25
  export default class Display extends React.PureComponent {
26
+
26
27
  @computed get asset() {
27
28
  return find(this.props.assets, asset =>
28
29
  asset.metadata && asset.metadata.nodeId === this.props.id);
@@ -30,7 +31,7 @@ export default class Display extends React.PureComponent {
30
31
 
31
32
  @action.bound
32
33
  onFileDrop(files) {
33
- let asset = this.asset;
34
+ let { asset } = this;
34
35
  if (!asset) {
35
36
  this.props.assets.push({ metadata: { nodeId: this.props.id } });
36
37
  asset = this.props.assets.get(this.props.assets.length - 1);
@@ -63,7 +64,7 @@ export default class Display extends React.PureComponent {
63
64
  <div className={cn('content-image-wrapper', { focused })}>
64
65
  <Button onClick={this.onAddClick}>{state.src ? 'Change' : 'Add'}</Button>
65
66
  <Dropzone
66
- ref={dz => (this.dropZone = dz)}
67
+ ref={(dz) => { this.dropZone = dz; }}
67
68
  style={{}}
68
69
  disableClick
69
70
  multiple={false}
@@ -77,4 +78,5 @@ export default class Display extends React.PureComponent {
77
78
  }
78
79
  return this.renderImage();
79
80
  }
81
+
80
82
  }