breezy 0.14.0 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8fdfe1618e246afbe75d3871a455b9404f46812e8aa9d560a94fae39494007b2
4
- data.tar.gz: 7274f1da29d6f9f179b431caeb8b9a42a473f5fe2cfde7a71a94402c75a75cbf
3
+ metadata.gz: 5c5e2d6ff06a62de207f2b867d1e64044b66816d5abbad514ea00a321bd01e04
4
+ data.tar.gz: e0b800f96939f33d719212de311eb8d692b5d8e7122a0a3cf424572239358a77
5
5
  SHA512:
6
- metadata.gz: 7782300709770eb255c4922866fa967a0ea0af748b8269cef7f674342638430f05f66e4cfa53ca74197fb02a8d7e7f9b29597167436eb1ccb357db90b8f6395a
7
- data.tar.gz: e1186f6487243b10f8c1c29bb068ca1accd20b08050d15485e68d1adee3f52b33a4ef267869ab555ecb4bf775477a0e9a26284560bda7c2141bb0b07ec1cdce4
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: 'const identifierToComponentMapping = {' do
57
- "\n '#{[controller_file_path, action].join('/')}': #{component_name},"
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
- <%% content_for :initial_state do %>
4
- <script type="text/javascript">
5
- window.BREEZY_INITIAL_PAGE_STATE=<%%= initial_state.html_safe %>;
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 {mapStateToProps, mapDispatchToProps} from '@jho406/breezy'
3
- import {connect} from 'react-redux'
4
- import BaseScreen from 'components/BaseScreen'
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
- class <%= plural_table_name.camelize %>Edit extends BaseScreen {
9
- render () {
10
- const {
11
- form,
12
- flash,
13
- <%= singular_table_name.camelize(:lower) %>Path,
14
- <%= plural_table_name.camelize(:lower) %>Path,
15
- } = this.props
16
- const error = flash.form_error
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
- const messagesEl = error && (
19
- <div id="error_explanation">
20
- <h2>{ error.explanation }</h2>
21
- <ul>{ error.messages.map(({body})=> <li key={body}>{body}</li>) }</ul>
22
- </div>
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
- return (
26
- <div>
27
- {messagesEl}
28
- <RailsTag {...form} data-bz-visit={true}/>
29
- <a href={<%= singular_table_name.camelize(:lower) %>Path} data-bz-visit={true}>Show</a>
30
- <a href={<%= plural_table_name.camelize(:lower) %>Path} data-bz-visit={true}>Back</a>
31
- </div>
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
- <%% content_for :initial_state do %>
4
- <script type="text/javascript">
5
- window.BREEZY_INITIAL_PAGE_STATE=<%%= initial_state.html_safe %>;
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 {mapStateToProps, mapDispatchToProps} from '@jho406/breezy'
3
- import { connect } from 'react-redux'
4
- import BaseScreen from 'components/BaseScreen'
5
-
6
- class <%= plural_table_name.camelize %>Index extends BaseScreen {
7
- static defaultProps = {
8
- <%= plural_table_name.camelize(:lower) %>: []
9
- }
10
-
11
- render () {
12
- const {
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
- <div>
31
- <p id="notice">{flash.notice}</p>
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
- <h1><%= plural_table_name.capitalize %></h1>
25
+ return (
26
+ <div>
27
+ <p id="notice">{flash.notice}</p>
34
28
 
35
- <table>
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
- <tbody>
46
- {<%= singular_table_name %>Items}
47
- </tbody>
48
- </table>
49
- <br />
50
- <a href={new<%= singular_table_name.camelize %>Path} data-bz-visit={true}>New <%= singular_table_name.capitalize %></a>
51
- </div>
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
- <%% content_for :initial_state do %>
4
- <script type="text/javascript">
5
- window.BREEZY_INITIAL_PAGE_STATE=<%%= initial_state.html_safe %>;
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 {mapStateToProps, mapDispatchToProps} from '@jho406/breezy'
3
- import {connect} from 'react-redux'
4
- import BaseScreen from 'components/BaseScreen'
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
- class <%= plural_table_name.camelize %>New extends BaseScreen {
9
- render () {
10
- const {
11
- form,
12
- flash,
13
- <%= plural_table_name.camelize(:lower) %>Path,
14
- } = this.props
15
- const error = flash.form_error
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
- const messagesEl = error && (
18
- <div id="error_explanation">
19
- <h2>{ error.explanation }</h2>
20
- <ul>{ error.messages.map(({body})=> <li key={body}>{body}</li>) }</ul>
21
- </div>
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
- return (
25
- <div>
26
- {messagesEl}
27
- <RailsTag {...this.props.form} data-bz-visit={true}/>
28
- <a href={<%= plural_table_name.camelize(:lower) %>Path} data-bz-visit={true}>Back</a>
29
- </div>
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
- <%% content_for :initial_state do %>
4
- <script type="text/javascript">
5
- window.BREEZY_INITIAL_PAGE_STATE=<%%= initial_state.html_safe %>;
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 {mapStateToProps, mapDispatchToProps} from '@jho406/breezy'
3
- import { connect } from 'react-redux'
4
- import BaseScreen from 'components/BaseScreen'
2
+ // import * as actionCreators from 'javascript/packs/action_creators'
3
+ // import {useDispatch} from 'react-redux'
5
4
 
6
- class <%= plural_table_name.camelize %>Show extends BaseScreen {
7
- render () {
8
- return (
9
- <div>
10
- <p id="notice">{this.props.flash && this.props.flash.notice}</p>
11
- <%- attributes_list_with_timestamps.select{|attr| attr != :id }.each do |attr| -%>
12
- <p>
13
- <strong><%= attr.capitalize %>:</strong>
14
- {this.props.<%=attr.camelize(:lower)%>}
15
- </p>
16
- <%- end -%>
17
- <a href={ this.props.edit<%= singular_table_name.camelize %>Path } data-bz-visit={true}>Edit</a>
18
- <a href={ this.props.<%= plural_table_name.camelize(:lower) %>Path } data-bz-visit={true}>Back</a>
19
- </div>
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,3 +1,4 @@
1
1
  // Example:
2
2
  //
3
3
  // export const CLEAR_FORM_ERRORS = 'CLEAR_FORM_ERRORS'
4
+ export const REHYDRATE = 'persist/REHYDRATE'
@@ -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 { createBrowserHistory } from 'history'
8
- import Breezy from '@jho406/breezy'
9
- import Nav from '@jho406/breezy/dist/NavComponent'
10
- import ujsHandlers from '@jho406/breezy/dist/utils/ujs'
11
- import applicationReducer from './reducer'
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
- //The Nav is pretty bare bones
23
- //Feel free to replace the implementation
24
- const {reducer, initialState, initialPageKey, connect} = Breezy.start({
25
- window,
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
- const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose
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
- const {
34
- breezy: breezyReducer,
35
- pages: pagesReducer,
36
- } = reducer
46
+ export default class Application extends ApplicationBase {
47
+ mapping() {
48
+ return identifierToComponentMapping;
49
+ }
37
50
 
38
- const store = createStore(
39
- combineReducers({
40
- breezy: breezyReducer,
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
- const navigatorRef = React.createRef()
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
- connect(store)
76
+ if (this.hasWindow) {
77
+ // Persist the store using Redux-Persist
78
+ persistStore(store);
79
+ }
50
80
 
51
- class App extends React.Component {
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
- document.addEventListener("DOMContentLoaded", function() {
66
- const appEl = document.getElementById('app')
67
- if (appEl) {
68
- const {onClick, onSubmit} = ujsHandlers({
69
- navigatorRef,
70
- store,
71
- ujsAttributePrefix: 'data-bz'
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
- appEl.addEventListener('click', onClick)
75
- appEl.addEventListener('submit', onSubmit)
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
- render(<App mapping={identifierToComponentMapping}/>, appEl)
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
- export default function (state = {}, action) {
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 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 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: /extensions:\n/
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
@@ -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 run `rails webpacker:install:react`?"
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.14.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: 2020-06-05 00:00:00.000000000 Z
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.14.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.14.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.0.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
-