editus 1.0.0 → 1.1.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/README.md +56 -16
- data/app/controllers/editus/home_controller.rb +19 -1
- data/app/helpers/editus/home_helper.rb +19 -2
- data/app/views/editus/home/manual_update.html.erb +5 -1
- data/app/views/editus/home/scripts.html.erb +137 -13
- data/app/views/layouts/editus/application.html.erb +17 -5
- data/config/routes.rb +1 -1
- data/lib/editus/cop.rb +3 -3
- data/lib/editus/proxy.rb +9 -1
- data/lib/editus/script.rb +37 -1
- data/lib/editus/version.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 60b7c7adcfdb0b6d489e79e0bb946c2a19df3ec8642d6ad701a11400db7e581f
|
4
|
+
data.tar.gz: 10ca7886874f225e7b3ff73d51a3befeee3bc10f09a5f5d6324c535a841a5372
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 38dbd733e0865a021849d89bcdd8c896082956903bee8ac717d38c09fd9cf62b8f38c857a9fa3a53b3ee39d08d94eee2633e7d216617d7caa66807cc4ddaf417
|
7
|
+
data.tar.gz: 69e48942bbeb9289aff7e256c105dd794fa7ff5aea852d1ddb759122be18e1af41710e778bc4c174447632b6eb959426d1705779bd597dc1468f02dd5447dfe0
|
data/README.md
CHANGED
@@ -1,11 +1,30 @@
|
|
1
1
|
# Editus
|
2
|
-
Simplify code execution and database editing. Intuitive web interface. Run code snippets, modify databases in real-time.
|
3
2
|
|
4
|
-
|
3
|
+
[](https://badge.fury.io/rb/editus)
|
4
|
+
|
5
|
+
Streamline your coding and database editing processes with Editus. Its intuitive web interface allows you to execute code snippets and perform real-time database modifications with ease.
|
6
|
+
|
7
|
+
# Table of contents
|
8
|
+
|
9
|
+
- [Editus](#editus)
|
10
|
+
- [Table of contents](#table-of-contents)
|
11
|
+
- [Installation](#installation)
|
12
|
+
- [Usage](#usage)
|
13
|
+
* [Authentication](#authentication)
|
14
|
+
* [Models](#models)
|
15
|
+
* [Add Script](#add-script)
|
16
|
+
+ [Query](#query)
|
17
|
+
- [Contributing](#contributing)
|
18
|
+
- [License](#license)
|
19
|
+
|
20
|
+
<small><i><a href='http://ecotrust-canada.github.io/markdown-toc/'>Table of contents generated with markdown-toc</a></i></small>
|
21
|
+
|
22
|
+
|
23
|
+
# Installation
|
5
24
|
Add this line to your application's Gemfile:
|
6
25
|
|
7
26
|
```ruby
|
8
|
-
gem "editus"
|
27
|
+
gem "editus"
|
9
28
|
```
|
10
29
|
|
11
30
|
And then execute:
|
@@ -23,14 +42,14 @@ Add the following to your `config/routes.rb`:
|
|
23
42
|
|
24
43
|
```ruby
|
25
44
|
Rails.application.routes.draw do
|
26
|
-
mount Editus::Engine => "/
|
45
|
+
mount Editus::Engine => "/editus" unless Rails.env.production?
|
27
46
|
...
|
28
47
|
end
|
29
48
|
```
|
30
49
|
|
31
|
-
|
50
|
+
# Usage
|
32
51
|
|
33
|
-
|
52
|
+
## Authentication
|
34
53
|
|
35
54
|
Editus supports two forms of authentication:
|
36
55
|
|
@@ -52,11 +71,19 @@ config.auth = [%w[user@example.com Pass@123456], %w[manager@example.com Pass@123
|
|
52
71
|
|
53
72
|
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
73
|
|
55
|
-
|
74
|
+
## Models
|
56
75
|
|
57
76
|
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
77
|
|
59
|
-
|
78
|
+
You can configure to display only the models and fields that you allow:
|
79
|
+
|
80
|
+
```
|
81
|
+
config.models = ["User", {name: "Admin", fields: %w[name], exclude_fields: %w[id]}]
|
82
|
+
```
|
83
|
+
|
84
|
+
For the `Admin` model specified using the fields key. Additionally, the exclude_fields key is used to exclude the `id` field from being displayed.
|
85
|
+
|
86
|
+
## Add Script
|
60
87
|
|
61
88
|
To execute existing code create a directory `config/editus` in your code
|
62
89
|
|
@@ -66,12 +93,12 @@ Example:
|
|
66
93
|
```rb
|
67
94
|
Editus::Script.define :update_nick_name_user do
|
68
95
|
title "Update nick_name of user"
|
69
|
-
task :up do
|
70
|
-
user = User.find(
|
71
|
-
|
72
|
-
user.update_columns nick_name:
|
96
|
+
task :up do |id, new_nick_name|
|
97
|
+
user = User.find(id)
|
98
|
+
old_nick_name = user.nick_name
|
99
|
+
user.update_columns nick_name: new_nick_name
|
73
100
|
|
74
|
-
[
|
101
|
+
[id, old_nick_name]
|
75
102
|
end
|
76
103
|
|
77
104
|
task :down do |id, nick_name|
|
@@ -85,10 +112,23 @@ Make sure the filename and the defined name are the same. In the above code `tit
|
|
85
112
|
`task :up` is the code that will be executed when you run it.
|
86
113
|
`task :down` is the code that will be executed when you undo, if you don't need to undo you can skip it.
|
87
114
|
|
88
|
-
It can use the result returned from the `up`
|
115
|
+
It can use the result returned from the `up` method to use as an input parameter. The `up` method can also accept parameters directly.
|
116
|
+
|
117
|
+
### Query
|
118
|
+
|
119
|
+
In addition to running the two tasks `up` and `down`, you can perform other small code snippets by using `query`.
|
120
|
+
|
121
|
+
```rb
|
122
|
+
Editus::Script.define :users do
|
123
|
+
desc "Number of users"
|
124
|
+
query :count_user do
|
125
|
+
User.count
|
126
|
+
end
|
127
|
+
end
|
128
|
+
```
|
89
129
|
|
90
|
-
|
130
|
+
# Contributing
|
91
131
|
Contribution directions go here.
|
92
132
|
|
93
|
-
|
133
|
+
# License
|
94
134
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -53,12 +53,26 @@ module Editus
|
|
53
53
|
action.user = request_account
|
54
54
|
action.model_id = script.name
|
55
55
|
action.model_name = script.title
|
56
|
-
action.changes = script.proxy.up if script.proxy.respond_to?(:up)
|
56
|
+
action.changes = script.proxy.up(*parameters) if script.proxy.respond_to?(:up)
|
57
57
|
action.save
|
58
58
|
|
59
59
|
redirect_to root_path
|
60
60
|
end
|
61
61
|
|
62
|
+
def query
|
63
|
+
script = Editus::Script.all[params[:id].to_sym]
|
64
|
+
method = params[:method].to_sym
|
65
|
+
return render json: {status: false, error: :script_not_found}, status: 200 if script.blank?
|
66
|
+
|
67
|
+
unless script.proxy.respond_to?(method)
|
68
|
+
return render json: {status: false, error: :undefined_method},
|
69
|
+
status: 200
|
70
|
+
end
|
71
|
+
|
72
|
+
result = script.proxy.try(method, *parameters)
|
73
|
+
render json: {status: true, data: result}, status: 200
|
74
|
+
end
|
75
|
+
|
62
76
|
def undo
|
63
77
|
action = Editus::Actions.all.find{|act| act.id == params[:id]}
|
64
78
|
return redirect_to(root_path) if action.blank?
|
@@ -117,5 +131,9 @@ module Editus
|
|
117
131
|
params[:user]&.each{|key, _| params[:user].delete(key) if params[:user][key].blank?}
|
118
132
|
(params[:user] || {}).as_json
|
119
133
|
end
|
134
|
+
|
135
|
+
def parameters
|
136
|
+
params[:parameters]&.values || []
|
137
|
+
end
|
120
138
|
end
|
121
139
|
end
|
@@ -5,14 +5,31 @@ module Editus
|
|
5
5
|
end
|
6
6
|
|
7
7
|
def field_tag record, col, *args
|
8
|
-
|
8
|
+
case record.type_of_col(col)
|
9
|
+
when :datetime
|
9
10
|
text_field_tag(*args, placeholder: "YYYY-MM-DD HH:mm:ss UTC")
|
10
|
-
|
11
|
+
when :boolean
|
11
12
|
safe_join [hidden_field_tag(args.first, "false", id: nil),
|
12
13
|
check_box_tag(args.first, "true", record.try(col))]
|
13
14
|
else
|
14
15
|
text_field_tag(*args)
|
15
16
|
end
|
16
17
|
end
|
18
|
+
|
19
|
+
def parameters proxy, method
|
20
|
+
return [] unless proxy.respond_to?(method)
|
21
|
+
|
22
|
+
proxy.method(method).parameters.filter_map do |(type, value)|
|
23
|
+
value if type.in?(%i[req opt])
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def field_enums? record, col
|
28
|
+
record.defined_enums.key?(col.to_s) && record.defined_enums[col].present?
|
29
|
+
end
|
30
|
+
|
31
|
+
def enums record, col
|
32
|
+
record.defined_enums[col].keys.join(", ")
|
33
|
+
end
|
17
34
|
end
|
18
35
|
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<h1 class="ui header">Models</h1>
|
3
3
|
</div>
|
4
4
|
|
5
|
-
<%= form_tag validate_path, class: 'ui form warning' do %>
|
5
|
+
<%= form_tag validate_path, class: 'ui form warning manual' do %>
|
6
6
|
<div class="ui mt-4 text container">
|
7
7
|
<p>
|
8
8
|
<%= select_tag "klass", options_for_select(@model_names.sort, params[:klass]), prompt: "Select a model", id: 'select-klass' %>
|
@@ -40,6 +40,10 @@
|
|
40
40
|
<%= label_tag "user[#{col}]", class: "flex items-center" do %>
|
41
41
|
<%= field_tag @record, col, "user[#{col}]", nil %><span class="ml-2">True</span>
|
42
42
|
<% end %>
|
43
|
+
<% elsif field_enums?(@record, col) %>
|
44
|
+
<div class="ui" data-tooltip="<%= enums(@record, col) %>" data-inverted="" data-variation="mini">
|
45
|
+
<%= field_tag @record, col, "user[#{col}]", nil %>
|
46
|
+
</div>
|
43
47
|
<% else %>
|
44
48
|
<%= field_tag @record, col, "user[#{col}]", nil %>
|
45
49
|
<% end %>
|
@@ -18,33 +18,157 @@
|
|
18
18
|
<% @scripts.each do |script| %>
|
19
19
|
<section id="<%= script.name %>">
|
20
20
|
<h1 class="ui header"><%= script.title %></h1>
|
21
|
-
|
22
|
-
<button class="ui labeled mini icon red button
|
21
|
+
<% if parameters(script.proxy, :up).present? %>
|
22
|
+
<button class="ui labeled mini icon red button parameters" data-name="<%= script.name %>">
|
23
23
|
<i class="plus icon"></i>
|
24
24
|
Run
|
25
25
|
</button>
|
26
|
+
<% end %>
|
26
27
|
|
27
|
-
|
28
|
-
|
28
|
+
<div class="ui parameters-<%= script.name %> small modal">
|
29
|
+
<div class="header">
|
30
|
+
<%= parameters(script.proxy, :up).present? ? "Parameters" : "Confirmation" %>
|
31
|
+
</div>
|
32
|
+
<div class="scrolling content">
|
33
|
+
<%= form_tag run_path(id: script.name), method: :post, id: "run-#{script.name}", class: 'ui form' do %>
|
34
|
+
<% parameters(script.proxy, :up).each do |key| %>
|
35
|
+
<div class="inline fields">
|
36
|
+
<div class="two wide field">
|
37
|
+
</div>
|
38
|
+
<div class="six wide field">
|
39
|
+
<label><%= key.to_s.capitalize %></label>
|
40
|
+
</div>
|
41
|
+
<div class="six wide field">
|
42
|
+
<%= text_field_tag "parameters[#{key}]", nil %>
|
43
|
+
</div>
|
44
|
+
</div>
|
45
|
+
<% end %>
|
46
|
+
<% end %>
|
47
|
+
|
48
|
+
<p class="<%= parameters(script.proxy, :up).present? ? "mt-8" : "" %>">
|
49
|
+
These changes may cause data errors, do you still want to continue?
|
50
|
+
</p>
|
51
|
+
</div>
|
52
|
+
<div class="actions">
|
53
|
+
<div class="ui cancel button">Cancel</div>
|
54
|
+
<div class="ui red ok button">OK</div>
|
55
|
+
</div>
|
29
56
|
</div>
|
30
57
|
<div class="ui accordion">
|
31
58
|
<div class="title">
|
32
59
|
<i class="dropdown icon"></i>
|
33
|
-
|
60
|
+
Content
|
34
61
|
</div>
|
35
62
|
<div class="content">
|
36
63
|
<div class="transition hidden">
|
37
|
-
<div class="editor"><%= script.
|
64
|
+
<div class="editor"><%= script.content %></div>
|
38
65
|
</div>
|
39
66
|
</div>
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
67
|
+
|
68
|
+
<% if script.queries.present? %>
|
69
|
+
<div class="title">
|
70
|
+
<i class="dropdown icon"></i>
|
71
|
+
Queries
|
72
|
+
</div>
|
73
|
+
<div class="content">
|
74
|
+
<div class="transition hidden">
|
75
|
+
<div class="ui middle aligned selection list">
|
76
|
+
<% script.queries.each_with_index do |query, index| %>
|
77
|
+
<% query_key = "#{script.name}-#{index}" %>
|
78
|
+
|
79
|
+
<div class="item flex items-center justify-space-between query" data-index="<%= query_key %>">
|
80
|
+
<div class="content">
|
81
|
+
<%= query[:description] %>
|
82
|
+
</div>
|
83
|
+
<div class="content">
|
84
|
+
<div class="ui mini icon primary button">
|
85
|
+
<i class="terminal icon"></i>
|
86
|
+
</div>
|
87
|
+
</div>
|
88
|
+
</div>
|
89
|
+
|
90
|
+
<div class="ui query_<%= query_key %> small modal">
|
91
|
+
<div class="header">
|
92
|
+
Query
|
93
|
+
</div>
|
94
|
+
<div class="scrolling content">
|
95
|
+
<%= form_tag query_path(id: script.name, method: query[:query_name]), method: :post, id: "query_form_#{query_key}", class: 'ui form' do %>
|
96
|
+
<% parameters(script.proxy, query[:query_name]).each do |key| %>
|
97
|
+
<div class="inline fields">
|
98
|
+
<div class="two wide field">
|
99
|
+
</div>
|
100
|
+
<div class="six wide field">
|
101
|
+
<label><%= key.to_s.capitalize %></label>
|
102
|
+
</div>
|
103
|
+
<div class="six wide field">
|
104
|
+
<%= text_field_tag "parameters[#{key}]", nil %>
|
105
|
+
</div>
|
106
|
+
</div>
|
107
|
+
<% end %>
|
108
|
+
<% end %>
|
109
|
+
|
110
|
+
<p class="<%= parameters(script.proxy, query[:query_name]).present? ? "mt-8" : "" %>">
|
111
|
+
These changes may cause data errors, do you still want to continue?
|
112
|
+
</p>
|
113
|
+
|
114
|
+
<button class="ui button primary" id="run_query_<%= query_key %>">
|
115
|
+
Query
|
116
|
+
</button>
|
117
|
+
|
118
|
+
<pre class="bg-neutral-300 rounded p-4" id="pre_query_<%= query_key %>" style="display: none;">
|
119
|
+
</pre>
|
120
|
+
</div>
|
121
|
+
<div class="actions">
|
122
|
+
<div class="ui cancel button">Close</div>
|
123
|
+
</div>
|
124
|
+
</div>
|
125
|
+
<% end %>
|
126
|
+
</div>
|
127
|
+
</div>
|
128
|
+
</div>
|
129
|
+
<% end %>
|
130
|
+
</div>
|
47
131
|
</section>
|
48
132
|
<div class="ui divider"></div>
|
49
133
|
<% end %>
|
50
134
|
</div>
|
135
|
+
|
136
|
+
<script>
|
137
|
+
$("button.parameters").on("click", function (e) {
|
138
|
+
const name = $(e.currentTarget).data('name')
|
139
|
+
|
140
|
+
$(`.ui.parameters-${name}.modal`)
|
141
|
+
.modal({
|
142
|
+
onApprove: function () {
|
143
|
+
$(`#run-${name}`).submit()
|
144
|
+
}
|
145
|
+
})
|
146
|
+
.modal("show");
|
147
|
+
});
|
148
|
+
|
149
|
+
$(".query").on("click", function (e) {
|
150
|
+
const index = $(e.currentTarget).data('index')
|
151
|
+
|
152
|
+
$(`.ui.query_${index}.modal`).modal("show");
|
153
|
+
$(`#run_query_${index}`).on("click", function() {
|
154
|
+
const formId = `#query_form_${index}`
|
155
|
+
const preId = `#pre_query_${index}`
|
156
|
+
const serializeArray = $(formId).serializeArray()
|
157
|
+
const action = $(formId).attr("action")
|
158
|
+
|
159
|
+
$.post(action, $(formId).serialize()).done(function(res) {
|
160
|
+
if (res.status) {
|
161
|
+
$(preId).text(JSON.stringify(res.data))
|
162
|
+
} else {
|
163
|
+
$(preId).text(`Query Error: ${res.error}`)
|
164
|
+
}
|
165
|
+
|
166
|
+
$(preId).show()
|
167
|
+
});
|
168
|
+
})
|
169
|
+
});
|
170
|
+
|
171
|
+
$('form input').on('keypress', function(e) {
|
172
|
+
return e.which !== 13;
|
173
|
+
});
|
174
|
+
</script>
|
@@ -3,7 +3,7 @@
|
|
3
3
|
<head>
|
4
4
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
5
5
|
|
6
|
-
<title>
|
6
|
+
<title>Editus</title>
|
7
7
|
<%= csrf_meta_tags %>
|
8
8
|
<%= csp_meta_tag %>
|
9
9
|
|
@@ -48,11 +48,14 @@
|
|
48
48
|
margin-top: 7em;
|
49
49
|
}
|
50
50
|
.flex{
|
51
|
-
display: flex;
|
51
|
+
display: flex !important;
|
52
52
|
}
|
53
|
-
items-center{
|
53
|
+
.items-center{
|
54
54
|
align-items: center;
|
55
55
|
}
|
56
|
+
.justify-space-between {
|
57
|
+
justify-content: space-between;
|
58
|
+
}
|
56
59
|
.flex-column {
|
57
60
|
flex-direction: column;
|
58
61
|
}
|
@@ -86,6 +89,9 @@
|
|
86
89
|
.mt-4 {
|
87
90
|
margin-top: 1rem;
|
88
91
|
}
|
92
|
+
.mt-8 {
|
93
|
+
margin-top: 2rem;
|
94
|
+
}
|
89
95
|
.mx-4 {
|
90
96
|
margin-bottom: 1rem;
|
91
97
|
margin-top: 1rem;
|
@@ -95,6 +101,7 @@
|
|
95
101
|
}
|
96
102
|
pre {
|
97
103
|
white-space: pre-line;
|
104
|
+
word-break: break-word;
|
98
105
|
}
|
99
106
|
.ui.cards>.orange.card, .ui.orange.card, .ui.orange.cards>.card {
|
100
107
|
box-shadow: 0 0 0 1px #d4d4d5, 0 0px 3px 1px #f2711c, 0 1px 3px 0 #d4d4d5;
|
@@ -108,12 +115,18 @@
|
|
108
115
|
.ui.celled.table tr td, .ui.celled.table tr th {
|
109
116
|
word-break: break-all;
|
110
117
|
}
|
118
|
+
.ui.list>.item.flex:after {
|
119
|
+
display: none;
|
120
|
+
}
|
121
|
+
[data-tooltip][data-variation='mini']:after {
|
122
|
+
font-size: 12px;
|
123
|
+
}
|
111
124
|
</style>
|
112
125
|
</head>
|
113
126
|
<body>
|
114
127
|
<div class="ui fixed inverted menu">
|
115
128
|
<div class="ui container">
|
116
|
-
<%= link_to '
|
129
|
+
<%= link_to 'Editus', root_path, class: "header item" %>
|
117
130
|
<%= link_to 'Home', root_path, class: "item" %>
|
118
131
|
<div class="ui simple dropdown item">
|
119
132
|
Menu <i class="dropdown icon"></i>
|
@@ -146,7 +159,6 @@
|
|
146
159
|
$(".ui.confirmation.modal")
|
147
160
|
.modal({
|
148
161
|
onApprove: function () {
|
149
|
-
console.log($(e.currentTarget).data('method'))
|
150
162
|
switch ($(e.currentTarget).data('method')) {
|
151
163
|
case 'run':
|
152
164
|
$("#" + $(e.currentTarget).data('method')).submit()
|
data/config/routes.rb
CHANGED
@@ -5,7 +5,7 @@ Editus::Engine.routes.draw do
|
|
5
5
|
get "scripts", to: "home#scripts"
|
6
6
|
post "/update", to: "home#update", as: :update
|
7
7
|
post "validate", to: "home#validate", as: :validate
|
8
|
-
|
9
8
|
post "scripts/:id/run", to: "home#run_script", as: :run
|
10
9
|
post "undo/:id", to: "home#undo", as: :undo
|
10
|
+
post "query/:id/:method", to: "home#query", as: :query
|
11
11
|
end
|
data/lib/editus/cop.rb
CHANGED
@@ -33,9 +33,9 @@ module Editus
|
|
33
33
|
return nil if model.blank?
|
34
34
|
return nil unless model.is_a?(String) || model.is_a?(Hash)
|
35
35
|
|
36
|
-
name = model.is_a?(String) ? model : model[
|
37
|
-
fields = model.is_a?(Hash) ? model[
|
38
|
-
exclude_fields = model.is_a?(Hash) ? model[
|
36
|
+
name = model.is_a?(String) ? model : model[:name]
|
37
|
+
fields = model.is_a?(Hash) ? model[:fields] : []
|
38
|
+
exclude_fields = model.is_a?(Hash) ? model[:exclude_fields] : []
|
39
39
|
|
40
40
|
{name: name, fields: fields, exclude_fields: exclude_fields}
|
41
41
|
end
|
data/lib/editus/proxy.rb
CHANGED
@@ -29,7 +29,7 @@ module Editus
|
|
29
29
|
info = Editus::Cop.instance.info(klass)
|
30
30
|
all = cols
|
31
31
|
exclude_fields = info[:exclude_fields] || []
|
32
|
-
fields = info[:fields] ? (all & info[:fields]) : all
|
32
|
+
fields = info[:fields].present? ? (all & info[:fields]) : all
|
33
33
|
|
34
34
|
fields - %w[id] - exclude_fields
|
35
35
|
end
|
@@ -55,6 +55,14 @@ module Editus
|
|
55
55
|
klass.update_columns attributes
|
56
56
|
end
|
57
57
|
|
58
|
+
def type_of_col column
|
59
|
+
klass.class.columns_hash[column.to_s]&.type
|
60
|
+
end
|
61
|
+
|
62
|
+
def defined_enums
|
63
|
+
klass.class.defined_enums
|
64
|
+
end
|
65
|
+
|
58
66
|
private
|
59
67
|
|
60
68
|
def cols
|
data/lib/editus/script.rb
CHANGED
@@ -21,10 +21,16 @@ module Editus
|
|
21
21
|
@scripts[name.to_sym] || @scripts[name.to_sym] = new(name.to_sym)
|
22
22
|
end
|
23
23
|
|
24
|
-
attr_accessor :name, :
|
24
|
+
attr_accessor :name, :path, :proxy, :content, :queries
|
25
|
+
attr_writer :title
|
25
26
|
|
26
27
|
def initialize name = nil
|
27
28
|
@name = name
|
29
|
+
@queries = []
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_query desc, name
|
33
|
+
@queries.push({description: desc, query_name: name})
|
28
34
|
end
|
29
35
|
|
30
36
|
def up
|
@@ -34,6 +40,10 @@ module Editus
|
|
34
40
|
def down
|
35
41
|
content[/task\s.*down.*do.*\n[\s\S]*?\n\s*end/]
|
36
42
|
end
|
43
|
+
|
44
|
+
def title
|
45
|
+
@title || @name.to_s.humanize
|
46
|
+
end
|
37
47
|
end
|
38
48
|
|
39
49
|
class DSL
|
@@ -45,6 +55,7 @@ module Editus
|
|
45
55
|
|
46
56
|
def initialize name
|
47
57
|
@name = name
|
58
|
+
@query_index = 0
|
48
59
|
end
|
49
60
|
|
50
61
|
def task method, &block
|
@@ -59,6 +70,31 @@ module Editus
|
|
59
70
|
internal = Internal.find_or_create @name
|
60
71
|
internal.title = txt
|
61
72
|
end
|
73
|
+
|
74
|
+
def desc description
|
75
|
+
@description = if description.blank? || !description.is_a?(String)
|
76
|
+
@query_index += 1
|
77
|
+
"Query##{@query_index}"
|
78
|
+
else
|
79
|
+
description
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def query method, &block
|
84
|
+
internal = Internal.find_or_create @name
|
85
|
+
internal.proxy ||= Editus::DefinitionProxy.new(@name)
|
86
|
+
query_name = "query_#{method}"
|
87
|
+
internal.proxy.define_singleton_method(query_name, &block)
|
88
|
+
add_query_to_internal internal, query_name
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def add_query_to_internal internal, query_name
|
94
|
+
description = desc(@description)
|
95
|
+
internal.add_query description, query_name
|
96
|
+
@description = nil
|
97
|
+
end
|
62
98
|
end
|
63
99
|
|
64
100
|
class Reader
|
data/lib/editus/version.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Editus
|
2
|
-
VERSION = "1.
|
2
|
+
VERSION = "1.1.0"
|
3
3
|
SUMMARY = "This application is a simple web interface integrated with an existing Ruby on Rails application. It allows users to directly edit models, run predefined scripts, and easily undo changes."
|
4
4
|
DESCRIPTION = <<~DOC
|
5
5
|
This application is a user-friendly web interface designed to work with a Ruby on Rails application. With a simple and intuitive web interface, users can conveniently access the features of the application.
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: editus
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- hungkieu
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-08-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -89,7 +89,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
89
89
|
requirements:
|
90
90
|
- - ">="
|
91
91
|
- !ruby/object:Gem::Version
|
92
|
-
version:
|
92
|
+
version: 2.6.0
|
93
93
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
94
94
|
requirements:
|
95
95
|
- - ">="
|