breezy 0.14.0 → 0.15.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/generators/rails/breezy_generator.rb +2 -4
- data/lib/generators/rails/templates/web/edit.html.erb +4 -8
- data/lib/generators/rails/templates/web/edit.jsx +1 -2
- data/lib/generators/rails/templates/web/index.html.erb +4 -7
- data/lib/generators/rails/templates/web/index.jsx +1 -2
- data/lib/generators/rails/templates/web/new.html.erb +4 -8
- data/lib/generators/rails/templates/web/new.jsx +1 -2
- data/lib/generators/rails/templates/web/show.html.erb +4 -9
- data/lib/generators/rails/templates/web/show.jsx +1 -2
- data/lib/install/templates/web/actions.js +1 -0
- data/lib/install/templates/web/application.js +164 -53
- data/lib/install/templates/web/application.json.props +2 -1
- data/lib/install/templates/web/application_visit.js +65 -0
- data/lib/install/templates/web/initializer.rb +2 -0
- data/lib/install/templates/web/reducer.js +45 -1
- data/lib/install/web.rb +4 -19
- data/test/render_test.rb +2 -0
- metadata +8 -8
- data/lib/generators/rails/templates/web/base.jsx +0 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e9400844dcf51065a2b0fd72e55f9813a9d3c0e7ad6ff947f7944db6c9e009d0
|
4
|
+
data.tar.gz: 6e0fa8b1140dec3660bfcacfcf148c91b9d0d094fbba0d0fbf4803f25a6cbf33
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9fe9fc7f8b1edb98f34112d1447d99a56bd4ce825feb4594622609bebead8e504deb3ba15c28a4de9bc8db24f7e0f7447fb04f29b391c8af4f2bbdfae36f7f9a
|
7
|
+
data.tar.gz: 16d79e3e4754bec10601b2a04200691f1e8b1379c3e14f6232796b942bfa96658f623d2f98f3515a3ce3545bd493ac7664278347fb100e875df000c71d9b42f8
|
@@ -35,8 +35,6 @@ module Rails
|
|
35
35
|
template 'web/' + filename, File.join('app/views', controller_file_path, filename)
|
36
36
|
end
|
37
37
|
|
38
|
-
template 'web/base.jsx', File.join('app/components', 'BaseScreen.jsx')
|
39
|
-
|
40
38
|
%w(index show new edit).each do |view|
|
41
39
|
append_mapping(view)
|
42
40
|
end
|
@@ -53,8 +51,8 @@ module Rails
|
|
53
51
|
"\nimport #{component_name} from 'views/#{controller_file_path}/#{action}'"
|
54
52
|
end
|
55
53
|
|
56
|
-
inject_into_file app_js, after: '
|
57
|
-
"\n
|
54
|
+
inject_into_file app_js, after: 'identifierToComponentMapping = {' do
|
55
|
+
"\n '#{[controller_file_path, action].join('/')}': #{component_name},"
|
58
56
|
end
|
59
57
|
end
|
60
58
|
|
@@ -1,11 +1,7 @@
|
|
1
1
|
<%% initial_state = controller.render_to_string(@virtual_path ,formats: [:json], locals: local_assigns, layout: true) %>
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
</script>
|
7
|
-
<%% end %>
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
<script type="text/javascript">
|
4
|
+
window.BREEZY_INITIAL_PAGE_STATE=<%%= initial_state.html_safe %>;
|
5
|
+
</script>
|
11
6
|
|
7
|
+
<div id="app"></div>
|
@@ -1,11 +1,10 @@
|
|
1
1
|
import React from 'react'
|
2
2
|
import {mapStateToProps, mapDispatchToProps} from '@jho406/breezy'
|
3
3
|
import {connect} from 'react-redux'
|
4
|
-
import BaseScreen from 'components/BaseScreen'
|
5
4
|
import RailsTag from '@jho406/breezy/dist/RailsTag'
|
6
5
|
import * as applicationActionCreators from 'javascript/packs/action_creators'
|
7
6
|
|
8
|
-
class <%= plural_table_name.camelize %>Edit extends
|
7
|
+
class <%= plural_table_name.camelize %>Edit extends React.Component {
|
9
8
|
render () {
|
10
9
|
const {
|
11
10
|
form,
|
@@ -1,10 +1,7 @@
|
|
1
1
|
<%% initial_state = controller.render_to_string(@virtual_path ,formats: [:json], locals: local_assigns, layout: true) %>
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
</script>
|
7
|
-
<%% end %>
|
8
|
-
|
9
|
-
|
3
|
+
<script type="text/javascript">
|
4
|
+
window.BREEZY_INITIAL_PAGE_STATE=<%%= initial_state.html_safe %>;
|
5
|
+
</script>
|
10
6
|
|
7
|
+
<div id="app"></div>
|
@@ -1,9 +1,8 @@
|
|
1
1
|
import React from 'react'
|
2
2
|
import {mapStateToProps, mapDispatchToProps} from '@jho406/breezy'
|
3
3
|
import { connect } from 'react-redux'
|
4
|
-
import BaseScreen from 'components/BaseScreen'
|
5
4
|
|
6
|
-
class <%= plural_table_name.camelize %>Index extends
|
5
|
+
class <%= plural_table_name.camelize %>Index extends React.Component {
|
7
6
|
static defaultProps = {
|
8
7
|
<%= plural_table_name.camelize(:lower) %>: []
|
9
8
|
}
|
@@ -1,11 +1,7 @@
|
|
1
1
|
<%% initial_state = controller.render_to_string(@virtual_path ,formats: [:json], locals: local_assigns, layout: true) %>
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
</script>
|
7
|
-
<%% end %>
|
8
|
-
|
9
|
-
|
10
|
-
|
3
|
+
<script type="text/javascript">
|
4
|
+
window.BREEZY_INITIAL_PAGE_STATE=<%%= initial_state.html_safe %>;
|
5
|
+
</script>
|
11
6
|
|
7
|
+
<div id="app"></div>
|
@@ -1,11 +1,10 @@
|
|
1
1
|
import React from 'react'
|
2
2
|
import {mapStateToProps, mapDispatchToProps} from '@jho406/breezy'
|
3
3
|
import {connect} from 'react-redux'
|
4
|
-
import BaseScreen from 'components/BaseScreen'
|
5
4
|
import RailsTag from '@jho406/breezy/dist/RailsTag'
|
6
5
|
import * as applicationActionCreators from 'javascript/packs/action_creators'
|
7
6
|
|
8
|
-
class <%= plural_table_name.camelize %>New extends
|
7
|
+
class <%= plural_table_name.camelize %>New extends React.Component {
|
9
8
|
render () {
|
10
9
|
const {
|
11
10
|
form,
|
@@ -1,12 +1,7 @@
|
|
1
1
|
<%% initial_state = controller.render_to_string(@virtual_path ,formats: [:json], locals: local_assigns, layout: true) %>
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
</script>
|
7
|
-
<%% end %>
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
3
|
+
<script type="text/javascript">
|
4
|
+
window.BREEZY_INITIAL_PAGE_STATE=<%%= initial_state.html_safe %>;
|
5
|
+
</script>
|
12
6
|
|
7
|
+
<div id="app"></div>
|
@@ -1,9 +1,8 @@
|
|
1
1
|
import React from 'react'
|
2
2
|
import {mapStateToProps, mapDispatchToProps} from '@jho406/breezy'
|
3
3
|
import { connect } from 'react-redux'
|
4
|
-
import BaseScreen from 'components/BaseScreen'
|
5
4
|
|
6
|
-
class <%= plural_table_name.camelize %>Show extends
|
5
|
+
class <%= plural_table_name.camelize %>Show extends React.Component {
|
7
6
|
render () {
|
8
7
|
return (
|
9
8
|
<div>
|
@@ -4,76 +4,187 @@ import reduceReducers from 'reduce-reducers'
|
|
4
4
|
import thunk from 'redux-thunk'
|
5
5
|
import { Provider } from 'react-redux'
|
6
6
|
import { render } from 'react-dom'
|
7
|
-
import { createBrowserHistory } from 'history'
|
8
|
-
import
|
7
|
+
import { createBrowserHistory, createMemoryHistory } from 'history'
|
8
|
+
import { start } from '@jho406/breezy'
|
9
9
|
import Nav from '@jho406/breezy/dist/NavComponent'
|
10
10
|
import ujsHandlers from '@jho406/breezy/dist/utils/ujs'
|
11
|
-
import
|
11
|
+
import { persistStore, persistReducer } from 'redux-persist'
|
12
|
+
import storage from 'redux-persist/lib/storage'
|
13
|
+
import { applicationRootReducer, applicationPagesReducer } from './reducer'
|
14
|
+
import { buildVisitAndRemote } from './application_visit'
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
const
|
16
|
-
|
16
|
+
if(typeof window !== 'undefined' ) {
|
17
|
+
document.addEventListener("DOMContentLoaded", function() {
|
18
|
+
const appEl = document.getElementById('app')
|
19
|
+
const location = window.location
|
17
20
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
+
if (appEl) {
|
22
|
+
render(
|
23
|
+
<Application
|
24
|
+
appEl={appEl}
|
25
|
+
// The base url is an optional prefix to all calls made by the `visit`
|
26
|
+
// and `remote` thunks.
|
27
|
+
baseUrl={''}
|
28
|
+
// The global var BREEZY_INITIAL_PAGE_STATE is set by your erb
|
29
|
+
// template, e.g., index.html.erb
|
30
|
+
initialPage={window.BREEZY_INITIAL_PAGE_STATE}
|
31
|
+
// The initial path of the page, e.g., /foobar
|
32
|
+
path={location.pathname + location.search + location.hash}
|
33
|
+
/>, appEl)
|
34
|
+
}
|
35
|
+
})
|
36
|
+
}
|
21
37
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
initialPage,
|
27
|
-
baseUrl,
|
28
|
-
history
|
29
|
-
})
|
38
|
+
export default class Application extends React.Component {
|
39
|
+
constructor(props) {
|
40
|
+
super(props)
|
41
|
+
this.hasWindow = typeof window !== 'undefined'
|
30
42
|
|
31
|
-
|
43
|
+
// Mapping between your props template to Component, you must add to this
|
44
|
+
// to register any new page level component you create. If you are using the
|
45
|
+
// scaffold, it will auto append the identifers for you.
|
46
|
+
//
|
47
|
+
// e.g {'posts/new': PostNew}
|
48
|
+
this.identifierToComponentMapping = {
|
49
|
+
}
|
32
50
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
} = reducer
|
51
|
+
// Create a navigator Ref for UJS attributes and to enhance the base `visit`
|
52
|
+
// and `visit` thunks
|
53
|
+
this.navigatorRef = React.createRef()
|
37
54
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
55
|
+
// Start Breezy and return an object to prepare the Redux store
|
56
|
+
const breezy = start({
|
57
|
+
initialPage: this.props.initialPage,
|
58
|
+
baseUrl: this.props.baseUrl,
|
59
|
+
path: this.props.path,
|
60
|
+
fetch: this.hasWindow ? window.fetch : undefined,
|
61
|
+
})
|
62
|
+
this.breezy = breezy
|
46
63
|
|
47
|
-
|
64
|
+
// Build the store and pass Breezy's provided reducer to be combined with
|
65
|
+
// your reducers located at `application_reducer.js`
|
66
|
+
const {initialState, reducer} = breezy
|
67
|
+
this.store = this.buildStore(initialState, reducer)
|
48
68
|
|
49
|
-
|
69
|
+
// Fire initial events and populate the store
|
70
|
+
breezy.prepareStore(this.store)
|
50
71
|
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
</Provider>
|
72
|
+
// Build visit and remote thunks
|
73
|
+
// Your modified `visit` and `remote` will get passed below to the
|
74
|
+
// NavComponent then to your components through the provided
|
75
|
+
// mapDispatchToProps.
|
76
|
+
//
|
77
|
+
// You can access them via `this.props.visit` or `this.props.remote`. In
|
78
|
+
// your page components
|
79
|
+
const {visit, remote} = buildVisitAndRemote(this.navigatorRef, this.store)
|
80
|
+
this.visit = visit
|
81
|
+
this.remote = remote
|
62
82
|
}
|
63
|
-
}
|
64
83
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
84
|
+
componentDidMount() {
|
85
|
+
const { appEl } = this.props
|
86
|
+
// Create the ujs event handlers. You can change the ujsAttributePrefix
|
87
|
+
// in the event the data attribute conflicts with another.
|
88
|
+
this.ujsHandlers = ujsHandlers({
|
89
|
+
visit: this.visit,
|
90
|
+
remote: this.remote,
|
91
|
+
store: this.store,
|
71
92
|
ujsAttributePrefix: 'data-bz'
|
72
93
|
})
|
94
|
+
const {onClick, onSubmit} = this.ujsHandlers
|
73
95
|
|
74
96
|
appEl.addEventListener('click', onClick)
|
75
97
|
appEl.addEventListener('submit', onSubmit)
|
98
|
+
}
|
99
|
+
|
100
|
+
componentWillUnmount() {
|
101
|
+
const { appEl } = this.props
|
102
|
+
const {onClick, onSubmit} = this.ujsHandlers
|
103
|
+
|
104
|
+
appEl.removeEventListener('click', onClick)
|
105
|
+
appEl.removeEventListener('submit', onSubmit)
|
106
|
+
this.breezy.stop()
|
107
|
+
}
|
108
|
+
|
109
|
+
buildStore(initialState, {breezy: breezyReducer, pages: pagesReducer}) {
|
110
|
+
// Create the store
|
111
|
+
// See `./reducer.js` for an explaination of the two included reducers
|
112
|
+
const composeEnhancers = (this.hasWindow && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) || compose;
|
113
|
+
const reducer = this.wrapWithPersistReducer(
|
114
|
+
reduceReducers(
|
115
|
+
combineReducers({
|
116
|
+
breezy: breezyReducer,
|
117
|
+
pages: reduceReducers(pagesReducer, applicationPagesReducer),
|
118
|
+
}),
|
119
|
+
applicationRootReducer
|
120
|
+
)
|
121
|
+
)
|
122
|
+
const store = createStore(
|
123
|
+
reducer,
|
124
|
+
initialState,
|
125
|
+
composeEnhancers(applyMiddleware(thunk))
|
126
|
+
)
|
127
|
+
|
128
|
+
if(this.hasWindow) {
|
129
|
+
// Persist the store using Redux-Persist
|
130
|
+
persistStore(store)
|
131
|
+
}
|
76
132
|
|
77
|
-
|
133
|
+
return store
|
78
134
|
}
|
79
|
-
|
135
|
+
|
136
|
+
wrapWithPersistReducer(reducers) {
|
137
|
+
// Redux Persist settings
|
138
|
+
// The key is set to the stringified JS asset path to remove the need for
|
139
|
+
// migrations when hydrating.
|
140
|
+
if (!this.hasWindow) {
|
141
|
+
return reducers
|
142
|
+
}
|
143
|
+
const prefix = 'breezy'
|
144
|
+
const persistKey = prefix + this.props.initialPage.assets.filter( asset => asset.endsWith('.js')).join(",")
|
145
|
+
const persistConfig = {
|
146
|
+
key: persistKey,
|
147
|
+
storage,
|
148
|
+
}
|
149
|
+
|
150
|
+
// Remove older storage items that were used by previous JS assets
|
151
|
+
if (this.hasWindow) {
|
152
|
+
const storedKeys = Object.keys(localStorage)
|
153
|
+
storedKeys.forEach((key) => {
|
154
|
+
if (key.startsWith(`persist:${prefix}`) && key !== persistKey) {
|
155
|
+
localStorage.removeItem(key)
|
156
|
+
}
|
157
|
+
})
|
158
|
+
}
|
159
|
+
|
160
|
+
return persistReducer(persistConfig, reducers)
|
161
|
+
}
|
162
|
+
|
163
|
+
createHistory() {
|
164
|
+
if(this.hasWindow) {
|
165
|
+
// This is used for client side rendering
|
166
|
+
return createBrowserHistory({})
|
167
|
+
} else {
|
168
|
+
// This is used for server side rendering
|
169
|
+
return createMemoryHistory({})
|
170
|
+
}
|
171
|
+
}
|
172
|
+
|
173
|
+
render() {
|
174
|
+
const history = this.createHistory()
|
175
|
+
|
176
|
+
// The Nav component is pretty bare and can be inherited from for custom
|
177
|
+
// behavior or replaced with your own.
|
178
|
+
return <Provider store={this.store}>
|
179
|
+
<Nav
|
180
|
+
store={this.store}
|
181
|
+
ref={this.navigatorRef}
|
182
|
+
visit={this.visit}
|
183
|
+
remote={this.remote}
|
184
|
+
mapping={this.identifierToComponentMapping}
|
185
|
+
history={history}
|
186
|
+
initialPageKey={this.breezy.initialPageKey}
|
187
|
+
/>
|
188
|
+
</Provider>
|
189
|
+
}
|
190
|
+
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
path = param_to_search_path(params[:bzq])
|
1
|
+
path = request.format.json? ? param_to_search_path(params[:bzq]) : nil
|
2
2
|
|
3
3
|
json.data(search: path) do
|
4
4
|
yield json
|
@@ -21,5 +21,6 @@ if path
|
|
21
21
|
json.path search_path_to_camelized_param(path)
|
22
22
|
end
|
23
23
|
|
24
|
+
json.rendered_at Time.now.to_i
|
24
25
|
json.flash flash.to_h
|
25
26
|
|
@@ -0,0 +1,65 @@
|
|
1
|
+
import { visit, remote } from '@jho406/breezy/dist/action_creators'
|
2
|
+
|
3
|
+
export function buildVisitAndRemote(ref, store) {
|
4
|
+
const appRemote = (...args) => {
|
5
|
+
return store.dispatch(remote(...args))
|
6
|
+
}
|
7
|
+
|
8
|
+
const appVisit = (...args) => {
|
9
|
+
// Do something before
|
10
|
+
// e.g, show loading state, you can access the current pageKey
|
11
|
+
// via store.getState().breezy.currentPageKey
|
12
|
+
return store
|
13
|
+
.dispatch(visit(...args))
|
14
|
+
.then((meta) => {
|
15
|
+
// The assets fingerprints changed, instead of transitioning
|
16
|
+
// just go to the URL directly to retrieve new assets
|
17
|
+
if (meta.needsRefresh) {
|
18
|
+
window.location = meta.url
|
19
|
+
return
|
20
|
+
}
|
21
|
+
|
22
|
+
// There can only be one visit at a time, if `canNavigate` is false,
|
23
|
+
// then this request will be saved to the store but should be ignored
|
24
|
+
// for a more recent visit.
|
25
|
+
if (meta.canNavigate) {
|
26
|
+
ref.current.navigateTo(meta.pageKey, {
|
27
|
+
action: meta.suggestedAction,
|
28
|
+
})
|
29
|
+
}
|
30
|
+
})
|
31
|
+
.finally(() => {
|
32
|
+
// Do something after
|
33
|
+
// e.g, hide loading state, you can access the changed pageKey
|
34
|
+
// via getState().breezy.currentPageKey
|
35
|
+
})
|
36
|
+
.catch((err) => {
|
37
|
+
const response = err.response
|
38
|
+
|
39
|
+
if (!response) {
|
40
|
+
console.error(err)
|
41
|
+
return
|
42
|
+
}
|
43
|
+
|
44
|
+
if (response.ok) {
|
45
|
+
// err gets thrown, but if the response is ok,
|
46
|
+
// it must be an html body that
|
47
|
+
// breezy can't parse, just go to the location
|
48
|
+
window.location = response.url
|
49
|
+
} else {
|
50
|
+
if (response.status >= 400 && response.status < 500) {
|
51
|
+
window.location = '/400.html'
|
52
|
+
return
|
53
|
+
}
|
54
|
+
|
55
|
+
if (response.status >= 500) {
|
56
|
+
window.location = '/500.html'
|
57
|
+
return
|
58
|
+
}
|
59
|
+
}
|
60
|
+
})
|
61
|
+
}
|
62
|
+
|
63
|
+
return { visit: appVisit, remote: appRemote }
|
64
|
+
}
|
65
|
+
|
@@ -20,8 +20,52 @@
|
|
20
20
|
// }
|
21
21
|
// }
|
22
22
|
|
23
|
-
|
23
|
+
import {
|
24
|
+
REHYDRATE,
|
25
|
+
} from './actions'
|
26
|
+
|
27
|
+
// The applicationPageReducer is for cross page reducers
|
28
|
+
// Its common to add to this. You'll typically have to pass a pageKey to the
|
29
|
+
// action payload to distinguish the current page
|
30
|
+
//
|
31
|
+
// The pageKey is passed through the props in your component. Access it like
|
32
|
+
// this: `this.props.pageKey` then dispatch it in an action
|
33
|
+
export const applicationPagesReducer = (state = {}, action) => {
|
34
|
+
switch(action.type) {
|
35
|
+
default:
|
36
|
+
return state
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
// The applicationRootReducer is for app wide reducers
|
41
|
+
// Its rare to be adding to this. Included out of the box ix a reducer for
|
42
|
+
// Redux Persist.
|
43
|
+
//
|
44
|
+
// The REHYDRATE reducer is generated by Breezy and is needed to persist state
|
45
|
+
// on any changes made to the initial state that gets injected into
|
46
|
+
// window.BREEZY_INITIAL_PAGE_STATE.
|
47
|
+
export const applicationRootReducer = (state = {}, action) => {
|
24
48
|
switch(action.type) {
|
49
|
+
case REHYDRATE: {
|
50
|
+
if (action.payload) {
|
51
|
+
const {
|
52
|
+
pages: hydratedPages
|
53
|
+
} = action.payload
|
54
|
+
const { pages } = state
|
55
|
+
const nextPages = { ...pages, ...hydratedPages }
|
56
|
+
|
57
|
+
for (const key in pages) {
|
58
|
+
if (pages[key] && hydratedPages[key] &&
|
59
|
+
pages[key].renderedAt > hydratedPages[key].renderedAt) {
|
60
|
+
nextPages[key] = { ...pages[key] }
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
return { ...state, pages: nextPages }
|
65
|
+
} else {
|
66
|
+
return state
|
67
|
+
}
|
68
|
+
}
|
25
69
|
default:
|
26
70
|
return state
|
27
71
|
}
|
data/lib/install/web.rb
CHANGED
@@ -2,21 +2,6 @@ require "webpacker/configuration"
|
|
2
2
|
|
3
3
|
babel_config = Rails.root.join("babel.config.js")
|
4
4
|
|
5
|
-
def append_js_tags
|
6
|
-
app_html = 'app/views/layouts/application.html.erb'
|
7
|
-
js_tag = <<-JS_TAG
|
8
|
-
<%= yield :initial_state %>
|
9
|
-
JS_TAG
|
10
|
-
|
11
|
-
inject_into_file app_html, after: '<head>' do
|
12
|
-
js_tag
|
13
|
-
end
|
14
|
-
|
15
|
-
inject_into_file app_html, after: '<body>' do
|
16
|
-
"\n <div id='app'></div>"
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
5
|
def add_member_methods
|
21
6
|
inject_into_file "app/models/application_record.rb", after: "class ApplicationRecord < ActiveRecord::Base\n" do
|
22
7
|
<<-RUBY
|
@@ -58,20 +43,20 @@ copy_file "#{__dir__}/templates/web/action_creators.js", "#{Webpacker.config.sou
|
|
58
43
|
say "Copying actions.js file to #{Webpacker.config.source_entry_path}"
|
59
44
|
copy_file "#{__dir__}/templates/web/actions.js", "#{Webpacker.config.source_entry_path}/actions.js"
|
60
45
|
|
46
|
+
say "Copying application_visit.js file to #{Webpacker.config.source_entry_path}"
|
47
|
+
copy_file "#{__dir__}/templates/web/application_visit.js", "#{Webpacker.config.source_entry_path}/application_visit.js"
|
48
|
+
|
61
49
|
say "Copying Breezy initializer"
|
62
50
|
copy_file "#{__dir__}/templates/web/initializer.rb", "config/initializers/breezy.rb"
|
63
51
|
|
64
52
|
say "Copying application.json.props"
|
65
53
|
copy_file "#{__dir__}/templates/web/application.json.props", "app/views/layouts/application.json.props"
|
66
54
|
|
67
|
-
say "Appending js tags to your application.html.erb"
|
68
|
-
append_js_tags
|
69
|
-
|
70
55
|
say "Adding required member methods to ApplicationRecord"
|
71
56
|
add_member_methods
|
72
57
|
|
73
58
|
say "Installing React, Redux, and Breezy"
|
74
|
-
run "yarn add babel-plugin-module-resolver babel-preset-react history prop-types react-redux redux-thunk redux reduce-reducers react react-dom immer @jho406/breezy --save"
|
59
|
+
run "yarn add babel-plugin-module-resolver babel-preset-react history@\"^4\" html-react-parser@\"^0.13\" prop-types react-redux redux-thunk redux redux-persist reduce-reducers react react-dom immer @jho406/breezy --save"
|
75
60
|
|
76
61
|
say "Updating webpack config to include .jsx file extension and resolved_paths"
|
77
62
|
insert_into_file Webpacker.config.config_path, " - .jsx\n", after: /extensions:\n/
|
data/test/render_test.rb
CHANGED
@@ -44,6 +44,8 @@ class RenderTest < ActionController::TestCase
|
|
44
44
|
|
45
45
|
|
46
46
|
setup do
|
47
|
+
Props.reset_encoder!
|
48
|
+
|
47
49
|
if Rails.version >= '6'
|
48
50
|
# In rails 6, the fixture orders the templates based on their appearance in the handler
|
49
51
|
# This doesn't happen IRL, so I'm going to explicitly set the handler here.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: breezy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.15.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Johny Ho
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.15.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 0.
|
40
|
+
version: 0.15.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: webpacker
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -170,7 +170,6 @@ files:
|
|
170
170
|
- lib/generators/rails/templates/index.json.props
|
171
171
|
- lib/generators/rails/templates/new.json.props
|
172
172
|
- lib/generators/rails/templates/show.json.props
|
173
|
-
- lib/generators/rails/templates/web/base.jsx
|
174
173
|
- lib/generators/rails/templates/web/edit.html.erb
|
175
174
|
- lib/generators/rails/templates/web/edit.jsx
|
176
175
|
- lib/generators/rails/templates/web/index.html.erb
|
@@ -183,6 +182,7 @@ files:
|
|
183
182
|
- lib/install/templates/web/actions.js
|
184
183
|
- lib/install/templates/web/application.js
|
185
184
|
- lib/install/templates/web/application.json.props
|
185
|
+
- lib/install/templates/web/application_visit.js
|
186
186
|
- lib/install/templates/web/initializer.rb
|
187
187
|
- lib/install/templates/web/reducer.js
|
188
188
|
- lib/install/web.rb
|
@@ -195,7 +195,7 @@ homepage: https://github.com/jho406/breezy/
|
|
195
195
|
licenses:
|
196
196
|
- MIT
|
197
197
|
metadata: {}
|
198
|
-
post_install_message:
|
198
|
+
post_install_message:
|
199
199
|
rdoc_options: []
|
200
200
|
require_paths:
|
201
201
|
- lib
|
@@ -211,7 +211,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
211
211
|
version: '0'
|
212
212
|
requirements: []
|
213
213
|
rubygems_version: 3.0.3
|
214
|
-
signing_key:
|
214
|
+
signing_key:
|
215
215
|
specification_version: 4
|
216
216
|
summary: Rails integration for BreezyJS
|
217
217
|
test_files:
|
@@ -1,11 +0,0 @@
|
|
1
|
-
import React from 'react'
|
2
|
-
import {enhanceVisitWithBrowserBehavior} from '@jho406/breezy'
|
3
|
-
|
4
|
-
export default class extends React.Component {
|
5
|
-
constructor (props) {
|
6
|
-
super(props)
|
7
|
-
const visit = enhanceVisitWithBrowserBehavior(props.visit)
|
8
|
-
this.enhancedVisit = visit.bind(this)
|
9
|
-
}
|
10
|
-
}
|
11
|
-
|