hippo-fw 0.9.4 → 0.9.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/.travis.yml +2 -3
- data/Gemfile +1 -1
- data/client/hippo/__mocks__/config.js +4 -4
- data/client/hippo/boot.jsx +1 -0
- data/client/hippo/components/asset.jsx +4 -4
- data/client/hippo/components/date-time.jsx +169 -0
- data/client/hippo/components/date-time.scss +38 -0
- data/client/hippo/components/date-time/calendar.jsx +115 -0
- data/client/hippo/components/date-time/date-time-drop.jsx +77 -0
- data/client/hippo/components/date-time/date-time.scss +157 -0
- data/client/hippo/components/date-time/time.jsx +120 -0
- data/client/hippo/components/form/fields/date-wrapper.jsx +4 -3
- data/client/hippo/components/form/model.js +0 -2
- data/client/hippo/components/text-editor.jsx +85 -0
- data/client/hippo/components/text-editor/display-modes/Button.jsx +17 -0
- data/client/hippo/components/text-editor/display-modes/SaveState.jsx +17 -0
- data/client/hippo/components/text-editor/display-modes/ToggleEdit.jsx +22 -0
- data/client/hippo/components/text-editor/display-modes/ToggleInsert.jsx +21 -0
- data/client/hippo/components/text-editor/display-modes/ToggleLayout.jsx +21 -0
- data/client/hippo/components/text-editor/display-modes/TogglePreview.jsx +21 -0
- data/client/hippo/components/text-editor/display-modes/ToggleResize.jsx +21 -0
- data/client/hippo/components/text-editor/display-modes/index.css +0 -0
- data/client/hippo/components/text-editor/display-modes/index.js +30 -0
- data/client/hippo/components/text-editor/image-plugin/Component/Display/index.js +80 -0
- data/client/hippo/components/text-editor/image-plugin/Component/Form/index.js +40 -0
- data/client/hippo/components/text-editor/image-plugin/Component/index.js +16 -0
- data/client/hippo/components/text-editor/image-plugin/Component/index.scss +0 -0
- data/client/hippo/components/text-editor/image-plugin/index.js +32 -0
- data/client/hippo/components/text-editor/image-plugin/index.scss +25 -0
- data/client/hippo/components/text-editor/plugins.js +22 -0
- data/client/hippo/components/text-editor/renderer.jsx +37 -0
- data/client/hippo/components/text-editor/text-editor.scss +49 -0
- data/client/hippo/extensions/base.js +5 -2
- data/client/hippo/extensions/hippo.js +5 -2
- data/client/hippo/extensions/index.js +9 -3
- data/client/hippo/lib/__mocks__/request-assets.js +2 -2
- data/client/hippo/lib/bootstrap.js +0 -1
- data/client/hippo/lib/smooth-scroll.js +0 -1
- data/client/hippo/lib/util.js +4 -4
- data/client/hippo/models/asset.js +43 -23
- data/client/hippo/models/base.js +1 -2
- data/client/hippo/models/config.js +0 -1
- data/client/hippo/models/decorators.js +3 -3
- data/client/hippo/models/pub_sub.js +2 -5
- data/client/hippo/models/pub_sub/channel.js +0 -1
- data/client/hippo/models/query.js +0 -1
- data/client/hippo/models/query/array-result.js +0 -1
- data/client/hippo/models/query/clause.js +0 -1
- data/client/hippo/models/query/field.js +0 -1
- data/client/hippo/models/query/info.js +0 -3
- data/client/hippo/models/query/operator.js +0 -2
- data/client/hippo/models/query/result.js +0 -1
- data/client/hippo/models/sync.js +1 -1
- data/client/hippo/models/system-setting.js +0 -2
- data/client/hippo/models/tenant.js +0 -1
- data/client/hippo/screens/definition.js +0 -2
- data/client/hippo/screens/group.js +0 -2
- data/client/hippo/screens/instance.js +0 -3
- data/client/hippo/screens/system-settings/mailer-config.jsx +0 -3
- data/client/hippo/styles/global.scss +3 -0
- data/client/hippo/testing/mocks/fetch.js +6 -6
- data/client/hippo/user.js +4 -4
- data/client/hippo/workspace/index.jsx +12 -5
- data/client/hippo/workspace/root-view.jsx +10 -0
- data/command-reference-files/initial/.gitignore +1 -0
- data/command-reference-files/initial/Gemfile +1 -1
- data/command-reference-files/initial/client/appy-app/extension.js +4 -0
- data/command-reference-files/initial/config/webpack.config.js +25 -23
- data/config/routes.rb +4 -1
- data/config/webpack.config.js +1 -2
- data/hippo-fw.gemspec +4 -2
- data/lib/hippo.rb +0 -1
- data/lib/hippo/api/handlers/asset.rb +9 -0
- data/lib/hippo/api/updates.rb +2 -2
- data/lib/hippo/configuration.rb +0 -4
- data/lib/hippo/db.rb +2 -2
- data/lib/hippo/{rails.rb → db/fake_rails.rb} +0 -0
- data/lib/hippo/extension.rb +1 -2
- data/lib/hippo/mailer.rb +1 -0
- data/lib/hippo/spec_helper.rb +1 -0
- data/lib/hippo/version.rb +1 -1
- data/package-lock.json +626 -68
- data/package.json +14 -13
- data/spec/client/access/login-dialog.spec.jsx +1 -0
- data/spec/client/components/asset.spec.jsx +1 -2
- data/spec/client/components/date-time.spec.jsx +20 -0
- data/spec/client/extension/base.spec.js +0 -2
- data/spec/client/models/base.spec.js +4 -4
- data/spec/client/models/query.spec.js +2 -2
- data/spec/client/models/sync.spec.js +1 -1
- data/spec/client/screens/system-settings.spec.jsx +2 -1
- data/spec/client/setup.js +3 -0
- data/spec/client/test-models.js +0 -2
- data/spec/server/api/tenant_change_spec.rb +1 -1
- data/spec/server/api/tenant_isolation_spec.rb +6 -3
- data/spec/server/concerns/api_path_spec.rb +2 -2
- data/templates/.gitignore +1 -0
- data/templates/client/extension.js +4 -0
- data/templates/config/webpack.config.js +25 -23
- metadata +48 -12
- data/client/hippo/lib/pub_sub.js +0 -34
- data/client/hippo/react/viewport-root.jsx +0 -44
- data/spec/client/components/__snapshots__/asset.spec.jsx.snap +0 -48
- data/spec/client/screens/__snapshots__/system-settings.spec.jsx.snap +0 -443
- data/templates/gitignore +0 -4
@@ -0,0 +1,21 @@
|
|
1
|
+
import React from 'react'; // eslint-disable-line no-unused-vars
|
2
|
+
import AddIcon from 'grommet/components/icons/base/TableAdd';
|
3
|
+
import { connect } from 'react-redux';
|
4
|
+
import { insertMode } from 'ory-editor-core/lib/actions/display';
|
5
|
+
import { isInsertMode } from 'ory-editor-core/lib/selector/display';
|
6
|
+
import { createStructuredSelector } from 'reselect';
|
7
|
+
import Button from './Button';
|
8
|
+
|
9
|
+
const Inner = ({ isInsertMode: isinm, insertMode: inm }) => (
|
10
|
+
<Button
|
11
|
+
icon={<AddIcon />}
|
12
|
+
label="Add"
|
13
|
+
active={isinm}
|
14
|
+
onClick={inm}
|
15
|
+
/>
|
16
|
+
);
|
17
|
+
|
18
|
+
const mapStateToProps = createStructuredSelector({ isInsertMode });
|
19
|
+
const mapDispatchToProps = { insertMode };
|
20
|
+
|
21
|
+
export default connect(mapStateToProps, mapDispatchToProps)(Inner);
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import React from 'react'; // eslint-disable-line no-unused-vars
|
2
|
+
import GridIcon from 'grommet/components/icons/base/Grid';
|
3
|
+
import { connect } from 'react-redux';
|
4
|
+
import { layoutMode } from 'ory-editor-core/lib/actions/display';
|
5
|
+
import { isLayoutMode } from 'ory-editor-core/lib/selector/display';
|
6
|
+
import { createStructuredSelector } from 'reselect';
|
7
|
+
import Button from './Button';
|
8
|
+
|
9
|
+
const Inner = ({ isLayoutMode: islm, layoutMode: lm }) => (
|
10
|
+
<Button
|
11
|
+
icon={<GridIcon />}
|
12
|
+
label="Layout"
|
13
|
+
active={islm}
|
14
|
+
onClick={lm}
|
15
|
+
/>
|
16
|
+
);
|
17
|
+
|
18
|
+
const mapStateToProps = createStructuredSelector({ isLayoutMode });
|
19
|
+
const mapDispatchToProps = { layoutMode };
|
20
|
+
|
21
|
+
export default connect(mapStateToProps, mapDispatchToProps)(Inner);
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import React from 'react'; // eslint-disable-line no-unused-vars
|
2
|
+
import Devices from 'material-ui/svg-icons/device/devices';
|
3
|
+
import { connect } from 'react-redux';
|
4
|
+
import { previewMode } from 'ory-editor-core/lib/actions/display';
|
5
|
+
import { isPreviewMode } from 'ory-editor-core/lib/selector/display';
|
6
|
+
import { createStructuredSelector } from 'reselect';
|
7
|
+
import Button from './Button';
|
8
|
+
|
9
|
+
const Inner = ({ isPreviewMode: ispvm, previewMode: pvm }) => (
|
10
|
+
<Button
|
11
|
+
icon={<Devices />}
|
12
|
+
label="Preview"
|
13
|
+
active={ispvm}
|
14
|
+
onClick={pvm}
|
15
|
+
/>
|
16
|
+
);
|
17
|
+
|
18
|
+
const mapStateToProps = createStructuredSelector({ isPreviewMode });
|
19
|
+
const mapDispatchToProps = { previewMode };
|
20
|
+
|
21
|
+
export default connect(mapStateToProps, mapDispatchToProps)(Inner);
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import React from 'react'; // eslint-disable-line no-unused-vars
|
2
|
+
import ResizeIcon from 'grommet/components/icons/base/Pan';
|
3
|
+
import { connect } from 'react-redux';
|
4
|
+
import { resizeMode } from 'ory-editor-core/lib/actions/display';
|
5
|
+
import { isResizeMode } from 'ory-editor-core/lib/selector/display';
|
6
|
+
import { createStructuredSelector } from 'reselect';
|
7
|
+
import Button from './Button';
|
8
|
+
|
9
|
+
const Inner = ({ isResizeMode: isrsm, resizeMode: rsm }) => (
|
10
|
+
<Button
|
11
|
+
icon={<ResizeIcon />}
|
12
|
+
label="Resize"
|
13
|
+
active={isrsm}
|
14
|
+
onClick={rsm}
|
15
|
+
/>
|
16
|
+
);
|
17
|
+
|
18
|
+
const mapStateToProps = createStructuredSelector({ isResizeMode });
|
19
|
+
const mapDispatchToProps = { resizeMode };
|
20
|
+
|
21
|
+
export default connect(mapStateToProps, mapDispatchToProps)(Inner);
|
File without changes
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import React from 'react'; // eslint-disable-line no-unused-vars
|
2
|
+
import Header from 'grommet/components/Header';
|
3
|
+
import Provider from 'ory-editor-ui/lib/Provider';
|
4
|
+
import ToggleEdit from './ToggleEdit';
|
5
|
+
import ToggleInsert from './ToggleInsert';
|
6
|
+
import ToggleLayout from './ToggleLayout';
|
7
|
+
import TogglePreview from './TogglePreview';
|
8
|
+
import ToggleResize from './ToggleResize';
|
9
|
+
import SaveState from './SaveState';
|
10
|
+
|
11
|
+
const Inner = (props: any) => (
|
12
|
+
<Provider {...props}>
|
13
|
+
<Header
|
14
|
+
wrap
|
15
|
+
margin="small"
|
16
|
+
justify="end"
|
17
|
+
pad={{ horizontal: 'small' }}
|
18
|
+
>
|
19
|
+
<ToggleInsert />
|
20
|
+
<ToggleEdit />
|
21
|
+
<ToggleLayout />
|
22
|
+
<ToggleResize />
|
23
|
+
<TogglePreview />
|
24
|
+
{props.children}
|
25
|
+
<SaveState onSave={props.onSave} />
|
26
|
+
</Header>
|
27
|
+
</Provider>
|
28
|
+
);
|
29
|
+
|
30
|
+
export default Inner;
|
@@ -0,0 +1,80 @@
|
|
1
|
+
// @flow
|
2
|
+
import React from 'react';
|
3
|
+
import { observer, inject } from 'mobx-react';
|
4
|
+
import { action, computed } from 'mobx';
|
5
|
+
import { find } from 'lodash';
|
6
|
+
import Dropzone from 'react-dropzone';
|
7
|
+
import Button from 'grommet/components/Button';
|
8
|
+
import ImageIcon from 'grommet/components/icons/base/Image';
|
9
|
+
import cn from 'classnames';
|
10
|
+
|
11
|
+
const iconStyle = {
|
12
|
+
width: '100%',
|
13
|
+
height: 'auto',
|
14
|
+
padding: '0',
|
15
|
+
color: '#aaa',
|
16
|
+
textAlign: 'center',
|
17
|
+
minWidth: 64,
|
18
|
+
minHeight: 64,
|
19
|
+
maxHeight: 256,
|
20
|
+
};
|
21
|
+
|
22
|
+
|
23
|
+
@inject('assets')
|
24
|
+
@observer
|
25
|
+
export default class Display extends React.PureComponent {
|
26
|
+
@computed get asset() {
|
27
|
+
return find(this.props.assets, asset =>
|
28
|
+
asset.metadata && asset.metadata.nodeId === this.props.id);
|
29
|
+
}
|
30
|
+
|
31
|
+
@action.bound
|
32
|
+
onFileDrop(files) {
|
33
|
+
let asset = this.asset;
|
34
|
+
if (!asset) {
|
35
|
+
this.props.assets.push({ metadata: { nodeId: this.props.id } });
|
36
|
+
asset = this.props.assets.get(this.props.assets.length - 1);
|
37
|
+
}
|
38
|
+
|
39
|
+
asset.setFile(files[0]).then(() => {
|
40
|
+
this.props.onChange({ src: asset.previewUrl });
|
41
|
+
asset.save().then(() => {
|
42
|
+
this.props.onChange({
|
43
|
+
assetId: asset.id, src: asset.urlFor(),
|
44
|
+
});
|
45
|
+
});
|
46
|
+
});
|
47
|
+
}
|
48
|
+
|
49
|
+
renderImage() {
|
50
|
+
const { state: { src } } = this.props;
|
51
|
+
return src ? <img className="content-image" src={src} /> : <ImageIcon style={iconStyle} />;
|
52
|
+
}
|
53
|
+
|
54
|
+
@action.bound
|
55
|
+
onAddClick() {
|
56
|
+
this.dropZone.open();
|
57
|
+
}
|
58
|
+
|
59
|
+
render() {
|
60
|
+
const { isEditMode, state, focused } = this.props;
|
61
|
+
if (isEditMode) {
|
62
|
+
return (
|
63
|
+
<div className={cn('content-image-wrapper', { focused })}>
|
64
|
+
<Button onClick={this.onAddClick}>{state.src ? 'Change' : 'Add'}</Button>
|
65
|
+
<Dropzone
|
66
|
+
ref={dz => (this.dropZone = dz)}
|
67
|
+
style={{}}
|
68
|
+
disableClick
|
69
|
+
multiple={false}
|
70
|
+
onDrop={this.onFileDrop}
|
71
|
+
className="image-drop-zone"
|
72
|
+
>
|
73
|
+
{this.renderImage()}
|
74
|
+
</Dropzone>
|
75
|
+
</div>
|
76
|
+
);
|
77
|
+
}
|
78
|
+
return this.renderImage();
|
79
|
+
}
|
80
|
+
}
|
@@ -0,0 +1,40 @@
|
|
1
|
+
// @flow
|
2
|
+
import React from 'react';
|
3
|
+
import { inject, observer } from 'mobx-react';
|
4
|
+
import Dropzone from 'react-dropzone';
|
5
|
+
import { action } from 'mobx';
|
6
|
+
import { BottomToolbar } from 'ory-editor-ui';
|
7
|
+
|
8
|
+
import Display from '../Display';
|
9
|
+
|
10
|
+
@inject('model', 'images_attribute')
|
11
|
+
@observer
|
12
|
+
export default class Form extends React.PureComponent {
|
13
|
+
get assets() {
|
14
|
+
return this.props.model[this.props.images_attribute];
|
15
|
+
}
|
16
|
+
|
17
|
+
@action.bound
|
18
|
+
onFileDrop(files) {
|
19
|
+
this.assets.push({});
|
20
|
+
const asset = this.assets.at(this.assets.length - 1);
|
21
|
+
asset.setFile(files[0]);
|
22
|
+
}
|
23
|
+
|
24
|
+
render() {
|
25
|
+
const { props } = this;
|
26
|
+
|
27
|
+
return (
|
28
|
+
<div>
|
29
|
+
<Display {...props} />
|
30
|
+
<BottomToolbar open={props.focused}>
|
31
|
+
<Dropzone
|
32
|
+
onDrop={this.onFileDrop}
|
33
|
+
>
|
34
|
+
Drop a file here, or click to select one to upload.
|
35
|
+
</Dropzone>
|
36
|
+
</BottomToolbar>
|
37
|
+
</div>
|
38
|
+
);
|
39
|
+
}
|
40
|
+
}
|
@@ -0,0 +1,16 @@
|
|
1
|
+
// @flow
|
2
|
+
import React from 'react'; // eslint-disable-line no-unused-vars
|
3
|
+
import getMuiTheme from 'material-ui/styles/getMuiTheme';
|
4
|
+
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
|
5
|
+
import type { ContentPluginProps } from 'ory-editor-core/lib/service/plugin/classes';
|
6
|
+
import Display from './Display';
|
7
|
+
|
8
|
+
export type PropTypes = ContentPluginProps<{ src: string, caption: string }>
|
9
|
+
|
10
|
+
const Image = (props: PropTypes) => (
|
11
|
+
<MuiThemeProvider muiTheme={getMuiTheme()}>
|
12
|
+
<Display {...props} />
|
13
|
+
</MuiThemeProvider>
|
14
|
+
);
|
15
|
+
|
16
|
+
export default Image;
|
File without changes
|
@@ -0,0 +1,32 @@
|
|
1
|
+
// @flow
|
2
|
+
import React from 'react'; // eslint-disable-line no-unused-vars
|
3
|
+
import Panorama from 'material-ui/svg-icons/image/panorama';
|
4
|
+
import './index.scss';
|
5
|
+
import Asset from '../../../models/asset';
|
6
|
+
import Component from './Component';
|
7
|
+
|
8
|
+
export default {
|
9
|
+
Component,
|
10
|
+
name: 'ory/editor/core/content/image',
|
11
|
+
version: '0.0.1',
|
12
|
+
IconComponent: <Panorama />,
|
13
|
+
text: 'Image',
|
14
|
+
isInlineable: true,
|
15
|
+
description: 'Loads an image from an url.',
|
16
|
+
|
17
|
+
handleRemoveHotKey(ev, node) {
|
18
|
+
if (node.content.state.assetId) {
|
19
|
+
const asset = new Asset({ id: node.content.state.assetId });
|
20
|
+
return asset.destroy();
|
21
|
+
}
|
22
|
+
return Promise.resolve(node);
|
23
|
+
},
|
24
|
+
|
25
|
+
// We need this because otherwise we lose hotkey focus on elements like spoilers.
|
26
|
+
// This could probably be solved in an easier way by listening to window.document?
|
27
|
+
|
28
|
+
handleFocus: (props: any, source: any, ref: HTMLElement) => {
|
29
|
+
if (!ref) { return; }
|
30
|
+
setTimeout(() => ref.focus());
|
31
|
+
},
|
32
|
+
};
|
@@ -0,0 +1,25 @@
|
|
1
|
+
@import 'hippo/styles/global';
|
2
|
+
|
3
|
+
.ory-plugins-content-image {
|
4
|
+
width: 100%;
|
5
|
+
}
|
6
|
+
|
7
|
+
.ory-plugins-content-image-placeholder {
|
8
|
+
position: relative;
|
9
|
+
width: 100%;
|
10
|
+
text-align: center;
|
11
|
+
}
|
12
|
+
|
13
|
+
.content-image-wrapper {
|
14
|
+
border: 1px solid rgba(0, 0, 0, 0.15);
|
15
|
+
cursor: pointer;
|
16
|
+
&.focused {
|
17
|
+
border-width: 2px;
|
18
|
+
border-color: $focus-border-color;
|
19
|
+
}
|
20
|
+
button {
|
21
|
+
position: absolute;
|
22
|
+
top: 1rem;
|
23
|
+
right: 1rem;
|
24
|
+
}
|
25
|
+
}
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import spacer from 'ory-editor-plugins-spacer';
|
2
|
+
import slate from 'ory-editor-plugins-slate';
|
3
|
+
import video from 'ory-editor-plugins-video';
|
4
|
+
import parallax from 'ory-editor-plugins-parallax-background';
|
5
|
+
import 'ory-editor-plugins-parallax-background/lib/index.css';
|
6
|
+
import divider from 'ory-editor-plugins-divider';
|
7
|
+
|
8
|
+
import 'ory-editor-plugins-image/lib/index.css';
|
9
|
+
import 'ory-editor-plugins-spacer/lib/index.css';
|
10
|
+
import 'ory-editor-plugins-video/lib/index.css';
|
11
|
+
import 'ory-editor-plugins-slate/lib/index.css';
|
12
|
+
|
13
|
+
import image from './image-plugin';
|
14
|
+
|
15
|
+
const defaultPlugin = slate();
|
16
|
+
|
17
|
+
const plugins = {
|
18
|
+
content: [slate(), spacer, divider, image, video], // Define plugins for content cells
|
19
|
+
layout: [parallax({ defaultPlugin })],
|
20
|
+
};
|
21
|
+
|
22
|
+
export { defaultPlugin, plugins };
|
@@ -0,0 +1,37 @@
|
|
1
|
+
import React from 'react';
|
2
|
+
import PropTypes from 'prop-types';
|
3
|
+
import { plugins } from 'hippo/components/text-editor/plugins';
|
4
|
+
import { observable, toJS } from 'mobx';
|
5
|
+
import { observer, Provider, PropTypes as MobxPropTypes } from 'mobx-react';
|
6
|
+
import { HTMLRenderer } from 'ory-editor-renderer';
|
7
|
+
|
8
|
+
import 'ory-editor-core/lib/index.css';
|
9
|
+
|
10
|
+
@observer
|
11
|
+
export default class TextEditorRenderer extends React.PureComponent {
|
12
|
+
static defaultProps = {
|
13
|
+
assets: observable.array(),
|
14
|
+
}
|
15
|
+
|
16
|
+
static propTypes = {
|
17
|
+
content: PropTypes.object.isRequired,
|
18
|
+
assets: MobxPropTypes.observableArray,
|
19
|
+
}
|
20
|
+
|
21
|
+
static defaultProps = {
|
22
|
+
className: PropTypes.string,
|
23
|
+
}
|
24
|
+
|
25
|
+
render() {
|
26
|
+
return (
|
27
|
+
<Provider
|
28
|
+
assets={this.props.assets}
|
29
|
+
>
|
30
|
+
<HTMLRenderer
|
31
|
+
className={this.props.className} state={toJS(this.props.content)}
|
32
|
+
plugins={plugins}
|
33
|
+
/>
|
34
|
+
</Provider>
|
35
|
+
);
|
36
|
+
}
|
37
|
+
}
|
@@ -0,0 +1,49 @@
|
|
1
|
+
@import 'hippo/styles/global';
|
2
|
+
|
3
|
+
.grommet .text-editor {
|
4
|
+
|
5
|
+
border: 1px solid #ddd;
|
6
|
+
flex: 1;
|
7
|
+
display: flex;
|
8
|
+
flex-direction: column;
|
9
|
+
|
10
|
+
.text-editor-content {
|
11
|
+
flex: 1;
|
12
|
+
}
|
13
|
+
|
14
|
+
|
15
|
+
.toolbar > * {
|
16
|
+
display: flex;
|
17
|
+
flex-wrap: wrap;
|
18
|
+
justify-content: center;
|
19
|
+
align-items: center;
|
20
|
+
}
|
21
|
+
|
22
|
+
p:not(.grommetux-paragraph) {
|
23
|
+
max-width: inherit;
|
24
|
+
margin-left: 0;
|
25
|
+
margin-top: 0;
|
26
|
+
margin-bottom: 0;
|
27
|
+
}
|
28
|
+
|
29
|
+
.content-image {
|
30
|
+
width: 100%;
|
31
|
+
height: auto;
|
32
|
+
}
|
33
|
+
|
34
|
+
|
35
|
+
button:not(.grommetux-button) {
|
36
|
+
min-width: inherit;
|
37
|
+
padding: 0;
|
38
|
+
border: 0;
|
39
|
+
display: flex;
|
40
|
+
justify-content: center;
|
41
|
+
align-items: center;
|
42
|
+
}
|
43
|
+
|
44
|
+
header {
|
45
|
+
.active {
|
46
|
+
border-bottom: 2px solid $focus-border-color;
|
47
|
+
}
|
48
|
+
}
|
49
|
+
}
|
@@ -1,12 +1,11 @@
|
|
1
1
|
import { observable, computed } from 'mobx';
|
2
2
|
import { titleize, humanize } from '../lib/util';
|
3
3
|
import Extensions from './index';
|
4
|
+
import RootView from '../workspace/root-view';
|
4
5
|
|
5
6
|
export { identifiedBy, identifier } from '../models/base';
|
6
7
|
|
7
|
-
|
8
8
|
export class BaseExtension {
|
9
|
-
|
10
9
|
@observable data;
|
11
10
|
|
12
11
|
static register() {
|
@@ -24,4 +23,8 @@ export class BaseExtension {
|
|
24
23
|
@computed get domain() {
|
25
24
|
return window.location.hostname.split('.').slice(-2).join('.');
|
26
25
|
}
|
26
|
+
|
27
|
+
rootView() {
|
28
|
+
return RootView;
|
29
|
+
}
|
27
30
|
}
|