superglue 0.50.0.beta1 → 0.50.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: 44a42cb747cff210dd1550dae3f9ddf280e72a2b38ff26b72fa5f2eea2eeadfe
4
- data.tar.gz: f52f207c4be16d576a51c09f0e821c08d9af68b8150bf52d5b007f59e912d936
3
+ metadata.gz: '0586b4b5e16fbae55b29d0b9b56fb421fec1f5e0841bea7cb8ed2ee661ad6642'
4
+ data.tar.gz: 01fe043eadc91fb4efe74b96e4e1ce35d01bcb895514d701b6a924ce8c7ed994
5
5
  SHA512:
6
- metadata.gz: 57a0e0bbfd2fdcc815af7922f3b97042d016fe6f68be3389a83bcb77a5de2e1e68423a172878482533f25b69464c09d0395a116c4e8179a48ffce1d7a681dcd7
7
- data.tar.gz: d8f034124031b598ee70394fd4900e4daab38126458db85f25afb96e9074bb07196d1f01e9975e960768676da469772d7be044ca3ce0915de95f2e129fdc78d7
6
+ metadata.gz: dab5eef3eff758a64408a2d239e47d0107b60952cb4eb0dfec97a241f39eeeea644ff67741022550d6ca2847a5773098c72379c2b48a2fafb86f0f0ba6d46980
7
+ data.tar.gz: 10340fee27529540353885d343bd5202a35db8bbd5a403156b53c38e960e1b299dd34d5b8955e831cf0791f0f3ebed35908d3189a828fed3605e51eb4be640c8
@@ -1,10 +1,8 @@
1
1
  if @post.errors.any?
2
- content = {
2
+ json.errors({
3
3
  explanation: "#{pluralize(@<%= singular_table_name %>.errors.count, "error")} prohibited this post from being saved:",
4
4
  messages: @<%= singular_table_name %>.errors.full_messages.map{|msg| {body: msg}}
5
- }
6
-
7
- flash.now[:form_error] = content
5
+ })
8
6
  end
9
7
 
10
8
  json.form(partial: 'form') do
@@ -1,10 +1,8 @@
1
1
  if @post.errors.any?
2
- content = {
2
+ json.errors({
3
3
  explanation: "#{pluralize(@<%= singular_table_name %>.errors.count, "error")} prohibited this post from being saved:",
4
4
  messages: @<%= singular_table_name %>.errors.full_messages.map{|msg| {body: msg}}
5
- }
6
-
7
- flash.now[:form_error] = content
5
+ })
8
6
  end
9
7
 
10
8
  json.form(partial: 'form') do
@@ -1,17 +1,14 @@
1
1
  import React from 'react'
2
- // import * as actionCreators from 'javascript/packs/action_creators'
3
- // import {useDispatch} from 'react-redux'
2
+ // import { useSelector } from 'react-redux'
4
3
 
