hotsheet 0.1.0 → 0.2.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/LICENSE +1 -1
- data/README.md +32 -35
- data/app/assets/hotsheet.css +1 -0
- data/app/assets/hotsheet.js +33 -0
- data/app/controllers/hotsheet/application_controller.rb +2 -4
- data/app/controllers/hotsheet/sheets_controller.rb +47 -0
- data/app/helpers/hotsheet/application_helper.rb +3 -3
- data/app/views/hotsheet/shared/_nav.html.erb +14 -0
- data/app/views/hotsheet/sheets/error.html.erb +1 -0
- data/app/views/hotsheet/sheets/index.html.erb +20 -0
- data/app/views/hotsheet/sheets/root.html.erb +1 -0
- data/app/views/layouts/hotsheet/application.html.erb +7 -7
- data/config/routes.rb +6 -5
- data/lib/generators/templates/hotsheet.rb +7 -4
- data/lib/hotsheet/column.rb +31 -0
- data/lib/hotsheet/config.rb +29 -0
- data/lib/hotsheet/engine.rb +5 -4
- data/lib/hotsheet/sheet.rb +44 -0
- data/lib/hotsheet/version.rb +1 -1
- data/lib/hotsheet.rb +38 -11
- metadata +17 -89
- data/CHANGELOG.md +0 -17
- data/app/assets/config/hotsheet.js +0 -2
- data/app/assets/javascripts/hotsheet/application.js +0 -1
- data/app/assets/javascripts/hotsheet/channels/consumer.js +0 -3
- data/app/assets/javascripts/hotsheet/channels/inline_edit_channel.js +0 -3
- data/app/assets/javascripts/hotsheet/controllers/application.js +0 -6
- data/app/assets/javascripts/hotsheet/controllers/editable_attribute_controller.js +0 -51
- data/app/assets/stylesheets/hotsheet/application.css +0 -86
- data/app/channels/application_cable/channel.rb +0 -6
- data/app/channels/application_cable/connection.rb +0 -6
- data/app/channels/inline_edit_channel.rb +0 -9
- data/app/controllers/hotsheet/pages_controller.rb +0 -43
- data/app/views/hotsheet/pages/_editable_attribute.html.erb +0 -24
- data/app/views/hotsheet/pages/index.html.erb +0 -27
- data/app/views/layouts/hotsheet/_flash.html.erb +0 -7
- data/app/views/layouts/hotsheet/_sidebar.html.erb +0 -11
- data/config/initializers/hotsheet/content_security_policy.rb +0 -14
- data/config/initializers/hotsheet/editable_attributes.rb +0 -43
- data/config/initializers/hotsheet/pagy.rb +0 -7
- data/config/locales/en.yml +0 -5
- data/lib/hotsheet/configuration.rb +0 -19
- data/vendor/assets/stylesheets/hotsheet/pagy.css +0 -37
@@ -0,0 +1 @@
|
|
1
|
+
<h1><%= Hotsheet.t "title" %></h1>
|
@@ -1,21 +1,21 @@
|
|
1
1
|
<!DOCTYPE html>
|
2
2
|
<html lang="<%= I18n.locale %>">
|
3
3
|
<head>
|
4
|
-
<title
|
4
|
+
<title><%= Hotsheet.t "title" %></title>
|
5
5
|
<meta charset="utf-8">
|
6
6
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
7
7
|
<meta name="robots" content="noindex,nofollow">
|
8
8
|
<meta name="turbo-prefetch" content="false">
|
9
|
+
<meta name="turbo-refresh-method" content="morph">
|
10
|
+
<meta name="turbo-refresh-scroll" content="preserve">
|
9
11
|
<%= csrf_meta_tags %>
|
10
|
-
<%=
|
11
|
-
<%=
|
12
|
-
<%= javascript_include_tag "hotsheet/application", "data-turbolinks-track": :reload,
|
13
|
-
type: :module, nonce: content_security_policy_nonce, defer: true %>
|
12
|
+
<%= stylesheet_link_tag "hotsheet", nonce: true %>
|
13
|
+
<%= javascript_include_tag "hotsheet", nonce: true, defer: true %>
|
14
14
|
</head>
|
15
15
|
<body>
|
16
|
-
<%= render "
|
17
|
-
<%= render "layouts/hotsheet/flash" %>
|
16
|
+
<%= render "hotsheet/shared/nav" %>
|
18
17
|
<main>
|
18
|
+
<div class="flash"></div>
|
19
19
|
<%= yield %>
|
20
20
|
</main>
|
21
21
|
</body>
|
data/config/routes.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
Hotsheet::Engine.routes.draw do
|
4
|
-
|
4
|
+
next unless defined? Rails::Server
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
Hotsheet.models.each do |model|
|
9
|
-
resources model.table_name, controller: :pages, only: %i[index update], model: model.name
|
6
|
+
Hotsheet.sheets.each_key do |sheet_name|
|
7
|
+
resources sheet_name, sheet_name:, controller: :sheets, only: %i[index update]
|
10
8
|
end
|
9
|
+
|
10
|
+
root "sheets#root"
|
11
|
+
match "*path", to: "sheets#error", via: :all
|
11
12
|
end
|
@@ -1,9 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
Hotsheet.
|
4
|
-
|
3
|
+
# Configure the models to be used by Hotsheet.
|
4
|
+
# See https://github.com/renuo/hotsheet?tab=readme-ov-file#usage.
|
5
|
+
# The ID is included by default. It is always the first column.
|
5
6
|
|
6
|
-
|
7
|
-
#
|
7
|
+
Hotsheet.configure do
|
8
|
+
# sheet :User do
|
9
|
+
# column :name
|
10
|
+
# column :birthdate, editable: false
|
8
11
|
# end
|
9
12
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Hotsheet::Column
|
4
|
+
include Hotsheet::Config
|
5
|
+
|
6
|
+
attr_reader :config
|
7
|
+
|
8
|
+
CONFIG = {
|
9
|
+
editable: { allowed_classes: [FalseClass, Proc], default: true },
|
10
|
+
visible: { allowed_classes: [FalseClass, Proc], default: true }
|
11
|
+
}.freeze
|
12
|
+
|
13
|
+
def initialize(config)
|
14
|
+
@config = merge_config! CONFIG, config
|
15
|
+
end
|
16
|
+
|
17
|
+
def editable?
|
18
|
+
is? :editable
|
19
|
+
end
|
20
|
+
|
21
|
+
def visible?
|
22
|
+
is? :visible
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def is?(permission)
|
28
|
+
perm = @config[permission]
|
29
|
+
perm.is_a?(Proc) ? perm.call : perm
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Hotsheet::Config
|
4
|
+
def merge_config!(default, custom)
|
5
|
+
config = default.transform_values { |value| value[:default] }
|
6
|
+
|
7
|
+
custom.each do |key, value|
|
8
|
+
unless default.key? key
|
9
|
+
raise Hotsheet::Error, "Config must be one of #{default.keys}, got '#{key}'"
|
10
|
+
end
|
11
|
+
|
12
|
+
ensure_allowed_value! key, value, default[key]
|
13
|
+
config[key] = value
|
14
|
+
end
|
15
|
+
|
16
|
+
config
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def ensure_allowed_value!(key, value, config)
|
22
|
+
allowed = config[:allowed_classes]
|
23
|
+
value = value.class
|
24
|
+
|
25
|
+
return if allowed.include? value
|
26
|
+
|
27
|
+
raise Hotsheet::Error, "Config '#{key}' must be one of #{allowed}, got '#{value}'"
|
28
|
+
end
|
29
|
+
end
|
data/lib/hotsheet/engine.rb
CHANGED
@@ -1,9 +1,10 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
isolate_namespace Hotsheet
|
3
|
+
class Hotsheet::Engine < Rails::Engine
|
4
|
+
isolate_namespace Hotsheet
|
6
5
|
|
7
|
-
|
6
|
+
if config.respond_to? :assets
|
7
|
+
config.assets.paths << Hotsheet::Engine.root.join("app/assets")
|
8
|
+
config.assets.precompile << %w[hotsheet.css hotsheet.js]
|
8
9
|
end
|
9
10
|
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Hotsheet::Sheet
|
4
|
+
include Hotsheet::Config
|
5
|
+
|
6
|
+
CONFIG = {}.freeze
|
7
|
+
|
8
|
+
attr_reader :config, :model
|
9
|
+
|
10
|
+
def initialize(name, config, &columns)
|
11
|
+
@config = merge_config! CONFIG, config
|
12
|
+
@model = name.to_s.constantize
|
13
|
+
@columns = {}
|
14
|
+
|
15
|
+
column :id, editable: false
|
16
|
+
columns ? instance_eval(&columns) : use_default_configuration
|
17
|
+
end
|
18
|
+
|
19
|
+
def columns
|
20
|
+
@columns.select { |_name, column| column.visible? }
|
21
|
+
end
|
22
|
+
|
23
|
+
def cells_for(columns)
|
24
|
+
@model.pluck(*columns.keys).transpose
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def use_default_configuration
|
30
|
+
@model.column_names[1..].each { |name| column name }
|
31
|
+
end
|
32
|
+
|
33
|
+
def column(name, config = {})
|
34
|
+
ensure_column_exists! name
|
35
|
+
|
36
|
+
@columns[name.to_s] = Hotsheet::Column.new config
|
37
|
+
end
|
38
|
+
|
39
|
+
def ensure_column_exists!(name)
|
40
|
+
return if @model.column_names.include? name.to_s
|
41
|
+
|
42
|
+
raise Hotsheet::Error, "Column must be one of #{@model.column_names}, got '#{name}'"
|
43
|
+
end
|
44
|
+
end
|
data/lib/hotsheet/version.rb
CHANGED
data/lib/hotsheet.rb
CHANGED
@@ -1,26 +1,53 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "sprockets/railtie"
|
4
|
-
require "turbo-rails"
|
5
|
-
|
6
|
-
require "hotsheet/configuration"
|
7
|
-
require "hotsheet/engine"
|
8
3
|
require "hotsheet/version"
|
4
|
+
require "hotsheet/engine"
|
5
|
+
require "hotsheet/config"
|
6
|
+
require "hotsheet/sheet"
|
7
|
+
require "hotsheet/column"
|
9
8
|
|
10
9
|
module Hotsheet
|
11
10
|
class Error < StandardError; end
|
12
11
|
|
13
12
|
class << self
|
14
|
-
|
15
|
-
|
13
|
+
include Config
|
14
|
+
|
15
|
+
CONFIG = {}.freeze
|
16
|
+
|
17
|
+
attr_reader :config
|
18
|
+
|
19
|
+
def configure(config = {}, &sheets)
|
20
|
+
@config = [merge_config!(CONFIG, config), sheets]
|
21
|
+
self
|
16
22
|
end
|
17
23
|
|
18
|
-
def
|
19
|
-
|
24
|
+
def sheets
|
25
|
+
@sheets ||= begin
|
26
|
+
@sheets = {}
|
27
|
+
instance_eval(&@config.pop)
|
28
|
+
@sheets
|
29
|
+
end
|
20
30
|
end
|
21
31
|
|
22
|
-
def
|
23
|
-
|
32
|
+
def t(key)
|
33
|
+
I18n.t key, scope: "hotsheet"
|
34
|
+
rescue I18n::MissingTranslationData
|
35
|
+
I18n.with_locale(:en) { I18n.t key, scope: "hotsheet" }
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def sheet(name, config = {}, &)
|
41
|
+
ensure_sheet_exists! name
|
42
|
+
|
43
|
+
sheet = Sheet.new(name, config, &)
|
44
|
+
@sheets[sheet.model.table_name] = sheet
|
45
|
+
end
|
46
|
+
|
47
|
+
def ensure_sheet_exists!(name)
|
48
|
+
return if Object.const_defined? name
|
49
|
+
|
50
|
+
raise Hotsheet::Error, "Unknown model '#{name}'"
|
24
51
|
end
|
25
52
|
end
|
26
53
|
end
|
metadata
CHANGED
@@ -1,14 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hotsheet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Renuo AG
|
8
|
-
autorequire:
|
9
8
|
bindir: bin
|
10
9
|
cert_chain: []
|
11
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
12
11
|
dependencies:
|
13
12
|
- !ruby/object:Gem::Dependency
|
14
13
|
name: rails
|
@@ -24,64 +23,7 @@ dependencies:
|
|
24
23
|
- - ">="
|
25
24
|
- !ruby/object:Gem::Version
|
26
25
|
version: 6.1.0
|
27
|
-
-
|
28
|
-
name: pagy
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :runtime
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: sprockets-rails
|
43
|
-
requirement: !ruby/object:Gem::Requirement
|
44
|
-
requirements:
|
45
|
-
- - ">="
|
46
|
-
- !ruby/object:Gem::Version
|
47
|
-
version: '0'
|
48
|
-
type: :runtime
|
49
|
-
prerelease: false
|
50
|
-
version_requirements: !ruby/object:Gem::Requirement
|
51
|
-
requirements:
|
52
|
-
- - ">="
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: '0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: stimulus-rails
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ">="
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :runtime
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ">="
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: turbo-rails
|
71
|
-
requirement: !ruby/object:Gem::Requirement
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
76
|
-
type: :runtime
|
77
|
-
prerelease: false
|
78
|
-
version_requirements: !ruby/object:Gem::Requirement
|
79
|
-
requirements:
|
80
|
-
- - ">="
|
81
|
-
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
83
|
-
description: This gem allows you to mount a view to manage your database using atable
|
84
|
-
view where you can edit DB records inline.
|
26
|
+
description: Manage your Rails database through a spreadsheet-like interface.
|
85
27
|
email:
|
86
28
|
- ignacio.sfeir@renuo.ch
|
87
29
|
- simon.isler@renuo.ch
|
@@ -91,49 +33,36 @@ executables: []
|
|
91
33
|
extensions: []
|
92
34
|
extra_rdoc_files: []
|
93
35
|
files:
|
94
|
-
- CHANGELOG.md
|
95
36
|
- LICENSE
|
96
37
|
- README.md
|
97
|
-
- app/assets/
|
98
|
-
- app/assets/
|
99
|
-
- app/assets/javascripts/hotsheet/channels/consumer.js
|
100
|
-
- app/assets/javascripts/hotsheet/channels/inline_edit_channel.js
|
101
|
-
- app/assets/javascripts/hotsheet/controllers/application.js
|
102
|
-
- app/assets/javascripts/hotsheet/controllers/editable_attribute_controller.js
|
103
|
-
- app/assets/stylesheets/hotsheet/application.css
|
104
|
-
- app/channels/application_cable/channel.rb
|
105
|
-
- app/channels/application_cable/connection.rb
|
106
|
-
- app/channels/inline_edit_channel.rb
|
38
|
+
- app/assets/hotsheet.css
|
39
|
+
- app/assets/hotsheet.js
|
107
40
|
- app/controllers/hotsheet/application_controller.rb
|
108
|
-
- app/controllers/hotsheet/
|
41
|
+
- app/controllers/hotsheet/sheets_controller.rb
|
109
42
|
- app/helpers/hotsheet/application_helper.rb
|
110
|
-
- app/views/hotsheet/
|
111
|
-
- app/views/hotsheet/
|
112
|
-
- app/views/
|
113
|
-
- app/views/
|
43
|
+
- app/views/hotsheet/shared/_nav.html.erb
|
44
|
+
- app/views/hotsheet/sheets/error.html.erb
|
45
|
+
- app/views/hotsheet/sheets/index.html.erb
|
46
|
+
- app/views/hotsheet/sheets/root.html.erb
|
114
47
|
- app/views/layouts/hotsheet/application.html.erb
|
115
|
-
- config/initializers/hotsheet/content_security_policy.rb
|
116
|
-
- config/initializers/hotsheet/editable_attributes.rb
|
117
|
-
- config/initializers/hotsheet/pagy.rb
|
118
|
-
- config/locales/en.yml
|
119
48
|
- config/routes.rb
|
120
49
|
- lib/generators/hotsheet/install_generator.rb
|
121
50
|
- lib/generators/templates/hotsheet.rb
|
122
51
|
- lib/hotsheet.rb
|
123
|
-
- lib/hotsheet/
|
52
|
+
- lib/hotsheet/column.rb
|
53
|
+
- lib/hotsheet/config.rb
|
124
54
|
- lib/hotsheet/engine.rb
|
55
|
+
- lib/hotsheet/sheet.rb
|
125
56
|
- lib/hotsheet/version.rb
|
126
|
-
- vendor/assets/stylesheets/hotsheet/pagy.css
|
127
57
|
homepage: https://github.com/renuo/hotsheet
|
128
58
|
licenses:
|
129
59
|
- MIT
|
130
60
|
metadata:
|
131
|
-
homepage_uri: https://github.com/renuo/hotsheet
|
132
61
|
source_code_uri: https://github.com/renuo/hotsheet
|
62
|
+
bug_tracker_uri: https://github.com/renuo/hotsheet/issues
|
133
63
|
changelog_uri: https://github.com/renuo/hotsheet/blob/main/CHANGELOG.md
|
134
64
|
documentation_uri: https://github.com/renuo/hotsheet/blob/main/README.md
|
135
65
|
rubygems_mfa_required: 'true'
|
136
|
-
post_install_message:
|
137
66
|
rdoc_options: []
|
138
67
|
require_paths:
|
139
68
|
- lib
|
@@ -141,15 +70,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
141
70
|
requirements:
|
142
71
|
- - ">="
|
143
72
|
- !ruby/object:Gem::Version
|
144
|
-
version: 3.
|
73
|
+
version: 3.1.0
|
145
74
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
146
75
|
requirements:
|
147
76
|
- - ">="
|
148
77
|
- !ruby/object:Gem::Version
|
149
78
|
version: '0'
|
150
79
|
requirements: []
|
151
|
-
rubygems_version: 3.
|
152
|
-
signing_key:
|
80
|
+
rubygems_version: 3.6.9
|
153
81
|
specification_version: 4
|
154
|
-
summary:
|
82
|
+
summary: Database GUI for Rails.
|
155
83
|
test_files: []
|
data/CHANGELOG.md
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
## [Unreleased](https://github.com/renuo/hotsheet/compare/v0.1.0..HEAD)
|
2
|
-
|
3
|
-
-
|
4
|
-
|
5
|
-
## [0.1.0](https://github.com/renuo/hotsheet/releases/tag/v0.1.0) (2024-11-05)
|
6
|
-
|
7
|
-
- Gem structure and initial configuration ([@ignaciosy])
|
8
|
-
- Inline editing table (([@simon-isler]) and ([@edmunteanu]))
|
9
|
-
- Dummy app for development and test ([@hunchr])
|
10
|
-
- Configuration for initializer, CI, lint, tests ([@hunchr])
|
11
|
-
- Generator `bin/rails g hotsheet:install` for copying initializer and mounting engine in routes ([@hunchr])
|
12
|
-
- Pagination for data tables ([@hunchr])
|
13
|
-
|
14
|
-
[@ignaciosy]: https://github.com/ignaciosy
|
15
|
-
[@hunchr]: https://github.com/hunchr
|
16
|
-
[@simon-isler]: https://github.com/simon-isler
|
17
|
-
[@edmunteanu]: https://github.com/edmunteanu
|
@@ -1 +0,0 @@
|
|
1
|
-
//= require ./controllers/application
|
@@ -1,6 +0,0 @@
|
|
1
|
-
import { Application } from "https://unpkg.com/@hotwired/stimulus/dist/stimulus.js"
|
2
|
-
import EditableAttributeController from "./controllers/editable_attribute_controller"
|
3
|
-
|
4
|
-
window.Stimulus = Application.start()
|
5
|
-
|
6
|
-
Stimulus.register("editable-attribute", EditableAttributeController)
|
@@ -1,51 +0,0 @@
|
|
1
|
-
import { Controller } from "https://unpkg.com/@hotwired/stimulus/dist/stimulus.js"
|
2
|
-
|
3
|
-
export default class extends Controller {
|
4
|
-
static values = {
|
5
|
-
broadcastUrl: String,
|
6
|
-
resourceName: String,
|
7
|
-
resourceId: Number,
|
8
|
-
}
|
9
|
-
|
10
|
-
static targets = ["readonlyAttribute", "attributeForm", "attributeFormInput"]
|
11
|
-
|
12
|
-
displayInputField() {
|
13
|
-
// this.broadcastEditIntent()
|
14
|
-
this.readonlyAttributeTarget.style.display = "none"
|
15
|
-
this.attributeFormTarget.style.display = "block"
|
16
|
-
this.attributeFormInputTarget.focus()
|
17
|
-
}
|
18
|
-
|
19
|
-
broadcastEditIntent() {
|
20
|
-
const headers = {
|
21
|
-
"Content-Type": "application/json",
|
22
|
-
"X-CSRF-Token": document.querySelector("meta[name=csrf-token]").content,
|
23
|
-
}
|
24
|
-
const body = JSON.stringify({
|
25
|
-
broadcast: {
|
26
|
-
resource_name: this.resourceNameValue,
|
27
|
-
resource_id: this.resourceIdValue,
|
28
|
-
},
|
29
|
-
})
|
30
|
-
|
31
|
-
fetch(this.broadcastUrlValue, { method: "POST", headers, body })
|
32
|
-
}
|
33
|
-
|
34
|
-
submitForm(event) {
|
35
|
-
// Prevent standard submission triggered by Enter press
|
36
|
-
event.preventDefault()
|
37
|
-
|
38
|
-
const previousValue = this.readonlyAttributeTarget.innerText.trim()
|
39
|
-
const newValue = this.attributeFormInputTarget.value
|
40
|
-
|
41
|
-
if (previousValue && previousValue === newValue) {
|
42
|
-
this.readonlyAttributeTarget.style.display = "block"
|
43
|
-
this.attributeFormTarget.style.display = "none"
|
44
|
-
return
|
45
|
-
}
|
46
|
-
|
47
|
-
// It's important to use requestSubmit() instead of simply submit() as the latter will circumvent the
|
48
|
-
// Turbo mechanism, causing the PATCH request to be submitted as HTML instead of TURBO_STREAM
|
49
|
-
this.attributeFormInputTarget.form.requestSubmit()
|
50
|
-
}
|
51
|
-
}
|
@@ -1,86 +0,0 @@
|
|
1
|
-
/*
|
2
|
-
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
-
* listed below.
|
4
|
-
*
|
5
|
-
*= require_tree .
|
6
|
-
*= require_self
|
7
|
-
*= require hotsheet/pagy
|
8
|
-
*/
|
9
|
-
|
10
|
-
:root {
|
11
|
-
--bg-color: lightgray;
|
12
|
-
--sidebar-width: 12rem;
|
13
|
-
}
|
14
|
-
|
15
|
-
body {
|
16
|
-
font: 400 16px system-ui, Roboto, Helvetica, Arial, sans-serif;
|
17
|
-
margin: 0;
|
18
|
-
}
|
19
|
-
|
20
|
-
main {
|
21
|
-
margin-left: var(--sidebar-width);
|
22
|
-
padding: 1rem;
|
23
|
-
}
|
24
|
-
|
25
|
-
aside {
|
26
|
-
background-color: var(--bg-color);
|
27
|
-
border-right: 1px solid gray;
|
28
|
-
height: 100%;
|
29
|
-
left: 0;
|
30
|
-
overflow-y: auto;
|
31
|
-
position: fixed;
|
32
|
-
top: 0;
|
33
|
-
width: var(--sidebar-width);
|
34
|
-
|
35
|
-
ul {
|
36
|
-
display: flex;
|
37
|
-
flex-direction: column;
|
38
|
-
margin: 0;
|
39
|
-
padding: 0.25rem;
|
40
|
-
|
41
|
-
a {
|
42
|
-
border-radius: 0.5rem;
|
43
|
-
color: green;
|
44
|
-
font-weight: 700;
|
45
|
-
overflow: hidden;
|
46
|
-
padding: 0.5rem;
|
47
|
-
text-decoration: none;
|
48
|
-
text-overflow: ellipsis;
|
49
|
-
white-space: nowrap;
|
50
|
-
|
51
|
-
&:hover {
|
52
|
-
background-color: darkgray;
|
53
|
-
}
|
54
|
-
}
|
55
|
-
}
|
56
|
-
}
|
57
|
-
|
58
|
-
h1 {
|
59
|
-
margin: 0 0 1rem 0;
|
60
|
-
}
|
61
|
-
|
62
|
-
table {
|
63
|
-
border-collapse: collapse;
|
64
|
-
|
65
|
-
th,
|
66
|
-
td {
|
67
|
-
border: 1px solid var(--bg-color);
|
68
|
-
padding: 0.5rem;
|
69
|
-
text-align: left;
|
70
|
-
}
|
71
|
-
|
72
|
-
th {
|
73
|
-
background-color: var(--bg-color);
|
74
|
-
}
|
75
|
-
|
76
|
-
.readonly-attribute {
|
77
|
-
min-height: 1rem;
|
78
|
-
min-width: 1rem;
|
79
|
-
}
|
80
|
-
|
81
|
-
.editable-input {
|
82
|
-
background-color: transparent;
|
83
|
-
border: none;
|
84
|
-
width: 100%;
|
85
|
-
}
|
86
|
-
}
|
@@ -1,43 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Hotsheet
|
4
|
-
class PagesController < ApplicationController
|
5
|
-
def index
|
6
|
-
@pagy, @records = pagy model.all if model
|
7
|
-
end
|
8
|
-
|
9
|
-
def broadcast_edit_intent
|
10
|
-
ActionCable.server.broadcast InlineEditChannel::STREAM_NAME, {
|
11
|
-
resource_name: broadcast_params[:resource_name],
|
12
|
-
resource_id: broadcast_params[:resource_id]
|
13
|
-
}
|
14
|
-
end
|
15
|
-
|
16
|
-
def update # rubocop:disable Metrics/AbcSize
|
17
|
-
record = model.find params[:id]
|
18
|
-
|
19
|
-
if record.update model_params
|
20
|
-
flash[:notice] = t("hotsheet.success", record: model.model_name.human)
|
21
|
-
else
|
22
|
-
flash[:alert] = t("hotsheet.error", record: model.model_name.human,
|
23
|
-
errors: record.errors.full_messages.join(", "))
|
24
|
-
end
|
25
|
-
|
26
|
-
redirect_to "#{root_path}#{model.table_name}"
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def broadcast_params
|
32
|
-
params.require(:broadcast).permit :resource_name, :resource_id
|
33
|
-
end
|
34
|
-
|
35
|
-
def model_params
|
36
|
-
params.require(model.name.underscore).permit(*model.editable_attributes)
|
37
|
-
end
|
38
|
-
|
39
|
-
def model
|
40
|
-
@model ||= params[:model]&.constantize
|
41
|
-
end
|
42
|
-
end
|
43
|
-
end
|