editus 1.0.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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +94 -0
- data/Rakefile +18 -0
- data/app/controllers/editus/application_controller.rb +51 -0
- data/app/controllers/editus/home_controller.rb +121 -0
- data/app/helpers/editus/application_helper.rb +4 -0
- data/app/helpers/editus/home_helper.rb +18 -0
- data/app/models/editus/application_record.rb +5 -0
- data/app/views/editus/home/index.html.erb +79 -0
- data/app/views/editus/home/manual_update.html.erb +91 -0
- data/app/views/editus/home/scripts.html.erb +50 -0
- data/app/views/editus/home/validate.html.erb +39 -0
- data/app/views/editus/supports/bug.html.erb +18 -0
- data/app/views/layouts/editus/application.html.erb +186 -0
- data/config/routes.rb +11 -0
- data/lib/editus/actions.rb +51 -0
- data/lib/editus/client.rb +31 -0
- data/lib/editus/cop.rb +43 -0
- data/lib/editus/definition_proxy.rb +7 -0
- data/lib/editus/engine.rb +14 -0
- data/lib/editus/file.rb +42 -0
- data/lib/editus/proxy.rb +64 -0
- data/lib/editus/script.rb +77 -0
- data/lib/editus/version.rb +11 -0
- data/lib/editus.rb +109 -0
- data/lib/tasks/editus_tasks.rake +15 -0
- metadata +105 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 3cec41e8e70a12bb3dd860f31729437bad4870ff201eb3a4892be778fdcf8558
|
4
|
+
data.tar.gz: 76b985c2519cb34198be4ce940128f1dd6265347e3ea48ec1cb1ceb5335b6028
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e705129944f1362d82e5dc9d749547ffd4ec0d59a4d315a0b90149f843f073f4dde0522ff3ec997b7d45c29b23780df1e4a56e94ac7a239b16e087c776e1a5c4
|
7
|
+
data.tar.gz: 4b7d829b9c4df393a913f9b05eaebfa149c6953189ad413204e47e358409a8d1e35dfbbb0398d566686e31461729b64185e0d12a5566fe023d78733ea2fa14a8
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2023 hungkieu
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
# Editus
|
2
|
+
Simplify code execution and database editing. Intuitive web interface. Run code snippets, modify databases in real-time.
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
Add this line to your application's Gemfile:
|
6
|
+
|
7
|
+
```ruby
|
8
|
+
gem "editus", git: "https://github.com/muoihai-com/editus.git"
|
9
|
+
```
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
```bash
|
13
|
+
$ bundle install
|
14
|
+
```
|
15
|
+
|
16
|
+
Run the following code to create the config file:
|
17
|
+
|
18
|
+
```bash
|
19
|
+
rake editus:install # It will create file config/initializer/editus.rb
|
20
|
+
```
|
21
|
+
|
22
|
+
Add the following to your `config/routes.rb`:
|
23
|
+
|
24
|
+
```ruby
|
25
|
+
Rails.application.routes.draw do
|
26
|
+
mount Editus::Engine => "/updater" unless Rails.env.production?
|
27
|
+
...
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
## Usage
|
32
|
+
|
33
|
+
### Authentication
|
34
|
+
|
35
|
+
Editus supports two forms of authentication:
|
36
|
+
|
37
|
+
1. Define the `editus_account` method in `ApplicationHelper`: This method should return the current account (e.g., `current_user` or `current_admin`). If this method is defined, Editus will use it to determine the current account.
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
module ApplicationHelper
|
41
|
+
def editus_account
|
42
|
+
current_user # or any other method that returns the current account
|
43
|
+
end
|
44
|
+
end
|
45
|
+
```
|
46
|
+
|
47
|
+
2. Configuration in the config/initializer/editus.rb file: Create an array containing accounts authenticated via HTTP Basic Authentication. Each account is a sub-array with two elements: the username and password.
|
48
|
+
|
49
|
+
```ruby
|
50
|
+
config.auth = [%w[user@example.com Pass@123456], %w[manager@example.com Pass@123456]]
|
51
|
+
```
|
52
|
+
|
53
|
+
Use one of the above authentication methods to secure access to Editus. Note that the `editus_account` method will take precedence if both methods are provided.
|
54
|
+
|
55
|
+
### Models
|
56
|
+
|
57
|
+
Display a simple form interface that helps you update the fields of the selected model. The update will use `update_columns` so will ignore callback and validate
|
58
|
+
|
59
|
+
### Add Script
|
60
|
+
|
61
|
+
To execute existing code create a directory `config/editus` in your code
|
62
|
+
|
63
|
+
Example:
|
64
|
+
`config/editus/update_nick_name_user.rb`
|
65
|
+
|
66
|
+
```rb
|
67
|
+
Editus::Script.define :update_nick_name_user do
|
68
|
+
title "Update nick_name of user"
|
69
|
+
task :up do
|
70
|
+
user = User.find(1)
|
71
|
+
nick_name = user.nick_name
|
72
|
+
user.update_columns nick_name: "xatara"
|
73
|
+
|
74
|
+
[1, nick_name]
|
75
|
+
end
|
76
|
+
|
77
|
+
task :down do |id, nick_name|
|
78
|
+
User.find(id).update_columns(nick_name: nick_name)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
```
|
83
|
+
|
84
|
+
Make sure the filename and the defined name are the same. In the above code `title` to set the title of the code.
|
85
|
+
`task :up` is the code that will be executed when you run it.
|
86
|
+
`task :down` is the code that will be executed when you undo, if you don't need to undo you can skip it.
|
87
|
+
|
88
|
+
It can use the result returned from the `up` function to use as an input parameter
|
89
|
+
|
90
|
+
## Contributing
|
91
|
+
Contribution directions go here.
|
92
|
+
|
93
|
+
## License
|
94
|
+
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
|
3
|
+
APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
|
4
|
+
load "rails/tasks/engine.rake"
|
5
|
+
|
6
|
+
load "rails/tasks/statistics.rake"
|
7
|
+
|
8
|
+
require "bundler/gem_tasks"
|
9
|
+
|
10
|
+
require "rake/testtask"
|
11
|
+
|
12
|
+
Rake::TestTask.new(:test) do |t|
|
13
|
+
t.libs << 'test'
|
14
|
+
t.pattern = 'test/**/*_test.rb'
|
15
|
+
t.verbose = false
|
16
|
+
end
|
17
|
+
|
18
|
+
task default: :test
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Editus
|
2
|
+
class ApplicationController < ActionController::Base
|
3
|
+
prepend ::ApplicationHelper
|
4
|
+
|
5
|
+
before_action :authenticate!, :set_locale
|
6
|
+
|
7
|
+
rescue_from "StandardError" do |exception|
|
8
|
+
@exception = exception
|
9
|
+
|
10
|
+
render "editus/supports/bug"
|
11
|
+
end
|
12
|
+
|
13
|
+
def authenticate!
|
14
|
+
return if editus_auth_account.present?
|
15
|
+
return head 401 if editus_account_needed?
|
16
|
+
return if authenticate(Editus.configuration.auth)
|
17
|
+
|
18
|
+
request_http_basic_authentication
|
19
|
+
end
|
20
|
+
|
21
|
+
def authenticate auth_configs
|
22
|
+
return true if auth_configs.blank?
|
23
|
+
|
24
|
+
authenticate_with_http_basic do |u, p|
|
25
|
+
session[:basic_auth_account] = u if auth_configs.include?([u, p])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def set_locale
|
30
|
+
I18n.locale = :en
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def editus_account_needed?
|
36
|
+
::ApplicationHelper.method_defined?(:editus_account)
|
37
|
+
end
|
38
|
+
|
39
|
+
def editus_auth_account
|
40
|
+
if editus_account_needed?
|
41
|
+
editus_account if editus_account.is_a?(ActiveRecord::Base)
|
42
|
+
else
|
43
|
+
session[:basic_auth_account]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def request_account
|
48
|
+
editus_auth_account.try(:email) || session[:basic_auth_account] || request.remote_ip
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
require_dependency "editus/application_controller"
|
2
|
+
|
3
|
+
module Editus
|
4
|
+
class HomeController < ApplicationController
|
5
|
+
before_action :load_model, :load_record, :load_column
|
6
|
+
|
7
|
+
def index
|
8
|
+
@scripts = Editus::Script.all.values
|
9
|
+
@actions = Editus::Actions.all.reverse
|
10
|
+
end
|
11
|
+
|
12
|
+
def validate
|
13
|
+
@record.assign_attributes user_params
|
14
|
+
@changes = @record.changes.transform_values do |(from, to)|
|
15
|
+
"From #{from.nil? ? 'null' : from} to #{to}"
|
16
|
+
end
|
17
|
+
@validate_error_flag = !@record.valid?
|
18
|
+
@full_messages = @record.errors.full_messages
|
19
|
+
|
20
|
+
render "validate"
|
21
|
+
end
|
22
|
+
|
23
|
+
def update
|
24
|
+
@record.assign_attributes user_params
|
25
|
+
return redirect_to(root_path) unless @record.changed?
|
26
|
+
|
27
|
+
action = Editus::Action.new
|
28
|
+
action.changes = @record.changes
|
29
|
+
action.type = "models"
|
30
|
+
action.user = request_account
|
31
|
+
action.model_id = @record.id
|
32
|
+
action.model_name = @record.klass.class.name
|
33
|
+
action.save
|
34
|
+
@record.update_columns user_params
|
35
|
+
|
36
|
+
redirect_to root_path
|
37
|
+
end
|
38
|
+
|
39
|
+
def manual_update
|
40
|
+
@model_names = Editus::Client.models
|
41
|
+
end
|
42
|
+
|
43
|
+
def scripts
|
44
|
+
@scripts = Editus::Script.all.values
|
45
|
+
end
|
46
|
+
|
47
|
+
def run_script
|
48
|
+
script = Editus::Script.all[params[:id].to_sym]
|
49
|
+
return redirect_to(root_path) if script.blank?
|
50
|
+
|
51
|
+
action = Editus::Action.new
|
52
|
+
action.type = "scripts"
|
53
|
+
action.user = request_account
|
54
|
+
action.model_id = script.name
|
55
|
+
action.model_name = script.title
|
56
|
+
action.changes = script.proxy.up if script.proxy.respond_to?(:up)
|
57
|
+
action.save
|
58
|
+
|
59
|
+
redirect_to root_path
|
60
|
+
end
|
61
|
+
|
62
|
+
def undo
|
63
|
+
action = Editus::Actions.all.find{|act| act.id == params[:id]}
|
64
|
+
return redirect_to(root_path) if action.blank?
|
65
|
+
|
66
|
+
new_action = Editus::Action.new
|
67
|
+
new_action.type = "undo"
|
68
|
+
new_action.user = request_account
|
69
|
+
new_action.model_id = action.id
|
70
|
+
new_action.model_name = action.model_name
|
71
|
+
case action.type
|
72
|
+
when "models"
|
73
|
+
pr = action.changes.transform_values{|(from, _to)| from}
|
74
|
+
record = action.model_name.constantize.find(action.model_id)
|
75
|
+
record.assign_attributes pr
|
76
|
+
new_action.changes = record.changes
|
77
|
+
record.update_columns pr
|
78
|
+
when "scripts"
|
79
|
+
script = Editus::Script.all[action.model_id.to_sym]
|
80
|
+
return redirect_to(root_path) if action.blank?
|
81
|
+
|
82
|
+
if script.proxy.respond_to?(:down)
|
83
|
+
action.changes.empty? ? script.proxy.down : script.proxy.down(*action.changes)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
new_action.save
|
87
|
+
|
88
|
+
redirect_to root_path
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def load_model
|
94
|
+
return if params[:klass].blank?
|
95
|
+
|
96
|
+
@proxy = Editus::Client.model(params[:klass])
|
97
|
+
return if @proxy.blank?
|
98
|
+
|
99
|
+
@column_names = @proxy.column_names
|
100
|
+
rescue NameError
|
101
|
+
redirect_to manual_update_path
|
102
|
+
end
|
103
|
+
|
104
|
+
def load_record
|
105
|
+
return if @proxy.blank? || params[:attribute].blank? || params[:value].blank?
|
106
|
+
|
107
|
+
@record = @proxy.find_by(params[:attribute] => params[:value])
|
108
|
+
end
|
109
|
+
|
110
|
+
def load_column
|
111
|
+
return if params[:column].blank? || @record.try(params[:column]).blank?
|
112
|
+
|
113
|
+
@update_value = @record.try(params[:column])
|
114
|
+
end
|
115
|
+
|
116
|
+
def user_params
|
117
|
+
params[:user]&.each{|key, _| params[:user].delete(key) if params[:user][key].blank?}
|
118
|
+
(params[:user] || {}).as_json
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Editus
|
2
|
+
module HomeHelper
|
3
|
+
def path_active? path
|
4
|
+
request.original_url.include?(path)
|
5
|
+
end
|
6
|
+
|
7
|
+
def field_tag record, col, *args
|
8
|
+
if record.try(col).is_a?(Time)
|
9
|
+
text_field_tag(*args, placeholder: "YYYY-MM-DD HH:mm:ss UTC")
|
10
|
+
elsif [true, false].include? record.try(col)
|
11
|
+
safe_join [hidden_field_tag(args.first, "false", id: nil),
|
12
|
+
check_box_tag(args.first, "true", record.try(col))]
|
13
|
+
else
|
14
|
+
text_field_tag(*args)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
<div class="ui main text container">
|
2
|
+
<h1 class="ui header">Scripts</h1>
|
3
|
+
|
4
|
+
<% if @scripts.blank? %>
|
5
|
+
<div class="ui placeholder segment">
|
6
|
+
<div class="ui icon header">
|
7
|
+
<i class="file code outline icon"></i>
|
8
|
+
No scripts are listed.
|
9
|
+
</div>
|
10
|
+
<%= link_to 'https://github.com/muoihai-com/editus#add-script', target: "_blank" do %>
|
11
|
+
<div class="ui primary button">
|
12
|
+
Tutorial - Add Script
|
13
|
+
</div>
|
14
|
+
<% end %>
|
15
|
+
</div>
|
16
|
+
<% else %>
|
17
|
+
<div class="ui relaxed divided list">
|
18
|
+
<% @scripts.each do |script| %>
|
19
|
+
<div class="item">
|
20
|
+
<div class="content">
|
21
|
+
<%= link_to "#{scripts_path}##{script.name}", class: "header" do %>
|
22
|
+
<div class="ui horizontal label">#<%= script.name %></div>
|
23
|
+
<%= script.title %>
|
24
|
+
<% end %>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
<% end %>
|
28
|
+
</div>
|
29
|
+
<% end %>
|
30
|
+
|
31
|
+
<h1 class="ui header">Histories</h1>
|
32
|
+
<div class="ui cards flex-column">
|
33
|
+
<% if @actions.blank? %>
|
34
|
+
<div class="ui placeholder segment">
|
35
|
+
<div class="ui icon header">
|
36
|
+
<i class="calendar alternate outline icon"></i>
|
37
|
+
No action has been taken yet
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
<% else %>
|
41
|
+
<% @actions.each do |action| %>
|
42
|
+
<div class="ui card w-full" id="action-<%= action.id %>">
|
43
|
+
<div class="content">
|
44
|
+
<div class="header"><%= action.user %></div>
|
45
|
+
<% if action.type == "models" %>
|
46
|
+
<div class="meta">updated <b><%= action.model_name %>#<%= action.model_id %></b> <%= time_ago_in_words(action.created_at) %> ago</div>
|
47
|
+
<% elsif action.type == "scripts"%>
|
48
|
+
<div class="meta">used script <b><%= link_to action.model_name, "#{scripts_path}##{action.model_id}" %></b> <%= time_ago_in_words(action.created_at) %> ago</div>
|
49
|
+
<% elsif action.type == "undo"%>
|
50
|
+
<div class="meta">undo action <b><%= link_to action.model_id, "##{action.model_id}", class: "action" %></b> <%= time_ago_in_words(action.created_at) %> ago</div>
|
51
|
+
<% end %>
|
52
|
+
<div class="description">
|
53
|
+
<% if (action.type == "models" || action.type == "undo") && action.changes %>
|
54
|
+
<pre class="bg-neutral-300 rounded p-4">
|
55
|
+
<%= action.changes.transform_values{|(from, to)| "From #{from.nil? ? 'null' : from} to #{to}"} %>
|
56
|
+
</pre>
|
57
|
+
<% elsif action.type == "scripts" && action.changes %>
|
58
|
+
<pre class="bg-neutral-300 rounded p-4">
|
59
|
+
<%= action.changes %>
|
60
|
+
</pre>
|
61
|
+
<% end %>
|
62
|
+
</div>
|
63
|
+
</div>
|
64
|
+
<% if action.type != "undo" %>
|
65
|
+
<div class="extra content">
|
66
|
+
<button class="ui labeled icon button red confirmation" data-method="undo" data-id="<%= action.id %>">
|
67
|
+
<i class="undo icon"></i>
|
68
|
+
Undo
|
69
|
+
</button>
|
70
|
+
|
71
|
+
<%= form_tag undo_path(id: action.id), method: :post, id: action.id do %>
|
72
|
+
<% end %>
|
73
|
+
</div>
|
74
|
+
<% end %>
|
75
|
+
</div>
|
76
|
+
<% end %>
|
77
|
+
<% end %>
|
78
|
+
</div>
|
79
|
+
</div>
|
@@ -0,0 +1,91 @@
|
|
1
|
+
<div class="ui main text container">
|
2
|
+
<h1 class="ui header">Models</h1>
|
3
|
+
</div>
|
4
|
+
|
5
|
+
<%= form_tag validate_path, class: 'ui form warning' do %>
|
6
|
+
<div class="ui mt-4 text container">
|
7
|
+
<p>
|
8
|
+
<%= select_tag "klass", options_for_select(@model_names.sort, params[:klass]), prompt: "Select a model", id: 'select-klass' %>
|
9
|
+
</p>
|
10
|
+
|
11
|
+
<% if params[:klass].present? %>
|
12
|
+
<p>
|
13
|
+
find by <%= text_field_tag "attribute", params[:attribute] || 'id', placeholder: "Id, Email,..." %>
|
14
|
+
</p>
|
15
|
+
<p>
|
16
|
+
with value <%= text_field_tag "value", params[:value], placeholder: "value..." %>
|
17
|
+
</p>
|
18
|
+
<p>
|
19
|
+
<button class="ui button blue" id="find">Find</button>
|
20
|
+
</p>
|
21
|
+
<% end %>
|
22
|
+
</div>
|
23
|
+
<% if @record.present? %>
|
24
|
+
<div class="ui mt-4 px-4 container">
|
25
|
+
<table class="ui celled table">
|
26
|
+
<thead>
|
27
|
+
<tr>
|
28
|
+
<th>Attribute</th>
|
29
|
+
<th>Value</th>
|
30
|
+
<th>Update</th>
|
31
|
+
</tr>
|
32
|
+
</thead>
|
33
|
+
<tbody>
|
34
|
+
<% @column_names.each do |col| %>
|
35
|
+
<tr>
|
36
|
+
<td><%= col %></td>
|
37
|
+
<td class="w-3/5"><%= @record.try(col) %></td>
|
38
|
+
<td>
|
39
|
+
<% if [true, false].include? @record.try(col) %>
|
40
|
+
<%= label_tag "user[#{col}]", class: "flex items-center" do %>
|
41
|
+
<%= field_tag @record, col, "user[#{col}]", nil %><span class="ml-2">True</span>
|
42
|
+
<% end %>
|
43
|
+
<% else %>
|
44
|
+
<%= field_tag @record, col, "user[#{col}]", nil %>
|
45
|
+
<% end %>
|
46
|
+
</td>
|
47
|
+
</tr>
|
48
|
+
<% end %>
|
49
|
+
</tbody>
|
50
|
+
</table>
|
51
|
+
</div>
|
52
|
+
|
53
|
+
<div class="ui mt-4 mb-4 text container">
|
54
|
+
<%= submit_tag "Validate", class: "ui button blue" %>
|
55
|
+
</div>
|
56
|
+
|
57
|
+
<% elsif params[:klass] && params[:attribute] && params[:value] %>
|
58
|
+
<div class="ui mt-4 text container">
|
59
|
+
<div class="ui warning message">
|
60
|
+
<i class="warning icon"></i>
|
61
|
+
Record Not Found
|
62
|
+
</div>
|
63
|
+
</div>
|
64
|
+
<% end %>
|
65
|
+
<% end %>
|
66
|
+
|
67
|
+
<script>
|
68
|
+
function selectClassChange(e) {
|
69
|
+
const value = e.target.value
|
70
|
+
|
71
|
+
window.location.href = `${window.location.origin}${window.location.pathname}?klass=${value}`
|
72
|
+
}
|
73
|
+
|
74
|
+
function findBy(e) {
|
75
|
+
e.preventDefault()
|
76
|
+
|
77
|
+
const attribute = document.getElementById('attribute').value
|
78
|
+
const value = document.getElementById('value').value
|
79
|
+
|
80
|
+
const search = new URLSearchParams()
|
81
|
+
search.set('klass', '<%= params[:klass] %>')
|
82
|
+
search.set('attribute', attribute)
|
83
|
+
search.set('value', value)
|
84
|
+
window.location.href = `${window.location.origin}${window.location.pathname}?${search}`
|
85
|
+
}
|
86
|
+
|
87
|
+
document.addEventListener('DOMContentLoaded', function(event) {
|
88
|
+
document.getElementById('select-klass').addEventListener('change', selectClassChange)
|
89
|
+
document.getElementById('find').addEventListener('click', findBy)
|
90
|
+
});
|
91
|
+
</script>
|
@@ -0,0 +1,50 @@
|
|
1
|
+
<div class="ui main text container">
|
2
|
+
<h1 class="ui header">Scripts</h1>
|
3
|
+
|
4
|
+
<% if @scripts.blank? %>
|
5
|
+
<div class="ui placeholder segment">
|
6
|
+
<div class="ui icon header">
|
7
|
+
<i class="file code outline icon"></i>
|
8
|
+
No scripts are listed.
|
9
|
+
</div>
|
10
|
+
<%= link_to 'https://github.com/muoihai-com/editus#add-script', target: "_blank" do %>
|
11
|
+
<div class="ui primary button">
|
12
|
+
Tutorial - Add Script
|
13
|
+
</div>
|
14
|
+
<% end %>
|
15
|
+
</div>
|
16
|
+
<% end %>
|
17
|
+
|
18
|
+
<% @scripts.each do |script| %>
|
19
|
+
<section id="<%= script.name %>">
|
20
|
+
<h1 class="ui header"><%= script.title %></h1>
|
21
|
+
<div>
|
22
|
+
<button class="ui labeled mini icon red button confirmation" data-method="run">
|
23
|
+
<i class="plus icon"></i>
|
24
|
+
Run
|
25
|
+
</button>
|
26
|
+
|
27
|
+
<%= form_tag run_path(id: script.name), method: :post, id: "run" do %>
|
28
|
+
<% end %>
|
29
|
+
</div>
|
30
|
+
<div class="ui accordion">
|
31
|
+
<div class="title">
|
32
|
+
<i class="dropdown icon"></i>
|
33
|
+
Up
|
34
|
+
</div>
|
35
|
+
<div class="content">
|
36
|
+
<div class="transition hidden">
|
37
|
+
<div class="editor"><%= script.up %></div>
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
<div class="title">
|
41
|
+
<i class="dropdown icon"></i>
|
42
|
+
Down
|
43
|
+
</div>
|
44
|
+
<div class="content">
|
45
|
+
<div class="editor"><%= script.down %></div>
|
46
|
+
</div>
|
47
|
+
</section>
|
48
|
+
<div class="ui divider"></div>
|
49
|
+
<% end %>
|
50
|
+
</div>
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<div class="ui main text container">
|
2
|
+
You have made the following changes:
|
3
|
+
<pre class="bg-neutral-300 rounded p-4">
|
4
|
+
<%= @changes %>
|
5
|
+
</pre>
|
6
|
+
|
7
|
+
<div class="ui warning message">
|
8
|
+
<div class="header">
|
9
|
+
<%= "Verify that these changes are #{@validate_error_flag ? "invalid" : "valid"}." %>
|
10
|
+
</div>
|
11
|
+
<% if @full_messages.present? %>
|
12
|
+
<pre class="bg-neutral-300 rounded p-4 mx-4">
|
13
|
+
<%= @full_messages.join("\n") %>
|
14
|
+
</pre>
|
15
|
+
<% end %>
|
16
|
+
|
17
|
+
Please be aware that: These updates will skip the validation of the record and may potentially cause data errors.
|
18
|
+
</div>
|
19
|
+
|
20
|
+
<%= form_tag update_path, class: 'pure-form' do %>
|
21
|
+
<%= hidden_field_tag "klass", @record.klass.class %>
|
22
|
+
<%= hidden_field_tag "attribute", 'id' %>
|
23
|
+
<%= hidden_field_tag "value", @record.id %>
|
24
|
+
<% @column_names.each do |col| %>
|
25
|
+
<% next unless @record.try("#{col}_changed?") %>
|
26
|
+
|
27
|
+
<%= hidden_field_tag "user[#{col}]", @record.try(col) %>
|
28
|
+
<% end %>
|
29
|
+
|
30
|
+
<div class="ui buttons">
|
31
|
+
<%= link_to manual_update_path, class: "ui button" do %>
|
32
|
+
Back
|
33
|
+
<% end %>
|
34
|
+
<div class="or"></div>
|
35
|
+
|
36
|
+
<%= submit_tag "Save", class: "ui button red" %>
|
37
|
+
</div>
|
38
|
+
<% end %>
|
39
|
+
</div>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<div class="ui text main container">
|
2
|
+
<h1 class="ui center aligned icon header">
|
3
|
+
<i class="circular inverted bug icon"></i>
|
4
|
+
Server Error
|
5
|
+
</h1>
|
6
|
+
|
7
|
+
<div class="ui negative message">
|
8
|
+
<div class="header">
|
9
|
+
<%= @exception.class %> - <%= @exception.message %>
|
10
|
+
</div>
|
11
|
+
<p class="break-words">
|
12
|
+
<%= @exception.backtrace.first(10).join("\n") %>
|
13
|
+
</p>
|
14
|
+
</div>
|
15
|
+
|
16
|
+
<div style="height: 2rem;" />
|
17
|
+
</div>
|
18
|
+
|