5
4
  export default function <%= plural_table_name.camelize %>Edit ({
6
5
  // visit,
7
6
  // remote,
8
7
  form,
9
- flash,
8
+ error,
10
9
  <%= singular_table_name.camelize(:lower) %>Path,
11
10
  <%= plural_table_name.camelize(:lower) %>Path,
12
11
  }) {
13
- const error = flash.form_error
14
-
15
12
  const messagesEl = error && (
16
13
  <div id="error_explanation">
17
14
  <h2>{ error.explanation }</h2>
@@ -1,14 +1,14 @@
1
1
  import React from 'react'
2
- // import * as actionCreators from 'javascript/packs/action_creators'
3
- // import {useDispatch} from 'react-redux'
2
+ import { useSelector } from 'react-redux'
4
3
 
5
4
  export default function <%= plural_table_name.camelize %>Index({
6
5
  // visit,
7
6
  // remote,
8
- flash,
9
7
  new<%= singular_table_name.camelize %>Path,
10
8
  <%= plural_table_name.camelize(:lower) %> = [],
11
9
  }) {
10
+ const flash = useSelector((state) => state.flash)
11
+
12
12
  const <%= singular_table_name.camelize(:lower) %>Items = <%= plural_table_name.camelize(:lower) %>.map((<%= singular_table_name.camelize(:lower) %>, key) => {
13
13
  const deleteForm = <%=singular_table_name.camelize(:lower)%>.deleteForm;
14
14
 
@@ -31,7 +31,7 @@ export default function <%= plural_table_name.camelize %>Index({
31
31
 
32
32
  return (
33
33
  <div>
34
- <p id="notice">{flash.notice}</p>
34
+ <p id="notice">{flash && flash.notice}</p>
35
35
 
36
36
  <h1><%= plural_table_name.capitalize %></h1>
37
37
 
@@ -1,16 +1,13 @@
1
1
  import React from 'react'
2
- // import * as actionCreators from 'javascript/packs/action_creators'
3
- // import { useDispatch } from 'react-redux'
2
+ // import { useSelector } from 'react-redux'
4
3
 
5
4
  export default function <%= plural_table_name.camelize %>New({
6
5
  // visit,
7
6
  // remote
8
7
  form,
9
- flash,
8
+ error,
10
9
  <%= plural_table_name.camelize(:lower) %>Path,
11
10
  }) {
12
- const error = flash.form_error
13
-
14
11
  const messagesEl = error && (
15
12
  <div id="error_explanation">
16
13
  <h2>{ error.explanation }</h2>
@@ -1,17 +1,17 @@
1
1
  import React from 'react'
2
- // import * as actionCreators from 'javascript/packs/action_creators'
3
- // import {useDispatch} from 'react-redux'
2
+ import { useSelector } from 'react-redux'
4
3
 
5
4
  export default function <%= plural_table_name.camelize %>Show({
6
5
  // visit,
7
6
  // remote,
8
- flash,
9
7
  <%- attributes_list_with_timestamps.select{|attr| attr != :id }.each do |attr| -%>
10
8
  <%=attr.camelize(:lower)%>,
11
9
  <%- end -%>
12
10
  edit<%= singular_table_name.camelize %>Path,
13
11
  <%= plural_table_name.camelize(:lower) %>Path
14
12
  }) {
13
+ const flash = useSelector((state) => state.flash)
14
+
15
15
  return (
16
16
  <div>
17
17
  <p id="notice">{flash && flash.notice}</p>
@@ -1,3 +1,6 @@
1
- // Example:
2
- //
3
- // export const CLEAR_FORM_ERRORS = 'CLEAR_FORM_ERRORS'
1
+ import { createAction } from '@reduxjs/toolkit'
2
+ import { SAVE_RESPONSE, BEFORE_VISIT, UPDATE_FRAGMENTS } from '@thoughtbot/superglue'
3
+
4
+ export const saveResponse = createAction(SAVE_RESPONSE)
5
+ export const beforeVisit = createAction(BEFORE_VISIT)
6
+ export const updateFragments = createAction(UPDATE_FRAGMENTS)
@@ -1,13 +1,11 @@
1
1
  import React from 'react';
2
- import { combineReducers, createStore, applyMiddleware, compose } from 'redux';
3
- import reduceReducers from 'reduce-reducers';
4
2
  import thunk from 'redux-thunk';
5
3
  import { Provider } from 'react-redux';
6
- import { render } from 'react-dom';
7
- import { ApplicationBase, fragmentMiddleware } from '@thoughtbot/superglue';
8
- import { applicationRootReducer, applicationPagesReducer } from './reducer';
4
+ import { createRoot } from 'react-dom/client';
5
+ import { ApplicationBase } from '@thoughtbot/superglue';
9
6
  import { buildVisitAndRemote } from './application_visit';
10
7
  import { pageIdentifierToPageComponent } from './page_to_page_mapping';
8
+ import { buildStore } from './store'
11
9
 
12
10
  class Application extends ApplicationBase {
13
11
  mapping() {
@@ -18,27 +16,8 @@ class Application extends ApplicationBase {
18
16
  return buildVisitAndRemote(navRef, store);
19
17
  }
20
18
 
21
- buildStore(initialState, { superglue: superglueReducer, pages: pagesReducer }) {
22
- // Create the store
23
- // See `./reducer.js` for an explaination of the two included reducers
24
- const composeEnhancers =
25
- (this.hasWindow && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||
26
- compose;
27
- const reducer = reduceReducers(
28
- combineReducers({
29
- superglue: superglueReducer,
30
- pages: reduceReducers(pagesReducer, applicationPagesReducer),
31
- }),
32
- applicationRootReducer
33
- );
34
-
35
- const store = createStore(
36
- reducer,
37
- initialState,
38
- composeEnhancers(applyMiddleware(thunk, fragmentMiddleware))
39
- );
40
-
41
- return store;
19
+ buildStore(initialState, { superglue, pages}) {
20
+ return buildStore(initialState, superglue, pages);
42
21
  }
43
22
  }
44
23
 
@@ -48,7 +27,8 @@ if (typeof window !== "undefined") {
48
27
  const location = window.location;
49
28
 
50
29
  if (appEl) {
51
- render(
30
+ const root = createRoot(appEl);
31
+ root.render(
52
32
  <Application
53
33
  appEl={appEl}
54
34
  // The base url prefixed to all calls made by the `visit`
@@ -59,11 +39,10 @@ if (typeof window !== "undefined") {
59
39
  initialPage={window.SUPERGLUE_INITIAL_PAGE_STATE}
60
40
  // The initial path of the page, e.g., /foobar
61
41
  path={location.pathname + location.search + location.hash}
62
- buildVisitAndRemote={buildVisitAndRemote}
63
- />,
64
- appEl
42
+ />
65
43
  );
66
44
  }
67
45
  });
68
46
  }
69
47
 
48
+
@@ -21,4 +21,7 @@ end
21
21
  json.restore_strategy 'fromCacheAndRevisitInBackground'
22
22
 
23
23
  json.rendered_at Time.now.to_i
24
- json.flash flash.to_h
24
+
25
+ json.slices do
26
+ json.flash flash.to_h
27
+ end
@@ -0,0 +1,19 @@
1
+ import { createSlice } from '@reduxjs/toolkit'
2
+ import { saveResponse, beforeVisit } from '../actions'
3
+
4
+ export const flashSlice = createSlice({
5
+ name: 'flash',
6
+ initialState: {},
7
+ extraReducers: (builder) => {
8
+ builder.addCase(beforeVisit, (state, action) => {
9
+ return {}
10
+ })
11
+ builder.addCase(saveResponse, (state, action) => {
12
+ const { page } = action.payload;
13
+
14
+ return {
15
+ ...state, ...page.slices.flash
16
+ }
17
+ })
18
+ }
19
+ })
@@ -0,0 +1,15 @@
1
+ import { createSlice } from '@reduxjs/toolkit'
2
+ import { saveResponse, beforeVisit } from '../actions'
3
+
4
+ export const pagesSlice = createSlice({
5
+ name: 'pages',
6
+ // extraReducers: (builder) => {
7
+ // builder.addCase(beforeVisit, (state, action) => {
8
+ // const {currentPageKey} = action.payload
9
+ //
10
+ // const currentPage = draft[currentPageKey]
11
+ // delete currentPage.error
12
+ // })
13
+ // }
14
+ })
15
+
@@ -0,0 +1,32 @@
1
+ import { configureStore } from '@reduxjs/toolkit'
2
+ import { pagesSlice } from "./slices/pages"
3
+ import { flashSlice } from "./slices/flash"
4
+ import {
5
+ BEFORE_VISIT,
6
+ BEFORE_FETCH,
7
+ BEFORE_REMOTE,
8
+ fragmentMiddleware
9
+ } from '@thoughtbot/superglue'
10
+
11
+ export const buildStore = (initialState, superglueReducer, supergluePagesReducer) => {
12
+
13
+ return configureStore({
14
+ preloadedState: initialState,
15
+ devTools: process.env.NODE_ENV !== 'production',
16
+ middleware: (getDefaultMiddleware) =>
17
+ getDefaultMiddleware({
18
+ serializableCheck: {
19
+ ignoredActions: [BEFORE_VISIT, BEFORE_FETCH, BEFORE_REMOTE],
20
+ },
21
+ }).concat(fragmentMiddleware),
22
+ reducer: {
23
+ superglue: superglueReducer,
24
+ pages: (state, action) => {
25
+ const nextState = supergluePagesReducer(state, action)
26
+ return pagesSlice.reducer(nextState, action)
27
+ },
28
+ flash: flashSlice.reducer
29
+ },
30
+ });
31
+ };
32
+
data/lib/install/web.rb CHANGED
@@ -22,11 +22,14 @@ copy_file "#{__dir__}/templates/web/application.js", "#{app_js_path}/application
22
22
  say "Copying page_to_page_mapping.js file to #{app_js_path}"
23
23
  copy_file "#{__dir__}/templates/web/page_to_page_mapping.js", "#{app_js_path}/page_to_page_mapping.js"
24
24
 
25
- say "Copying reducer.js file to #{app_js_path}"
26
- copy_file "#{__dir__}/templates/web/reducer.js", "#{app_js_path}/reducer.js"
25
+ say "Copying flash.js file to #{app_js_path}"
26
+ copy_file "#{__dir__}/templates/web/flash.js", "#{app_js_path}/slices/flash.js"
27
27
 
28
- say "Copying action_creators.js file to #{app_js_path}"
29
- copy_file "#{__dir__}/templates/web/action_creators.js", "#{app_js_path}/action_creators.js"
28
+ say "Copying pages.js file to #{app_js_path}"
29
+ copy_file "#{__dir__}/templates/web/pages.js", "#{app_js_path}/slices/pages.js"
30
+
31
+ say "Copying store.js file to #{app_js_path}"
32
+ copy_file "#{__dir__}/templates/web/store.js", "#{app_js_path}/store.js"
30
33
 
31
34
  say "Copying actions.js file to #{app_js_path}"
32
35
  copy_file "#{__dir__}/templates/web/actions.js", "#{app_js_path}/actions.js"
@@ -46,7 +49,7 @@ add_member_methods
46
49
  say "Installing FormProps"
47
50
  run "bundle add form_props"
48
51
 
49
- say "Installing React, Redux, and Superglue"
50
- run "yarn add history react-redux redux-thunk redux reduce-reducers immer @thoughtbot/superglue --save"
52
+ say "Installing Superglue and friends"
53
+ run "yarn add history react react-dom @reduxjs/toolkit react-redux @thoughtbot/superglue --save"
51
54
 
52
55
  say "Superglue is Installed! 🎉", :green
@@ -1,17 +1,7 @@
1
1
  namespace :superglue do
2
- desc "Verifies if any version of react is in package.json"
3
- task :verify_react do
4
- package_json = JSON.parse(File.read(Rails.root.join("package.json")))
5
-
6
- if package_json["dependencies"]["react"].nil?
7
- warn "React not installed. Did you install React? https://github.com/rails/webpacker#react"
8
- warn "Exiting!" && exit!
9
- end
10
- end
11
-
12
2
  namespace :install do
13
3
  desc "Install everything needed for superglue web"
14
- task "web" => ["superglue:verify_react"] do
4
+ task "web" do
15
5
  template = File.expand_path("../install/web.rb", __dir__)
16
6
  exec "#{RbConfig.ruby} ./bin/rails app:template LOCATION=#{template}"
17
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: superglue
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.50.0.beta1
4
+ version: 0.50.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Johny Ho
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-08-17 00:00:00.000000000 Z
11
+ date: 2023-10-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: actionpack
@@ -16,14 +16,14 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 6.0.0
19
+ version: 7.0.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 6.0.0
26
+ version: 7.0.0
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: props_template
29
29
  requirement: !ruby/object:Gem::Requirement
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '6.0'
61
+ version: '7.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '6.0'
68
+ version: '7.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rake
71
71
  requirement: !ruby/object:Gem::Requirement
@@ -80,20 +80,6 @@ dependencies:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '12.0'
83
- - !ruby/object:Gem::Dependency
84
- name: byebug
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - "~>"
88
- - !ruby/object:Gem::Version
89
- version: '9.0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - "~>"
95
- - !ruby/object:Gem::Version
96
- version: '9.0'
97
83
  - !ruby/object:Gem::Dependency
98
84
  name: sqlite3
99
85
  requirement: !ruby/object:Gem::Requirement
@@ -172,14 +158,15 @@ files:
172
158
  - lib/generators/rails/templates/web/new.js
173
159
  - lib/generators/rails/templates/web/show.html.erb
174
160
  - lib/generators/rails/templates/web/show.js
175
- - lib/install/templates/web/action_creators.js
176
161
  - lib/install/templates/web/actions.js
177
162
  - lib/install/templates/web/application.js
178
163
  - lib/install/templates/web/application.json.props
179
164
  - lib/install/templates/web/application_visit.js
165
+ - lib/install/templates/web/flash.js
180
166
  - lib/install/templates/web/initializer.rb
181
167
  - lib/install/templates/web/page_to_page_mapping.js
182
- - lib/install/templates/web/reducer.js
168
+ - lib/install/templates/web/pages.js
169
+ - lib/install/templates/web/store.js
183
170
  - lib/install/web.rb
184
171
  - lib/superglue.rb
185
172
  - lib/superglue/helpers.rb
@@ -200,9 +187,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
200
187
  version: '0'
201
188
  required_rubygems_version: !ruby/object:Gem::Requirement
202
189
  requirements:
203
- - - ">"
190
+ - - ">="
204
191
  - !ruby/object:Gem::Version
205
- version: 1.3.1
192
+ version: '0'
206
193
  requirements: []
207
194
  rubygems_version: 3.4.6
208
195
  signing_key:
@@ -1,14 +0,0 @@
1
- // Example:
2
- //
3
- // import {
4
- // CLEAR_FORM_ERRORS
5
- // } from './actions'
6
- //
7
- // export function clearFormErrors(pageKey) {
8
- // return {
9
- // type: CLEAR_FORM_ERRORS,
10
- // payload: {
11
- // pageKey,
12
- // }
13
- // }
14
- // }
@@ -1,44 +0,0 @@
1
- // Example:
2
- //
3
- // import {
4
- // CLEAR_FORM_ERRORS
5
- // } from './actions'
6
- // import produce from "immer"
7
- //
8
- // export const applicationPagesReducer = (state = {}, action) => {
9
- // switch(action.type) {
10
- // case CLEAR_FORM_ERRORS: {
11
- // const {pageKey} = action.payload
12
- //
13
- // return produce(state, draft => {
14
- // const currentPage = draft[pageKey]
15
- // delete currentPage.errors
16
- // })
17
- // }
18
- // default:
19
- // return state
20
- // }
21
- // }
22
-
23
-
24
- // The applicationPageReducer is for cross page reducers
25
- // Its common to add to this. You'll typically have to pass a pageKey to the
26
- // action payload to distinguish the current page
27
- //
28
- // The pageKey is passed through the props in your component. Access it like
29
- // this: `this.props.pageKey` then dispatch it in an action
30
- export const applicationPagesReducer = (state = {}, action) => {
31
- switch(action.type) {
32
- default:
33
- return state
34
- }
35
- }
36
-
37
- // The applicationRootReducer is for app wide reducers
38
- // Its rare to be adding to this.
39
- export const applicationRootReducer = (state = {}, action) => {
40
- switch(action.type) {
41
- default:
42
- return state
43
- }
44
- }