goblin-laboratory 2.2.1 → 2.2.2
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.
- package/.editorconfig +9 -9
- package/.eslintrc.js +28 -28
- package/.zou-flow +3 -3
- package/README.md +107 -107
- package/carnotzet.js +10 -10
- package/config.js +13 -13
- package/laboratory.js +13 -13
- package/lib/.webpack-config.js +53 -53
- package/lib/carnotzet.js +118 -118
- package/lib/helpers.js +16 -16
- package/lib/index.js +66 -66
- package/package.json +47 -47
- package/widgets/connect-helpers/arrayEquals.js +5 -5
- package/widgets/connect-helpers/arraysEquals.js +24 -24
- package/widgets/connect-helpers/c.js +99 -99
- package/widgets/connect-helpers/join-models.js +16 -16
- package/widgets/connect-helpers/with-c.js +276 -276
- package/widgets/devtools.js +5 -5
- package/widgets/disconnect-overlay/styles.js +50 -50
- package/widgets/disconnect-overlay/widget.js +40 -40
- package/widgets/fields-view/widget.js +34 -34
- package/widgets/form/index.js +79 -79
- package/widgets/frame/widget.js +47 -47
- package/widgets/frontend-form/reducer.js +18 -18
- package/widgets/frontend-form/widget.js +15 -15
- package/widgets/importer/default.js +14 -14
- package/widgets/importer/importer.js +54 -53
- package/widgets/importer/index.js +4 -4
- package/widgets/index-browsers.js +195 -195
- package/widgets/index-electron-ws.js +153 -153
- package/widgets/index-electron.js +69 -69
- package/widgets/index.js +1 -1
- package/widgets/laboratory/service.js +542 -542
- package/widgets/laboratory/widget.js +98 -98
- package/widgets/maintenance/styles.js +38 -38
- package/widgets/maintenance/widget.js +65 -65
- package/widgets/props-binder/widget.js +48 -48
- package/widgets/renderer.js +85 -85
- package/widgets/root/index.js +54 -54
- package/widgets/searchkit/index.js +68 -68
- package/widgets/store/backend-reducer.js +116 -116
- package/widgets/store/commands-reducer.js +14 -14
- package/widgets/store/middlewares.js +171 -171
- package/widgets/store/network-reducer.js +23 -23
- package/widgets/store/root-reducer.js +35 -35
- package/widgets/store/store.js +40 -40
- package/widgets/store/widgets-reducer.js +95 -95
- package/widgets/theme-context/js-to-css.js +20 -20
- package/widgets/theme-context/widget.js +130 -130
- package/widgets/view/index.js +31 -31
- package/widgets/widget/index.js +1205 -1205
- package/widgets/widget/utils/connect.js +47 -47
- package/widgets/widget/utils/connectBackend.js +48 -48
- package/widgets/widget/utils/connectWidget.js +31 -31
- package/widgets/widget/utils/manifest.txt +134 -134
- package/widgets/widget/utils/shallowEqualShredder.js +36 -36
- package/widgets/widget/utils/widgets-actions.js +21 -21
- package/widgets/widget/utils/wrapMapStateToProps.js +26 -26
- package/widgets/with-desktop-id/widget.js +20 -20
- package/widgets/with-model/context.js +5 -5
- package/widgets/with-model/widget.js +42 -42
- package/widgets/with-workitem/widget.js +30 -30
|
@@ -1,95 +1,95 @@
|
|
|
1
|
-
import {fromJS} from 'immutable';
|
|
2
|
-
import importer from 'goblin_importer';
|
|
3
|
-
import Shredder from 'xcraft-core-shredder';
|
|
4
|
-
|
|
5
|
-
const reducerImporter = importer('reducer');
|
|
6
|
-
const wrappedReducers = {};
|
|
7
|
-
|
|
8
|
-
const actionTypePrefix = '@widgets_';
|
|
9
|
-
const findReducerNameRegex = /\$([^@]*)/;
|
|
10
|
-
|
|
11
|
-
const wrapReducer = (reducer) => (state, action) => {
|
|
12
|
-
if (state) {
|
|
13
|
-
state = new Shredder(state);
|
|
14
|
-
}
|
|
15
|
-
const nState = reducer(state, action);
|
|
16
|
-
if (Shredder.isShredder(nState)) {
|
|
17
|
-
return nState.state;
|
|
18
|
-
}
|
|
19
|
-
return nState;
|
|
20
|
-
};
|
|
21
|
-
|
|
22
|
-
function findReducerName(action) {
|
|
23
|
-
const matches = action._id.match(findReducerNameRegex);
|
|
24
|
-
if (!matches || !matches[1]) {
|
|
25
|
-
throw new Error(
|
|
26
|
-
`Unable to find a reducer name for action: ${JSON.stringify(action)}`
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
return matches[1];
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function getWrappedReducer(reducerName) {
|
|
33
|
-
let wrappedReducer = wrappedReducers[reducerName];
|
|
34
|
-
if (!wrappedReducer) {
|
|
35
|
-
const reducer = reducerImporter(reducerName);
|
|
36
|
-
if (!reducer) {
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
wrappedReducer = wrapReducer(reducer);
|
|
40
|
-
wrappedReducers[reducerName] = wrappedReducer;
|
|
41
|
-
}
|
|
42
|
-
return wrappedReducer;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function getReducerForAction(action) {
|
|
46
|
-
if (action._type) {
|
|
47
|
-
const reducer = getWrappedReducer(action._type);
|
|
48
|
-
if (reducer) {
|
|
49
|
-
return reducer;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const reducerName = findReducerName(action);
|
|
54
|
-
const reducer = getWrappedReducer(reducerName);
|
|
55
|
-
if (reducer) {
|
|
56
|
-
return reducer;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
throw new Error(
|
|
60
|
-
`No reducer named "${reducerName}" found. Action:\n${JSON.stringify(
|
|
61
|
-
action
|
|
62
|
-
)}`
|
|
63
|
-
);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
export default (state = fromJS({}), action = {}) => {
|
|
67
|
-
if (action.type === 'FIELD-CHANGED' && action.path.startsWith('widgets.')) {
|
|
68
|
-
const path = action.path.split('.').slice(1);
|
|
69
|
-
return state.setIn(path, action.value);
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (action.type === 'WIDGETS_COLLECT') {
|
|
73
|
-
action.ids.forEach((id) => {
|
|
74
|
-
state = state.delete(id);
|
|
75
|
-
});
|
|
76
|
-
return state;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
if (!action.type.startsWith(actionTypePrefix)) {
|
|
80
|
-
return state;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const wrappedReducer = getReducerForAction(action);
|
|
84
|
-
|
|
85
|
-
// Remove type prefix
|
|
86
|
-
action = {
|
|
87
|
-
...action,
|
|
88
|
-
type: action.type.substring(actionTypePrefix.length),
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
const id = action._id;
|
|
92
|
-
let _state = state.get(id, undefined);
|
|
93
|
-
_state = wrappedReducer(_state, action);
|
|
94
|
-
return state.set(id, _state);
|
|
95
|
-
};
|
|
1
|
+
import {fromJS} from 'immutable';
|
|
2
|
+
import importer from 'goblin_importer';
|
|
3
|
+
import Shredder from 'xcraft-core-shredder';
|
|
4
|
+
|
|
5
|
+
const reducerImporter = importer('reducer');
|
|
6
|
+
const wrappedReducers = {};
|
|
7
|
+
|
|
8
|
+
const actionTypePrefix = '@widgets_';
|
|
9
|
+
const findReducerNameRegex = /\$([^@]*)/;
|
|
10
|
+
|
|
11
|
+
const wrapReducer = (reducer) => (state, action) => {
|
|
12
|
+
if (state) {
|
|
13
|
+
state = new Shredder(state);
|
|
14
|
+
}
|
|
15
|
+
const nState = reducer(state, action);
|
|
16
|
+
if (Shredder.isShredder(nState)) {
|
|
17
|
+
return nState.state;
|
|
18
|
+
}
|
|
19
|
+
return nState;
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
function findReducerName(action) {
|
|
23
|
+
const matches = action._id.match(findReducerNameRegex);
|
|
24
|
+
if (!matches || !matches[1]) {
|
|
25
|
+
throw new Error(
|
|
26
|
+
`Unable to find a reducer name for action: ${JSON.stringify(action)}`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
return matches[1];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getWrappedReducer(reducerName) {
|
|
33
|
+
let wrappedReducer = wrappedReducers[reducerName];
|
|
34
|
+
if (!wrappedReducer) {
|
|
35
|
+
const reducer = reducerImporter(reducerName);
|
|
36
|
+
if (!reducer) {
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
wrappedReducer = wrapReducer(reducer);
|
|
40
|
+
wrappedReducers[reducerName] = wrappedReducer;
|
|
41
|
+
}
|
|
42
|
+
return wrappedReducer;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function getReducerForAction(action) {
|
|
46
|
+
if (action._type) {
|
|
47
|
+
const reducer = getWrappedReducer(action._type);
|
|
48
|
+
if (reducer) {
|
|
49
|
+
return reducer;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const reducerName = findReducerName(action);
|
|
54
|
+
const reducer = getWrappedReducer(reducerName);
|
|
55
|
+
if (reducer) {
|
|
56
|
+
return reducer;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
throw new Error(
|
|
60
|
+
`No reducer named "${reducerName}" found. Action:\n${JSON.stringify(
|
|
61
|
+
action
|
|
62
|
+
)}`
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export default (state = fromJS({}), action = {}) => {
|
|
67
|
+
if (action.type === 'FIELD-CHANGED' && action.path.startsWith('widgets.')) {
|
|
68
|
+
const path = action.path.split('.').slice(1);
|
|
69
|
+
return state.setIn(path, action.value);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (action.type === 'WIDGETS_COLLECT') {
|
|
73
|
+
action.ids.forEach((id) => {
|
|
74
|
+
state = state.delete(id);
|
|
75
|
+
});
|
|
76
|
+
return state;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!action.type.startsWith(actionTypePrefix)) {
|
|
80
|
+
return state;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
const wrappedReducer = getReducerForAction(action);
|
|
84
|
+
|
|
85
|
+
// Remove type prefix
|
|
86
|
+
action = {
|
|
87
|
+
...action,
|
|
88
|
+
type: action.type.substring(actionTypePrefix.length),
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const id = action._id;
|
|
92
|
+
let _state = state.get(id, undefined);
|
|
93
|
+
_state = wrappedReducer(_state, action);
|
|
94
|
+
return state.set(id, _state);
|
|
95
|
+
};
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
import toCss from 'obj-to-css';
|
|
2
|
-
import cssKey from 'css-key';
|
|
3
|
-
|
|
4
|
-
export default function jsToCSS(jsStyles) {
|
|
5
|
-
return toCss(
|
|
6
|
-
Object.assign(
|
|
7
|
-
{},
|
|
8
|
-
...Object.keys(jsStyles).map((className) => {
|
|
9
|
-
return {
|
|
10
|
-
[cssKey(className)]: Object.assign(
|
|
11
|
-
{},
|
|
12
|
-
...Object.keys(jsStyles[className]).map((key) => {
|
|
13
|
-
return {[cssKey(key)]: jsStyles[className][key]};
|
|
14
|
-
})
|
|
15
|
-
),
|
|
16
|
-
};
|
|
17
|
-
})
|
|
18
|
-
)
|
|
19
|
-
);
|
|
20
|
-
}
|
|
1
|
+
import toCss from 'obj-to-css';
|
|
2
|
+
import cssKey from 'css-key';
|
|
3
|
+
|
|
4
|
+
export default function jsToCSS(jsStyles) {
|
|
5
|
+
return toCss(
|
|
6
|
+
Object.assign(
|
|
7
|
+
{},
|
|
8
|
+
...Object.keys(jsStyles).map((className) => {
|
|
9
|
+
return {
|
|
10
|
+
[cssKey(className)]: Object.assign(
|
|
11
|
+
{},
|
|
12
|
+
...Object.keys(jsStyles[className]).map((key) => {
|
|
13
|
+
return {[cssKey(key)]: jsStyles[className][key]};
|
|
14
|
+
})
|
|
15
|
+
),
|
|
16
|
+
};
|
|
17
|
+
})
|
|
18
|
+
)
|
|
19
|
+
);
|
|
20
|
+
}
|
|
@@ -1,130 +1,130 @@
|
|
|
1
|
-
//T:2019-02-27
|
|
2
|
-
import React from 'react';
|
|
3
|
-
import Widget from 'goblin-laboratory/widgets/widget';
|
|
4
|
-
import PropTypes from 'prop-types';
|
|
5
|
-
import importer from 'goblin_importer';
|
|
6
|
-
import jsToCSS from './js-to-css.js';
|
|
7
|
-
|
|
8
|
-
const themeContextImporter = importer('theme-context');
|
|
9
|
-
|
|
10
|
-
class ThemeContext extends Widget {
|
|
11
|
-
constructor() {
|
|
12
|
-
super(...arguments);
|
|
13
|
-
this._theme = null;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
getChildContext() {
|
|
17
|
-
return {
|
|
18
|
-
theme: this._theme,
|
|
19
|
-
themeContextName: this.props.themeContext,
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
static get childContextTypes() {
|
|
24
|
-
return {
|
|
25
|
-
theme: PropTypes.object,
|
|
26
|
-
themeContextName: PropTypes.string,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
build(themeContext) {
|
|
31
|
-
let theme = this.props.theme ? this.props.theme.toJS() : null;
|
|
32
|
-
if (!theme) {
|
|
33
|
-
return null;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const themesGen = this.props.themesGen;
|
|
37
|
-
const themeGen = themesGen ? themesGen.get(this.props.currentTheme, 1) : 1;
|
|
38
|
-
theme.cacheName = `${theme.name}-${themeGen}`;
|
|
39
|
-
|
|
40
|
-
const {
|
|
41
|
-
colors = theme.colors,
|
|
42
|
-
spacing = theme.spacing,
|
|
43
|
-
timing = theme.timing,
|
|
44
|
-
look = theme.look,
|
|
45
|
-
paletteBuilder,
|
|
46
|
-
shapesBuilder,
|
|
47
|
-
stylesBuilder,
|
|
48
|
-
transitionsBuilder,
|
|
49
|
-
typoBuilder,
|
|
50
|
-
} = themeContext.builders[theme.builder];
|
|
51
|
-
|
|
52
|
-
const palette = paletteBuilder(colors);
|
|
53
|
-
const shapes = shapesBuilder(spacing, colors);
|
|
54
|
-
const transitions = transitionsBuilder(timing);
|
|
55
|
-
const typo = typoBuilder(spacing);
|
|
56
|
-
|
|
57
|
-
const styles = stylesBuilder({
|
|
58
|
-
colors: colors,
|
|
59
|
-
palette,
|
|
60
|
-
shapes,
|
|
61
|
-
spacing: spacing,
|
|
62
|
-
timing: timing,
|
|
63
|
-
transitions,
|
|
64
|
-
typo,
|
|
65
|
-
look: look,
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
return {
|
|
69
|
-
...theme,
|
|
70
|
-
styles,
|
|
71
|
-
palette,
|
|
72
|
-
shapes,
|
|
73
|
-
transitions,
|
|
74
|
-
typo,
|
|
75
|
-
};
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
render() {
|
|
79
|
-
if (!this.props.theme) {
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
const themeContext = themeContextImporter(this.props.themeContext);
|
|
83
|
-
this._theme = this.build(themeContext);
|
|
84
|
-
if (!this._theme) {
|
|
85
|
-
return null;
|
|
86
|
-
}
|
|
87
|
-
const globalStyles = themeContext.getGlobalStyles(this._theme);
|
|
88
|
-
if (this.props.frameThemeContext && globalStyles['.root']) {
|
|
89
|
-
globalStyles[`.root-${this.props.labId.replace(/@/g, '-')}`] =
|
|
90
|
-
globalStyles['.root'];
|
|
91
|
-
delete globalStyles['.root'];
|
|
92
|
-
}
|
|
93
|
-
const fonts = themeContext.getFonts(this._theme);
|
|
94
|
-
|
|
95
|
-
return (
|
|
96
|
-
// The `key` prop forces all children to be recreated when the theme changes
|
|
97
|
-
// Changing the (legacy) context is not sufficient to redraw the children
|
|
98
|
-
<React.Fragment key={this._theme.cacheName}>
|
|
99
|
-
{/* // This <style> is not necessary without shadow dom and causes errors in aphrodite after unmount and remount */}
|
|
100
|
-
{/* <style type="text/css" data-aphrodite /> */}
|
|
101
|
-
{globalStyles && (
|
|
102
|
-
<style
|
|
103
|
-
type="text/css"
|
|
104
|
-
dangerouslySetInnerHTML={{__html: jsToCSS(globalStyles)}}
|
|
105
|
-
/>
|
|
106
|
-
)}
|
|
107
|
-
{fonts && (
|
|
108
|
-
<style type="text/css" dangerouslySetInnerHTML={{__html: fonts}} />
|
|
109
|
-
)}
|
|
110
|
-
{this.props.children}
|
|
111
|
-
</React.Fragment>
|
|
112
|
-
);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
export default Widget.connect((state, props) => {
|
|
117
|
-
const {labId, themeContext, currentTheme} = props;
|
|
118
|
-
const themesGen = state.get(`backend.${labId}.themesGen`);
|
|
119
|
-
|
|
120
|
-
if (!state.has(`backend.theme-composer@${themeContext}`)) {
|
|
121
|
-
console.warn(`theme context "${themeContext}" is missing`);
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
return {
|
|
125
|
-
theme: state.get(
|
|
126
|
-
`backend.theme-composer@${themeContext}.themes.${currentTheme}`
|
|
127
|
-
),
|
|
128
|
-
themesGen,
|
|
129
|
-
};
|
|
130
|
-
})(ThemeContext);
|
|
1
|
+
//T:2019-02-27
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import Widget from 'goblin-laboratory/widgets/widget';
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
5
|
+
import importer from 'goblin_importer';
|
|
6
|
+
import jsToCSS from './js-to-css.js';
|
|
7
|
+
|
|
8
|
+
const themeContextImporter = importer('theme-context');
|
|
9
|
+
|
|
10
|
+
class ThemeContext extends Widget {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
13
|
+
this._theme = null;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
getChildContext() {
|
|
17
|
+
return {
|
|
18
|
+
theme: this._theme,
|
|
19
|
+
themeContextName: this.props.themeContext,
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
static get childContextTypes() {
|
|
24
|
+
return {
|
|
25
|
+
theme: PropTypes.object,
|
|
26
|
+
themeContextName: PropTypes.string,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
build(themeContext) {
|
|
31
|
+
let theme = this.props.theme ? this.props.theme.toJS() : null;
|
|
32
|
+
if (!theme) {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const themesGen = this.props.themesGen;
|
|
37
|
+
const themeGen = themesGen ? themesGen.get(this.props.currentTheme, 1) : 1;
|
|
38
|
+
theme.cacheName = `${theme.name}-${themeGen}`;
|
|
39
|
+
|
|
40
|
+
const {
|
|
41
|
+
colors = theme.colors,
|
|
42
|
+
spacing = theme.spacing,
|
|
43
|
+
timing = theme.timing,
|
|
44
|
+
look = theme.look,
|
|
45
|
+
paletteBuilder,
|
|
46
|
+
shapesBuilder,
|
|
47
|
+
stylesBuilder,
|
|
48
|
+
transitionsBuilder,
|
|
49
|
+
typoBuilder,
|
|
50
|
+
} = themeContext.builders[theme.builder];
|
|
51
|
+
|
|
52
|
+
const palette = paletteBuilder(colors);
|
|
53
|
+
const shapes = shapesBuilder(spacing, colors);
|
|
54
|
+
const transitions = transitionsBuilder(timing);
|
|
55
|
+
const typo = typoBuilder(spacing);
|
|
56
|
+
|
|
57
|
+
const styles = stylesBuilder({
|
|
58
|
+
colors: colors,
|
|
59
|
+
palette,
|
|
60
|
+
shapes,
|
|
61
|
+
spacing: spacing,
|
|
62
|
+
timing: timing,
|
|
63
|
+
transitions,
|
|
64
|
+
typo,
|
|
65
|
+
look: look,
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
return {
|
|
69
|
+
...theme,
|
|
70
|
+
styles,
|
|
71
|
+
palette,
|
|
72
|
+
shapes,
|
|
73
|
+
transitions,
|
|
74
|
+
typo,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
render() {
|
|
79
|
+
if (!this.props.theme) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
const themeContext = themeContextImporter(this.props.themeContext);
|
|
83
|
+
this._theme = this.build(themeContext);
|
|
84
|
+
if (!this._theme) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
const globalStyles = themeContext.getGlobalStyles(this._theme);
|
|
88
|
+
if (this.props.frameThemeContext && globalStyles['.root']) {
|
|
89
|
+
globalStyles[`.root-${this.props.labId.replace(/@/g, '-')}`] =
|
|
90
|
+
globalStyles['.root'];
|
|
91
|
+
delete globalStyles['.root'];
|
|
92
|
+
}
|
|
93
|
+
const fonts = themeContext.getFonts(this._theme);
|
|
94
|
+
|
|
95
|
+
return (
|
|
96
|
+
// The `key` prop forces all children to be recreated when the theme changes
|
|
97
|
+
// Changing the (legacy) context is not sufficient to redraw the children
|
|
98
|
+
<React.Fragment key={this._theme.cacheName}>
|
|
99
|
+
{/* // This <style> is not necessary without shadow dom and causes errors in aphrodite after unmount and remount */}
|
|
100
|
+
{/* <style type="text/css" data-aphrodite /> */}
|
|
101
|
+
{globalStyles && (
|
|
102
|
+
<style
|
|
103
|
+
type="text/css"
|
|
104
|
+
dangerouslySetInnerHTML={{__html: jsToCSS(globalStyles)}}
|
|
105
|
+
/>
|
|
106
|
+
)}
|
|
107
|
+
{fonts && (
|
|
108
|
+
<style type="text/css" dangerouslySetInnerHTML={{__html: fonts}} />
|
|
109
|
+
)}
|
|
110
|
+
{this.props.children}
|
|
111
|
+
</React.Fragment>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export default Widget.connect((state, props) => {
|
|
117
|
+
const {labId, themeContext, currentTheme} = props;
|
|
118
|
+
const themesGen = state.get(`backend.${labId}.themesGen`);
|
|
119
|
+
|
|
120
|
+
if (!state.has(`backend.theme-composer@${themeContext}`)) {
|
|
121
|
+
console.warn(`theme context "${themeContext}" is missing`);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
theme: state.get(
|
|
126
|
+
`backend.theme-composer@${themeContext}.themes.${currentTheme}`
|
|
127
|
+
),
|
|
128
|
+
themesGen,
|
|
129
|
+
};
|
|
130
|
+
})(ThemeContext);
|
package/widgets/view/index.js
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
|
-
//T:2019-02-27
|
|
2
|
-
|
|
3
|
-
import React from 'react';
|
|
4
|
-
import PropTypes from 'prop-types';
|
|
5
|
-
import Widget from 'goblin-laboratory/widgets/widget';
|
|
6
|
-
|
|
7
|
-
class View extends Widget {
|
|
8
|
-
constructor() {
|
|
9
|
-
super(...arguments);
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
getChildContext() {
|
|
13
|
-
return {
|
|
14
|
-
desktopId: this.props.desktopId,
|
|
15
|
-
contextId: this.props.context,
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
static get childContextTypes() {
|
|
20
|
-
return {
|
|
21
|
-
desktopId: PropTypes.string,
|
|
22
|
-
contextId: PropTypes.string,
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
render() {
|
|
27
|
-
return <div>Missing view render implementation</div>;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export default View;
|
|
1
|
+
//T:2019-02-27
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import PropTypes from 'prop-types';
|
|
5
|
+
import Widget from 'goblin-laboratory/widgets/widget';
|
|
6
|
+
|
|
7
|
+
class View extends Widget {
|
|
8
|
+
constructor() {
|
|
9
|
+
super(...arguments);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
getChildContext() {
|
|
13
|
+
return {
|
|
14
|
+
desktopId: this.props.desktopId,
|
|
15
|
+
contextId: this.props.context,
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
static get childContextTypes() {
|
|
20
|
+
return {
|
|
21
|
+
desktopId: PropTypes.string,
|
|
22
|
+
contextId: PropTypes.string,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
render() {
|
|
27
|
+
return <div>Missing view render implementation</div>;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export default View;
|