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 +4 -4
- data/lib/generators/rails/templates/edit.json.props +2 -4
- data/lib/generators/rails/templates/new.json.props +2 -4
- data/lib/generators/rails/templates/web/edit.js +2 -5
- data/lib/generators/rails/templates/web/index.js +4 -4
- data/lib/generators/rails/templates/web/new.js +2 -5
- data/lib/generators/rails/templates/web/show.js +3 -3
- data/lib/install/templates/web/actions.js +6 -3
- data/lib/install/templates/web/application.js +9 -30
- data/lib/install/templates/web/application.json.props +4 -1
- data/lib/install/templates/web/flash.js +19 -0
- data/lib/install/templates/web/pages.js +15 -0
- data/lib/install/templates/web/store.js +32 -0
- data/lib/install/web.rb +9 -6
- data/lib/tasks/install.rake +1 -11
- metadata +11 -24
- data/lib/install/templates/web/action_creators.js +0 -14
- data/lib/install/templates/web/reducer.js +0 -44
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: '0586b4b5e16fbae55b29d0b9b56fb421fec1f5e0841bea7cb8ed2ee661ad6642'
|
4
|
+
data.tar.gz: 01fe043eadc91fb4efe74b96e4e1ce35d01bcb895514d701b6a924ce8c7ed994
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dab5eef3eff758a64408a2d239e47d0107b60952cb4eb0dfec97a241f39eeeea644ff67741022550d6ca2847a5773098c72379c2b48a2fafb86f0f0ba6d46980
|
7
|
+
data.tar.gz: 10340fee27529540353885d343bd5202a35db8bbd5a403156b53c38e960e1b299dd34d5b8955e831cf0791f0f3ebed35908d3189a828fed3605e51eb4be640c8
|
@@ -1,10 +1,8 @@
|
|
1
1
|
if @post.errors.any?
|
2
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
2
|
-
|
3
|
-
|
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 {
|
7
|
-
import { ApplicationBase
|
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
|
22
|
-
|
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
|
-
|
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
|
-
|
63
|
-
/>,
|
64
|
-
appEl
|
42
|
+
/>
|
65
43
|
);
|
66
44
|
}
|
67
45
|
});
|
68
46
|
}
|
69
47
|
|
48
|
+
|
@@ -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
|
26
|
-
copy_file "#{__dir__}/templates/web/
|
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
|
29
|
-
copy_file "#{__dir__}/templates/web/
|
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
|
50
|
-
run "yarn add history react
|
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
|
data/lib/tasks/install.rake
CHANGED
@@ -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"
|
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
|
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
|
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:
|
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:
|
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: '
|
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: '
|
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/
|
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:
|
192
|
+
version: '0'
|
206
193
|
requirements: []
|
207
194
|
rubygems_version: 3.4.6
|
208
195
|
signing_key:
|
@@ -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
|
-
}
|