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 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
-