superglue 0.41.0 → 0.50.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/rails/scaffold_controller_generator.rb +3 -3
- data/lib/generators/rails/superglue_generator.rb +49 -60
- data/lib/generators/rails/templates/_form.json.props +3 -10
- data/lib/generators/rails/templates/edit.json.props +2 -4
- data/lib/generators/rails/templates/index.json.props +3 -1
- data/lib/generators/rails/templates/new.json.props +2 -4
- data/lib/generators/rails/templates/web/edit.js +11 -7
- data/lib/generators/rails/templates/web/index.js +12 -5
- data/lib/generators/rails/templates/web/new.js +11 -7
- 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 +20 -47
- data/lib/install/templates/web/application.json.props +5 -6
- data/lib/install/templates/web/flash.js +19 -0
- data/lib/install/templates/web/initializer.rb +1 -1
- data/lib/install/templates/web/page_to_page_mapping.js +12 -0
- data/lib/install/templates/web/pages.js +15 -0
- data/lib/install/templates/web/store.js +32 -0
- data/lib/install/web.rb +15 -19
- data/lib/superglue/helpers.rb +7 -517
- data/lib/superglue/redirection.rb +1 -2
- data/lib/superglue.rb +6 -6
- data/lib/tasks/install.rake +1 -12
- metadata +20 -40
- data/lib/install/templates/web/action_creators.js +0 -14
- data/lib/install/templates/web/reducer.js +0 -44
- data/test/engine_test.rb +0 -7
- data/test/helpers_test.rb +0 -23
- data/test/render_test.rb +0 -81
- data/test/test_helper.rb +0 -20
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,10 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "rails/generators"
|
2
|
+
require "rails/generators/rails/scaffold_controller/scaffold_controller_generator"
|
3
3
|
|
4
4
|
module Rails
|
5
5
|
module Generators
|
6
6
|
class ScaffoldControllerGenerator
|
7
|
-
source_paths << File.expand_path(
|
7
|
+
source_paths << File.expand_path("../templates", __FILE__)
|
8
8
|
|
9
9
|
hook_for :superglue, type: :boolean, default: true
|
10
10
|
end
|
@@ -1,109 +1,98 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require 'rails/version'
|
1
|
+
require "rails/generators/named_base"
|
2
|
+
require "rails/generators/resource_helpers"
|
4
3
|
|
5
4
|
module Rails
|
6
5
|
module Generators
|
7
6
|
class SuperglueGenerator < NamedBase
|
8
7
|
include Rails::Generators::ResourceHelpers
|
9
8
|
|
10
|
-
source_root File.expand_path(
|
9
|
+
source_root File.expand_path("../templates", __FILE__)
|
11
10
|
|
12
|
-
argument :attributes, type: :array, default: [], banner:
|
11
|
+
argument :attributes, type: :array, default: [], banner: "field:type field:type"
|
13
12
|
|
14
13
|
def create_root_folder
|
15
|
-
path = File.join(
|
14
|
+
path = File.join("app/views", controller_file_path)
|
16
15
|
empty_directory path unless File.directory?(path)
|
17
16
|
end
|
18
17
|
|
19
18
|
def copy_view_files
|
20
|
-
%w
|
19
|
+
%w[index show new edit].each do |view|
|
21
20
|
@action_name = view
|
22
21
|
filename = filename_with_extensions(view)
|
23
|
-
template filename, File.join(
|
22
|
+
template filename, File.join("app/views", controller_file_path, filename)
|
24
23
|
end
|
25
|
-
template
|
24
|
+
template "_form.json.props", File.join("app/views", controller_file_path, "_form.json.props")
|
26
25
|
|
27
|
-
%w
|
26
|
+
%w[index show new edit].each do |view|
|
28
27
|
@action_name = view
|
29
28
|
filename = filename_with_js_extensions(view)
|
30
|
-
template
|
29
|
+
template "web/" + filename, File.join("app/views", controller_file_path, filename)
|
31
30
|
end
|
32
31
|
|
33
|
-
%w
|
32
|
+
%w[index show new edit].each do |view|
|
34
33
|
@action_name = view
|
35
34
|
filename = filename_with_html_extensions(view)
|
36
|
-
template
|
35
|
+
template "web/" + filename, File.join("app/views", controller_file_path, filename)
|
37
36
|
end
|
38
37
|
|
39
|
-
%w
|
38
|
+
%w[index show new edit].each do |view|
|
40
39
|
append_mapping(view)
|
41
40
|
end
|
42
41
|
end
|
43
42
|
|
44
|
-
|
45
43
|
protected
|
46
|
-
def view_path
|
47
|
-
if Rails.version >= "7"
|
48
|
-
"../views"
|
49
|
-
else
|
50
|
-
"../../views"
|
51
|
-
end
|
52
|
-
end
|
53
44
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
else
|
58
|
-
"app/javascript/packs"
|
59
|
-
end
|
60
|
-
end
|
45
|
+
def view_path
|
46
|
+
"../views"
|
47
|
+
end
|
61
48
|
|
62
|
-
|
63
|
-
|
49
|
+
def app_js_path
|
50
|
+
"app/javascript/"
|
51
|
+
end
|
64
52
|
|
65
|
-
|
53
|
+
def append_mapping(action)
|
54
|
+
app_js = "#{app_js_path}/page_to_page_mapping.js"
|
66
55
|
|
67
|
-
|
68
|
-
"\nimport #{component_name} from '#{view_path}/#{controller_file_path}/#{action}'"
|
69
|
-
end
|
56
|
+
component_name = [plural_table_name, action].map(&:camelcase).join
|
70
57
|
|
71
|
-
|
72
|
-
|
73
|
-
end
|
58
|
+
prepend_to_file app_js do
|
59
|
+
"\nimport #{component_name} from '#{view_path}/#{controller_file_path}/#{action}'"
|
74
60
|
end
|
75
61
|
|
76
|
-
|
77
|
-
|
62
|
+
inject_into_file app_js, after: "pageIdentifierToPageComponent = {" do
|
63
|
+
"\n '#{[controller_file_path, action].join("/")}': #{component_name},"
|
78
64
|
end
|
65
|
+
end
|
79
66
|
|
80
|
-
|
81
|
-
[:id] + super
|
82
|
-
end
|
67
|
+
attr_reader :action_name
|
83
68
|
|
84
|
-
|
85
|
-
|
86
|
-
|
69
|
+
def attributes_names
|
70
|
+
[:id] + super
|
71
|
+
end
|
87
72
|
|
88
|
-
|
89
|
-
|
90
|
-
|
73
|
+
def filename_with_extensions(name)
|
74
|
+
[name, :json, :props].join(".")
|
75
|
+
end
|
91
76
|
|
92
|
-
|
93
|
-
|
94
|
-
|
77
|
+
def filename_with_js_extensions(name)
|
78
|
+
[name, :js].join(".")
|
79
|
+
end
|
95
80
|
|
96
|
-
|
97
|
-
|
98
|
-
|
81
|
+
def filename_with_html_extensions(name)
|
82
|
+
[name, :html, :erb].join(".")
|
83
|
+
end
|
99
84
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
end
|
85
|
+
def attributes_list_with_timestamps
|
86
|
+
attributes_list(attributes_names + %w[created_at updated_at])
|
87
|
+
end
|
104
88
|
|
105
|
-
|
89
|
+
def attributes_list(attributes = attributes_names)
|
90
|
+
if self.attributes.any? { |attr| attr.name == "password" && attr.type == :digest }
|
91
|
+
attributes = attributes.reject { |name| %w[password password_confirmation].include? name }
|
106
92
|
end
|
93
|
+
|
94
|
+
attributes
|
95
|
+
end
|
107
96
|
end
|
108
97
|
end
|
109
98
|
end
|
@@ -1,13 +1,6 @@
|
|
1
|
-
|
2
|
-
inner = "".html_safe
|
3
|
-
|
1
|
+
form_props(model: @<%= model_resource_name %>) do |f|
|
4
2
|
<%- attributes.each do |attr| -%>
|
5
|
-
|
6
|
-
inner << form.<%= attr.field_type %>(:<%= attr.column_name %>)
|
3
|
+
f.<%= attr.field_type %>(:<%= attr.column_name %>)
|
7
4
|
<%- end -%>
|
8
|
-
|
9
|
-
|
10
|
-
inner
|
5
|
+
f.submit
|
11
6
|
end
|
12
|
-
|
13
|
-
json.html html
|
@@ -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
|
@@ -5,7 +5,9 @@ json.<%= plural_table_name %> do
|
|
5
5
|
<%- end -%>
|
6
6
|
json.edit_<%=singular_table_name%>_path edit_<%=singular_table_name%>_path(<%=singular_table_name%>)
|
7
7
|
json.<%=singular_table_name%>_path <%=singular_table_name%>_path(<%=singular_table_name%>)
|
8
|
-
json.
|
8
|
+
json.delete_form do
|
9
|
+
form_props(model: <%=singular_table_name%>, method: :delete)
|
10
|
+
end
|
9
11
|
end
|
10
12
|
end
|
11
13
|
|
@@ -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,18 +1,14 @@
|
|
1
1
|
import React from 'react'
|
2
|
-
import
|
3
|
-
// import * as actionCreators from 'javascript/packs/action_creators'
|
4
|
-
// import {useDispatch} from 'react-redux'
|
2
|
+
// import { useSelector } from 'react-redux'
|
5
3
|
|
6
4
|
export default function <%= plural_table_name.camelize %>Edit ({
|
7
5
|
// visit,
|
8
6
|
// remote,
|
9
7
|
form,
|
10
|
-
|
8
|
+
error,
|
11
9
|
<%= singular_table_name.camelize(:lower) %>Path,
|
12
10
|
<%= plural_table_name.camelize(:lower) %>Path,
|
13
11
|
}) {
|
14
|
-
const error = flash.form_error
|
15
|
-
|
16
12
|
const messagesEl = error && (
|
17
13
|
<div id="error_explanation">
|
18
14
|
<h2>{ error.explanation }</h2>
|
@@ -23,7 +19,15 @@ export default function <%= plural_table_name.camelize %>Edit ({
|
|
23
19
|
return (
|
24
20
|
<div>
|
25
21
|
{messagesEl}
|
26
|
-
<
|
22
|
+
<form {...form.props} data-sg-visit={true}>
|
23
|
+
{Object.values(form.extras).map((hiddenProps) => (<input {...hiddenProps} key={hiddenProps.id} type="hidden"/>))}
|
24
|
+
<%- attributes.each do |attr| -%>
|
25
|
+
<input {...form.inputs.<%= attr.column_name %>} type="text"/>
|
26
|
+
<label htmlFor={form.inputs.<%= attr.column_name %>.id}><%= attr.column_name %></label>
|
27
|
+
<%- end -%>
|
28
|
+
<button {...form.inputs.submit} type="submit"> {...form.inputs.submit.text} </button>
|
29
|
+
</form>
|
30
|
+
|
27
31
|
<a href={<%= singular_table_name.camelize(:lower) %>Path} data-sg-visit={true}>Show</a>
|
28
32
|
<a href={<%= plural_table_name.camelize(:lower) %>Path} data-sg-visit={true}>Back</a>
|
29
33
|
</div>
|
@@ -1,15 +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 %>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
|
+
const deleteForm = <%=singular_table_name.camelize(:lower)%>.deleteForm;
|
14
|
+
|
13
15
|
return (
|
14
16
|
<tr key={<%= singular_table_name.camelize(:lower) %>.id}>
|
15
17
|
<%- attributes_list.select{|attr| attr != :id }.each do |attr| -%>
|
@@ -17,14 +19,19 @@ export default function <%= plural_table_name.camelize %>Index({
|
|
17
19
|
<%- end -%>
|
18
20
|
<td><a href={ <%=singular_table_name%>.<%=singular_table_name.camelize(:lower)%>Path } data-sg-visit={true}>Show</a></td>
|
19
21
|
<td><a href={ <%=singular_table_name%>.edit<%=singular_table_name.camelize%>Path } data-sg-visit={true}>Edit</a></td>
|
20
|
-
<td
|
22
|
+
<td>
|
23
|
+
<form {...deleteForm.props} data-sg-visit={true}>
|
24
|
+
{Object.values(deleteForm.extras).map((hiddenProps) => (<input {...hiddenProps} key={hiddenProps.id} type="hidden"/>))}
|
25
|
+
<button type="submit">Delete</button>
|
26
|
+
</form>
|
27
|
+
</td>
|
21
28
|
</tr>
|
22
29
|
)
|
23
30
|
})
|
24
31
|
|
25
32
|
return (
|
26
33
|
<div>
|
27
|
-
<p id="notice">{flash.notice}</p>
|
34
|
+
<p id="notice">{flash && flash.notice}</p>
|
28
35
|
|
29
36
|
<h1><%= plural_table_name.capitalize %></h1>
|
30
37
|
|
@@ -1,17 +1,13 @@
|
|
1
1
|
import React from 'react'
|
2
|
-
import
|
3
|
-
// import * as actionCreators from 'javascript/packs/action_creators'
|
4
|
-
// import { useDispatch } from 'react-redux'
|
2
|
+
// import { useSelector } from 'react-redux'
|
5
3
|
|
6
4
|
export default function <%= plural_table_name.camelize %>New({
|
7
5
|
// visit,
|
8
6
|
// remote
|
9
7
|
form,
|
10
|
-
|
8
|
+
error,
|
11
9
|
<%= plural_table_name.camelize(:lower) %>Path,
|
12
10
|
}) {
|
13
|
-
const error = flash.form_error
|
14
|
-
|
15
11
|
const messagesEl = error && (
|
16
12
|
<div id="error_explanation">
|
17
13
|
<h2>{ error.explanation }</h2>
|
@@ -22,7 +18,15 @@ export default function <%= plural_table_name.camelize %>New({
|
|
22
18
|
return (
|
23
19
|
<div>
|
24
20
|
{messagesEl}
|
25
|
-
<
|
21
|
+
<form {...form.props} data-sg-visit={true}>
|
22
|
+
{Object.values(form.extras).map((hiddenProps) => (<input {...hiddenProps} key={hiddenProps.id} type="hidden"/>))}
|
23
|
+
<%- attributes.each do |attr| -%>
|
24
|
+
<input {...form.inputs.<%= attr.column_name %>} type="text"/>
|
25
|
+
<label htmlFor={form.inputs.<%= attr.column_name %>.id}><%= attr.column_name %></label>
|
26
|
+
<%- end -%>
|
27
|
+
<button {...form.inputs.submit} type="submit"> {...form.inputs.submit.text} </button>
|
28
|
+
</form>
|
29
|
+
|
26
30
|
<a href={<%= plural_table_name.camelize(:lower) %>Path} data-sg-visit={true}>Back</a>
|
27
31
|
</div>
|
28
32
|
)
|
@@ -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,20 +1,25 @@
|
|
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';
|
7
|
+
import { pageIdentifierToPageComponent } from './page_to_page_mapping';
|
8
|
+
import { buildStore } from './store'
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
10
|
+
class Application extends ApplicationBase {
|
11
|
+
mapping() {
|
12
|
+
return pageIdentifierToPageComponent;
|
13
|
+
}
|
14
|
+
|
15
|
+
visitAndRemote(navRef, store) {
|
16
|
+
return buildVisitAndRemote(navRef, store);
|
17
|
+
}
|
18
|
+
|
19
|
+
buildStore(initialState, { superglue, pages}) {
|
20
|
+
return buildStore(initialState, superglue, pages);
|
21
|
+
}
|
22
|
+
}
|
18
23
|
|
19
24
|
if (typeof window !== "undefined") {
|
20
25
|
document.addEventListener("DOMContentLoaded", function () {
|
@@ -22,7 +27,8 @@ if (typeof window !== "undefined") {
|
|
22
27
|
const location = window.location;
|
23
28
|
|
24
29
|
if (appEl) {
|
25
|
-
|
30
|
+
const root = createRoot(appEl);
|
31
|
+
root.render(
|
26
32
|
<Application
|
27
33
|
appEl={appEl}
|
28
34
|
// The base url prefixed to all calls made by the `visit`
|
@@ -33,43 +39,10 @@ if (typeof window !== "undefined") {
|
|
33
39
|
initialPage={window.SUPERGLUE_INITIAL_PAGE_STATE}
|
34
40
|
// The initial path of the page, e.g., /foobar
|
35
41
|
path={location.pathname + location.search + location.hash}
|
36
|
-
|
37
|
-
/>,
|
38
|
-
appEl
|
42
|
+
/>
|
39
43
|
);
|
40
44
|
}
|
41
45
|
});
|
42
46
|
}
|
43
47
|
|
44
|
-
export default class Application extends ApplicationBase {
|
45
|
-
mapping() {
|
46
|
-
return identifierToComponentMapping;
|
47
|
-
}
|
48
|
-
|
49
|
-
visitAndRemote(navRef, store) {
|
50
|
-
return buildVisitAndRemote(navRef, store);
|
51
|
-
}
|
52
48
|
|
53
|
-
buildStore(initialState, { superglue: superglueReducer, pages: pagesReducer }) {
|
54
|
-
// Create the store
|
55
|
-
// See `./reducer.js` for an explaination of the two included reducers
|
56
|
-
const composeEnhancers =
|
57
|
-
(this.hasWindow && window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__) ||
|
58
|
-
compose;
|
59
|
-
const reducer = reduceReducers(
|
60
|
-
combineReducers({
|
61
|
-
superglue: superglueReducer,
|
62
|
-
pages: reduceReducers(pagesReducer, applicationPagesReducer),
|
63
|
-
}),
|
64
|
-
applicationRootReducer
|
65
|
-
);
|
66
|
-
|
67
|
-
const store = createStore(
|
68
|
-
reducer,
|
69
|
-
initialState,
|
70
|
-
composeEnhancers(applyMiddleware(thunk, fragmentMiddleware))
|
71
|
-
);
|
72
|
-
|
73
|
-
return store;
|
74
|
-
}
|
75
|
-
}
|
@@ -7,11 +7,7 @@ end
|
|
7
7
|
json.component_identifier local_assigns[:virtual_path_of_template]
|
8
8
|
json.defers json.deferred!
|
9
9
|
json.fragments json.fragments!
|
10
|
-
json.assets [
|
11
|
-
# Uncomment for webpacker support
|
12
|
-
# asset_pack_path('application.js'),
|
13
|
-
asset_path('application.css')
|
14
|
-
]
|
10
|
+
json.assets [ asset_path('application.js') ]
|
15
11
|
|
16
12
|
if protect_against_forgery?
|
17
13
|
json.csrf_token form_authenticity_token
|
@@ -25,4 +21,7 @@ end
|
|
25
21
|
json.restore_strategy 'fromCacheAndRevisitInBackground'
|
26
22
|
|
27
23
|
json.rendered_at Time.now.to_i
|
28
|
-
|
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
|
+
})
|
@@ -1 +1 @@
|
|
1
|
-
require
|
1
|
+
require "props_template/core_ext"
|
@@ -0,0 +1,12 @@
|
|
1
|
+
// import your page component
|
2
|
+
// e.g import PostsEdit from '../views/posts/edit'
|
3
|
+
|
4
|
+
|
5
|
+
// Mapping between your props template to Component, you must add to this
|
6
|
+
// to register any new page level component you create. If you are using the
|
7
|
+
// scaffold, it will auto append the identifers for you.
|
8
|
+
//
|
9
|
+
// e.g {'posts/new': PostNew}
|
10
|
+
export const pageIdentifierToPageComponent = {
|
11
|
+
};
|
12
|
+
|
@@ -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
|
+
|