editus 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Gem Version](https://badge.fury.io/rb/editus.svg)](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
|
- - ">="
|