breezy 0.14.0 → 0.18.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 +26 -36
- data/lib/generators/rails/templates/web/index.html.erb +4 -7
- data/lib/generators/rails/templates/web/index.jsx +43 -54
- data/lib/generators/rails/templates/web/new.html.erb +4 -8
- data/lib/generators/rails/templates/web/new.jsx +24 -33
- data/lib/generators/rails/templates/web/show.html.erb +4 -9
- data/lib/generators/rails/templates/web/show.jsx +25 -25
- data/lib/install/templates/web/actions.js +1 -0
- data/lib/install/templates/web/application.js +99 -64
- data/lib/install/templates/web/application.json.props +2 -1
- data/lib/install/templates/web/application_visit.js +60 -0
- data/lib/install/templates/web/reducer.js +45 -1
- data/lib/install/web.rb +8 -20
- data/lib/tasks/install.rake +1 -1
- metadata +11 -11
- 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: 5c5e2d6ff06a62de207f2b867d1e64044b66816d5abbad514ea00a321bd01e04
|
4
|
+
data.tar.gz: e0b800f96939f33d719212de311eb8d692b5d8e7122a0a3cf424572239358a77
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d4d58896fa261c4aeb545dc749624643d270645753a952ac56ff71d6dd66f8eada37ec9e426816eeda6a69d8021348b83049732bb77c36b5c4242aa884d42849
|
7
|
+
data.tar.gz: f1631849823a71fc7211f432f4a514e38e82f31df7a24da6c567c0e461dc957e221a40ff939efde7ef5dd063df1d783b4cd7845ae045e8dbcff24f10ee11730b
|
@@ -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,41 +1,31 @@
|
|
1
1
|
import React from 'react'
|
2
|
-
import
|
3
|
-
import
|
4
|
-
import
|
5
|
-
import RailsTag from '@jho406/breezy/dist/RailsTag'
|
6
|
-
import * as applicationActionCreators from 'javascript/packs/action_creators'
|
2
|
+
import RailsTag from '@jho406/breezy/components/RailsTag'
|
3
|
+
// import * as actionCreators from 'javascript/packs/action_creators'
|
4
|
+
// import {useDispatch} from 'react-redux'
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
6
|
+
export default function <%= plural_table_name.camelize %>Edit ({
|
7
|
+
// visit,
|
8
|
+
// remote,
|
9
|
+
form,
|
10
|
+
flash,
|
11
|
+
<%= singular_table_name.camelize(:lower) %>Path,
|
12
|
+
<%= plural_table_name.camelize(:lower) %>Path,
|
13
|
+
}) {
|
14
|
+
const error = flash.form_error
|
17
15
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
16
|
+
const messagesEl = error && (
|
17
|
+
<div id="error_explanation">
|
18
|
+
<h2>{ error.explanation }</h2>
|
19
|
+
<ul>{ error.messages.map(({body})=> <li key={body}>{body}</li>) }</ul>
|
20
|
+
</div>
|
21
|
+
)
|
24
22
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
}
|
23
|
+
return (
|
24
|
+
<div>
|
25
|
+
{messagesEl}
|
26
|
+
<RailsTag {...form} data-bz-visit={true}/>
|
27
|
+
<a href={<%= singular_table_name.camelize(:lower) %>Path} data-bz-visit={true}>Show</a>
|
28
|
+
<a href={<%= plural_table_name.camelize(:lower) %>Path} data-bz-visit={true}>Back</a>
|
29
|
+
</div>
|
30
|
+
)
|
34
31
|
}
|
35
|
-
|
36
|
-
export default connect(
|
37
|
-
mapStateToProps,
|
38
|
-
{...mapDispatchToProps, ...applicationActionCreators}
|
39
|
-
)(<%= plural_table_name.camelize %>Edit)
|
40
|
-
|
41
|
-
|
@@ -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,60 +1,49 @@
|
|
1
1
|
import React from 'react'
|
2
|
-
import
|
3
|
-
import {
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
flash,
|
14
|
-
new<%= singular_table_name.camelize %>Path,
|
15
|
-
} = this.props
|
16
|
-
const <%= singular_table_name.camelize(:lower) %>Items = this.props.<%= plural_table_name.camelize(:lower) %>.map((<%= singular_table_name.camelize(:lower) %>, key) => {
|
17
|
-
return (
|
18
|
-
<tr key={<%= singular_table_name.camelize(:lower) %>.id}>
|
19
|
-
<%- attributes_list.select{|attr| attr != :id }.each do |attr| -%>
|
20
|
-
<td>{<%=singular_table_name.camelize(:lower)%>.<%=attr.camelize(:lower)%>}</td>
|
21
|
-
<%- end -%>
|
22
|
-
<td><a href={ <%=singular_table_name%>.<%=singular_table_name.camelize(:lower)%>Path } data-bz-visit={true}>Show</a></td>
|
23
|
-
<td><a href={ <%=singular_table_name%>.edit<%=singular_table_name.camelize%>Path } data-bz-visit={true}>Edit</a></td>
|
24
|
-
<td><a href={ <%=singular_table_name%>.delete<%=singular_table_name.camelize%>Path }data-bz-visit={true} data-bz-method={"DELETE"}>Delete</a></td>
|
25
|
-
</tr>
|
26
|
-
)
|
27
|
-
})
|
28
|
-
|
2
|
+
// import * as actionCreators from 'javascript/packs/action_creators'
|
3
|
+
// import {useDispatch} from 'react-redux'
|
4
|
+
|
5
|
+
export default function <%= plural_table_name.camelize %>Index({
|
6
|
+
// visit,
|
7
|
+
// remote,
|
8
|
+
flash,
|
9
|
+
new<%= singular_table_name.camelize %>Path,
|
10
|
+
<%= plural_table_name.camelize(:lower) %> = [],
|
11
|
+
}) {
|
12
|
+
const <%= singular_table_name.camelize(:lower) %>Items = <%= plural_table_name.camelize(:lower) %>.map((<%= singular_table_name.camelize(:lower) %>, key) => {
|
29
13
|
return (
|
30
|
-
<
|
31
|
-
|
14
|
+
<tr key={<%= singular_table_name.camelize(:lower) %>.id}>
|
15
|
+
<%- attributes_list.select{|attr| attr != :id }.each do |attr| -%>
|
16
|
+
<td>{<%=singular_table_name.camelize(:lower)%>.<%=attr.camelize(:lower)%>}</td>
|
17
|
+
<%- end -%>
|
18
|
+
<td><a href={ <%=singular_table_name%>.<%=singular_table_name.camelize(:lower)%>Path } data-bz-visit={true}>Show</a></td>
|
19
|
+
<td><a href={ <%=singular_table_name%>.edit<%=singular_table_name.camelize%>Path } data-bz-visit={true}>Edit</a></td>
|
20
|
+
<td><a href={ <%=singular_table_name%>.delete<%=singular_table_name.camelize%>Path }data-bz-visit={true} data-bz-method={"DELETE"}>Delete</a></td>
|
21
|
+
</tr>
|
22
|
+
)
|
23
|
+
})
|
32
24
|
|
33
|
-
|
25
|
+
return (
|
26
|
+
<div>
|
27
|
+
<p id="notice">{flash.notice}</p>
|
34
28
|
|
35
|
-
|
36
|
-
<thead>
|
37
|
-
<%- attributes_list.select{|attr| attr != :id }.each do |attr| -%>
|
38
|
-
<tr><th><%=attr.capitalize%></th></tr>
|
39
|
-
<%- end -%>
|
40
|
-
<tr>
|
41
|
-
<th colSpan="3"></th>
|
42
|
-
</tr>
|
43
|
-
</thead>
|
29
|
+
<h1><%= plural_table_name.capitalize %></h1>
|
44
30
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
31
|
+
<table>
|
32
|
+
<thead>
|
33
|
+
<%- attributes_list.select{|attr| attr != :id }.each do |attr| -%>
|
34
|
+
<tr><th><%=attr.capitalize%></th></tr>
|
35
|
+
<%- end -%>
|
36
|
+
<tr>
|
37
|
+
<th colSpan="3"></th>
|
38
|
+
</tr>
|
39
|
+
</thead>
|
40
|
+
|
41
|
+
<tbody>
|
42
|
+
{<%= singular_table_name %>Items}
|
43
|
+
</tbody>
|
44
|
+
</table>
|
45
|
+
<br />
|
46
|
+
<a href={new<%= singular_table_name.camelize %>Path} data-bz-visit={true}>New <%= singular_table_name.capitalize %></a>
|
47
|
+
</div>
|
48
|
+
)
|
54
49
|
}
|
55
|
-
|
56
|
-
export default connect(
|
57
|
-
mapStateToProps,
|
58
|
-
mapDispatchToProps
|
59
|
-
)(<%= plural_table_name.camelize %>Index)
|
60
|
-
|
@@ -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,38 +1,29 @@
|
|
1
1
|
import React from 'react'
|
2
|
-
import
|
3
|
-
import
|
4
|
-
import
|
5
|
-
import RailsTag from '@jho406/breezy/dist/RailsTag'
|
6
|
-
import * as applicationActionCreators from 'javascript/packs/action_creators'
|
2
|
+
import RailsTag from '@jho406/breezy/components/RailsTag'
|
3
|
+
// import * as actionCreators from 'javascript/packs/action_creators'
|
4
|
+
// import { useDispatch } from 'react-redux'
|
7
5
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
6
|
+
export default function <%= plural_table_name.camelize %>New({
|
7
|
+
// visit,
|
8
|
+
// remote
|
9
|
+
form,
|
10
|
+
flash,
|
11
|
+
<%= plural_table_name.camelize(:lower) %>Path,
|
12
|
+
}) {
|
13
|
+
const error = flash.form_error
|
16
14
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
15
|
+
const messagesEl = error && (
|
16
|
+
<div id="error_explanation">
|
17
|
+
<h2>{ error.explanation }</h2>
|
18
|
+
<ul>{ error.messages.map(({body})=> <li key={body}>{body}</li>) }</ul>
|
19
|
+
</div>
|
20
|
+
)
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
}
|
22
|
+
return (
|
23
|
+
<div>
|
24
|
+
{messagesEl}
|
25
|
+
<RailsTag {...form} data-bz-visit={true}/>
|
26
|
+
<a href={<%= plural_table_name.camelize(:lower) %>Path} data-bz-visit={true}>Back</a>
|
27
|
+
</div>
|
28
|
+
)
|
32
29
|
}
|
33
|
-
|
34
|
-
export default connect(
|
35
|
-
mapStateToProps,
|
36
|
-
{...mapDispatchToProps, ...applicationActionCreators}
|
37
|
-
)(<%= plural_table_name.camelize %>New)
|
38
|
-
|
@@ -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,28 +1,28 @@
|
|
1
1
|
import React from 'react'
|
2
|
-
import
|
3
|
-
import {
|
4
|
-
import BaseScreen from 'components/BaseScreen'
|
2
|
+
// import * as actionCreators from 'javascript/packs/action_creators'
|
3
|
+
// import {useDispatch} from 'react-redux'
|
5
4
|
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
5
|
+
export default function <%= plural_table_name.camelize %>Show({
|
6
|
+
// visit,
|
7
|
+
// remote,
|
8
|
+
flash,
|
9
|
+
<%- attributes_list_with_timestamps.select{|attr| attr != :id }.each do |attr| -%>
|
10
|
+
<%=attr.camelize(:lower)%>,
|
11
|
+
<%- end -%>
|
12
|
+
edit<%= singular_table_name.camelize %>Path,
|
13
|
+
<%= plural_table_name.camelize(:lower) %>Path
|
14
|
+
}) {
|
15
|
+
return (
|
16
|
+
<div>
|
17
|
+
<p id="notice">{flash && flash.notice}</p>
|
18
|
+
<%- attributes_list_with_timestamps.select{|attr| attr != :id }.each do |attr| -%>
|
19
|
+
<p>
|
20
|
+
<strong><%= attr.capitalize %>:</strong>
|
21
|
+
{<%=attr.camelize(:lower)%>}
|
22
|
+
</p>
|
23
|
+
<%- end -%>
|
24
|
+
<a href={ edit<%= singular_table_name.camelize %>Path } data-bz-visit={true}>Edit</a>
|
25
|
+
<a href={ <%= plural_table_name.camelize(:lower) %>Path } data-bz-visit={true}>Back</a>
|
26
|
+
</div>
|
27
|
+
)
|
22
28
|
}
|
23
|
-
|
24
|
-
export default connect(
|
25
|
-
mapStateToProps,
|
26
|
-
mapDispatchToProps
|
27
|
-
)(<%= plural_table_name.camelize %>Show)
|
28
|
-
|
@@ -1,79 +1,114 @@
|
|
1
|
-
import React from 'react'
|
2
|
-
import {combineReducers, createStore, applyMiddleware, compose} from 'redux'
|
3
|
-
import reduceReducers from 'reduce-reducers'
|
4
|
-
import thunk from 'redux-thunk'
|
5
|
-
import { Provider } from 'react-redux'
|
6
|
-
import { render } from 'react-dom'
|
7
|
-
import {
|
8
|
-
import
|
9
|
-
import
|
10
|
-
import
|
11
|
-
import
|
1
|
+
import React from 'react';
|
2
|
+
import { combineReducers, createStore, applyMiddleware, compose } from 'redux';
|
3
|
+
import reduceReducers from 'reduce-reducers';
|
4
|
+
import thunk from 'redux-thunk';
|
5
|
+
import { Provider } from 'react-redux';
|
6
|
+
import { render } from 'react-dom';
|
7
|
+
import { ApplicationBase } from '@jho406/breezy';
|
8
|
+
import { persistStore, persistReducer } from 'redux-persist';
|
9
|
+
import storage from 'redux-persist/lib/storage';
|
10
|
+
import { applicationRootReducer, applicationPagesReducer } from './reducer';
|
11
|
+
import { buildVisitAndRemote } from './application_visit';
|
12
12
|
|
13
|
-
// Mapping between your props template to Component
|
13
|
+
// Mapping between your props template to Component, you must add to this
|
14
|
+
// to register any new page level component you create. If you are using the
|
15
|
+
// scaffold, it will auto append the identifers for you.
|
16
|
+
//
|
14
17
|
// e.g {'posts/new': PostNew}
|
15
18
|
const identifierToComponentMapping = {
|
16
|
-
}
|
17
|
-
|
18
|
-
const history = createBrowserHistory({})
|
19
|
-
const initialPage = window.BREEZY_INITIAL_PAGE_STATE
|
20
|
-
const baseUrl = ''
|
19
|
+
};
|
21
20
|
|
22
|
-
|
23
|
-
|
24
|
-
const
|
25
|
-
|
26
|
-
initialPage,
|
27
|
-
baseUrl,
|
28
|
-
history
|
29
|
-
})
|
21
|
+
if (typeof window !== "undefined") {
|
22
|
+
document.addEventListener("DOMContentLoaded", function () {
|
23
|
+
const appEl = document.getElementById("app");
|
24
|
+
const location = window.location;
|
30
25
|
|
31
|
-
|
26
|
+
if (appEl) {
|
27
|
+
render(
|
28
|
+
<Application
|
29
|
+
appEl={appEl}
|
30
|
+
// The base url prefixed to all calls made by the `visit`
|
31
|
+
// and `remote` thunks.
|
32
|
+
baseUrl={location.origin}
|
33
|
+
// The global var BREEZY_INITIAL_PAGE_STATE is set by your erb
|
34
|
+
// template, e.g., index.html.erb
|
35
|
+
initialPage={window.BREEZY_INITIAL_PAGE_STATE}
|
36
|
+
// The initial path of the page, e.g., /foobar
|
37
|
+
path={location.pathname + location.search + location.hash}
|
38
|
+
buildVisitAndRemote={buildVisitAndRemote}
|
39
|
+
/>,
|
40
|
+
appEl
|
41
|
+
);
|
42
|
+
}
|
43
|
+
});
|
44
|
+
}
|
32
45
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
}
|
46
|
+
export default class Application extends ApplicationBase {
|
47
|
+
mapping() {
|
48
|
+
return identifierToComponentMapping;
|
49
|
+
}
|
37
50
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
pages: reduceReducers(pagesReducer, applicationReducer),
|
42
|
-
}),
|
43
|
-
initialState,
|
44
|
-
composeEnhancers(applyMiddleware(thunk))
|
45
|
-
)
|
51
|
+
visitAndRemote(navRef, store) {
|
52
|
+
return buildVisitAndRemote(navRef, store);
|
53
|
+
}
|
46
54
|
|
47
|
-
|
55
|
+
buildStore(initialState, { breezy: breezyReducer, pages: pagesReducer }) {
|
56
|
+
// Create the store
|
57
|
+
// See `./reducer.js` for an explaination of the two included reducers
|
58
|
+
const composeEnhancers =
|
59
|
+
(this.hasWindow && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||
|
60
|
+
compose;
|
61
|
+
const reducer = this.wrapWithPersistReducer(
|
62
|
+
reduceReducers(
|
63
|
+
combineReducers({
|
64
|
+
breezy: breezyReducer,
|
65
|
+
pages: reduceReducers(pagesReducer, applicationPagesReducer),
|
66
|
+
}),
|
67
|
+
applicationRootReducer
|
68
|
+
)
|
69
|
+
);
|
70
|
+
const store = createStore(
|
71
|
+
reducer,
|
72
|
+
initialState,
|
73
|
+
composeEnhancers(applyMiddleware(thunk))
|
74
|
+
);
|
48
75
|
|
49
|
-
|
76
|
+
if (this.hasWindow) {
|
77
|
+
// Persist the store using Redux-Persist
|
78
|
+
persistStore(store);
|
79
|
+
}
|
50
80
|
|
51
|
-
|
52
|
-
render() {
|
53
|
-
return <Provider store={store}>
|
54
|
-
<Nav
|
55
|
-
store={store}
|
56
|
-
ref={navigatorRef}
|
57
|
-
mapping={this.props.mapping}
|
58
|
-
history={history}
|
59
|
-
initialPageKey={initialPageKey}
|
60
|
-
/>
|
61
|
-
</Provider>
|
81
|
+
return store;
|
62
82
|
}
|
63
|
-
}
|
64
83
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
84
|
+
wrapWithPersistReducer(reducers) {
|
85
|
+
// Redux Persist settings
|
86
|
+
// The key is set to the stringified JS asset path to remove the need for
|
87
|
+
// migrations when hydrating.
|
88
|
+
if (!this.hasWindow) {
|
89
|
+
return reducers;
|
90
|
+
}
|
91
|
+
const prefix = "breezy";
|
92
|
+
const persistKey =
|
93
|
+
prefix +
|
94
|
+
this.props.initialPage.assets
|
95
|
+
.filter((asset) => asset.endsWith(".js"))
|
96
|
+
.join(",");
|
97
|
+
const persistConfig = {
|
98
|
+
key: persistKey,
|
99
|
+
storage,
|
100
|
+
};
|
73
101
|
|
74
|
-
|
75
|
-
|
102
|
+
// Remove older storage items that were used by previous JS assets
|
103
|
+
if (this.hasWindow) {
|
104
|
+
const storedKeys = Object.keys(localStorage);
|
105
|
+
storedKeys.forEach((key) => {
|
106
|
+
if (key.startsWith(`persist:${prefix}`) && key !== persistKey) {
|
107
|
+
localStorage.removeItem(key);
|
108
|
+
}
|
109
|
+
});
|
110
|
+
}
|
76
111
|
|
77
|
-
|
112
|
+
return persistReducer(persistConfig, reducers);
|
78
113
|
}
|
79
|
-
}
|
114
|
+
}
|
@@ -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,60 @@
|
|
1
|
+
import { visit, remote } from '@jho406/breezy/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
|
+
ref.current.navigateTo(meta.pageKey, {
|
23
|
+
action: meta.suggestedAction,
|
24
|
+
})
|
25
|
+
})
|
26
|
+
.finally(() => {
|
27
|
+
// Do something after
|
28
|
+
// e.g, hide loading state, you can access the changed pageKey
|
29
|
+
// via getState().breezy.currentPageKey
|
30
|
+
})
|
31
|
+
.catch((err) => {
|
32
|
+
const response = err.response
|
33
|
+
|
34
|
+
if (!response) {
|
35
|
+
console.error(err)
|
36
|
+
return
|
37
|
+
}
|
38
|
+
|
39
|
+
if (response.ok) {
|
40
|
+
// err gets thrown, but if the response is ok,
|
41
|
+
// it must be an html body that
|
42
|
+
// breezy can't parse, just go to the location
|
43
|
+
window.location = response.url
|
44
|
+
} else {
|
45
|
+
if (response.status >= 400 && response.status < 500) {
|
46
|
+
window.location = '/400.html'
|
47
|
+
return
|
48
|
+
}
|
49
|
+
|
50
|
+
if (response.status >= 500) {
|
51
|
+
window.location = '/500.html'
|
52
|
+
return
|
53
|
+
}
|
54
|
+
}
|
55
|
+
})
|
56
|
+
}
|
57
|
+
|
58
|
+
return { visit: appVisit, remote: appRemote }
|
59
|
+
}
|
60
|
+
|
@@ -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,23 +43,26 @@ 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
|
59
|
+
run "yarn add babel-plugin-module-resolver history@\"^4\" html-react-parser@\"^0.13\" react-redux redux-thunk redux redux-persist reduce-reducers immer @jho406/breezy --save"
|
75
60
|
|
76
61
|
say "Updating webpack config to include .jsx file extension and resolved_paths"
|
77
|
-
insert_into_file Webpacker.config.config_path, " - .jsx\n", after:
|
62
|
+
insert_into_file Webpacker.config.config_path, " - .jsx\n", after: /\bextensions:\n/
|
63
|
+
# For newer webpacker
|
64
|
+
insert_into_file Webpacker.config.config_path, "'app/views', 'app/components'", after: /additional_paths: \[/
|
65
|
+
# For older webpacker
|
78
66
|
insert_into_file Webpacker.config.config_path, "'app/views', 'app/components'", after: /resolved_paths: \[/
|
79
67
|
|
80
68
|
say "Webpacker now supports breezy.js 🎉", :green
|
data/lib/tasks/install.rake
CHANGED
@@ -15,7 +15,7 @@ namespace :breezy do
|
|
15
15
|
package_json = JSON.parse(File.read(Rails.root.join("package.json")))
|
16
16
|
|
17
17
|
if package_json['dependencies']['react'].nil?
|
18
|
-
$stderr.puts "React not installed. Did you
|
18
|
+
$stderr.puts "React not installed. Did you install React? https://github.com/rails/webpacker#react"
|
19
19
|
$stderr.puts "Exiting!" && exit!
|
20
20
|
end
|
21
21
|
end
|
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.18.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:
|
11
|
+
date: 2021-07-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: actionpack
|
@@ -28,16 +28,16 @@ dependencies:
|
|
28
28
|
name: props_template
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 0.
|
33
|
+
version: 0.20.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.20.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
|
@@ -210,8 +210,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
210
210
|
- !ruby/object:Gem::Version
|
211
211
|
version: '0'
|
212
212
|
requirements: []
|
213
|
-
rubygems_version: 3.
|
214
|
-
signing_key:
|
213
|
+
rubygems_version: 3.1.2
|
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
|
-
|