rails_execution 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 144dd7fcf30e5af4eeba4abba9112b46663919b4463db267a0b9ebcc665f6756
4
- data.tar.gz: b68d85f26a544eb520492d866d99f5e6af1fef98ba90c701c38204b6624af94e
3
+ metadata.gz: 7d04b62e7461cf38c3519551e7c96a9792418b5769d1e1782f317957c34bf617
4
+ data.tar.gz: cf09e00dfb2b487fae01323230b337f02b2867729ff05a6887d7dce0494cddbb
5
5
  SHA512:
6
- metadata.gz: 65dea3b11985125e87f87c73b6905aad2caf25b1baa4ab8dfc43d6f33f19e7883bb451ff1d3a35715f8a857a9d0fcaeaa34b8ae0e9d516a023a857d392195001
7
- data.tar.gz: bdc10fd5cd2f83853245e6fe43e17d13e8a014dbe242c49d182228fb6d152f9780913b9e99da596ff0e8aa60bf42117778c2d513e6f20c3ee2cfaa8f011ad42e
6
+ metadata.gz: 8ad2c6d2a14b9c6c3cb3be1e2728afbd9c691d5db1bd9d91f66a48d43219af9f334e4b9d23bf81d348e37422e7651d1d84469369845267d64b9ebf0aac4922de
7
+ data.tar.gz: b2e17748bdc9cb169ed742cb19fbe4ff80fc759c5465b25448f1d2ab47043d0bc40005b6b1c643cdd4f81c61944751f98108109e7f1ea1fcb086b7c220a8eabe
data/README.md CHANGED
@@ -1,35 +1,121 @@
1
- # RailsExecution
1
+ # Rails Execution
2
+ Rails Execution is an Engine to manage the Rails scripts for migration, cleanup, and fixing the bad data without deployment.
3
+ - Supported the Syntax checker
4
+ - Supported the Execution logs
5
+ - Supported the Reviewing process
6
+ - Supported the Attachment files
7
+ - Supported the Comments communication
8
+ - Supported the Activities tracking
2
9
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/rails_execution`. To experiment with that code, run `bin/console` for an interactive prompt.
4
10
 
5
- TODO: Delete this and the text above, and describe your gem
11
+ ![image](https://user-images.githubusercontent.com/6081795/193129359-fc1e8858-c3e7-4376-be1e-ca453890a98d.png)
12
+ ![image](https://user-images.githubusercontent.com/6081795/193129792-39176d6e-97fa-4a47-8541-30e7169841cd.png)
6
13
 
7
14
  ## Installation
8
15
 
9
- Install the gem and add to the application's Gemfile by executing:
16
+ Add the following line to your **Gemfile**:
10
17
 
11
- $ bundle add rails_execution
18
+ ```ruby
19
+ gem 'rails_execution'
20
+ ```
21
+ Then run `bundle install`
12
22
 
13
- If bundler is not being used to manage dependencies, install the gem by executing:
14
23
 
15
- $ gem install rails_execution
16
-
17
- ## Usage
24
+ ## Getting started
18
25
 
19
26
  ### How to setup
27
+ You need to run the generator:
28
+ ```bash
20
29
  $ rails g rails_execution:install
30
+ ```
31
+ And you can change the config in `config/initializers/rails_execution.rb`
32
+
33
+ Default is `Solo Mode`, without the Reviewing process.
34
+
35
+ #### Enable the Reviewing process
36
+ The first step is to disable the `Solo Mode`
37
+ ```ruby
38
+ config.solo_mode = false
39
+ ```
40
+ And then uncomment the configures of the `owner` and `reviewers`
41
+ ```ruby
42
+ config.owner_model = 'User'
43
+ config.owner_method = :current_user
44
+ config.owner_name_method = :name
45
+ config.owner_avatar = ->(owner) { owner.avatar.url }
46
+
47
+ config.reviewers = -> do
48
+ User.where(is_admin: true).map do |user|
49
+ {
50
+ name: user.name,
51
+ id: user.id,
52
+ type: 'User',
53
+ avatar_url: user.avatar.url,
54
+ }
55
+ end
56
+ end
57
+ ```
58
+
59
+ #### Enable the Attachment files
60
+ Run the generator to add the **FileUploader** and **FileReader**
61
+ ```bash
21
62
  $ rails g rails_execution:file_upload
22
-
23
- ## Development
24
-
25
- After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
26
-
27
- To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
28
-
29
- ## Contributing
30
-
31
- Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/rails_execution.
32
-
33
- ## License
34
-
35
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
63
+ ```
64
+ And then uncomment the file upload
65
+ ```ruby
66
+ config.file_upload = true
67
+ config.file_uploader = ::RailsExecution::FileUploader
68
+ config.file_reader = ::RailsExecution::FileReader
69
+ ```
70
+ To limit the File types. Default: `.png`, `.gif`, `.jpg`, `.jpeg`, `.pdf`, `.csv`
71
+ You can modify the limitation like this
72
+ ```ruby
73
+ config.acceptable_file_types = {
74
+ '.jpeg': 'image/jpeg',
75
+ '.pdf': 'application/pdf',
76
+ '.csv': ['text/csv', 'text/plain'],
77
+ }
78
+ ```
79
+
80
+ #### Control the Permissions
81
+ For example with *[Pundit](https://github.com/varvet/pundit)* authorization.
82
+ ```ruby
83
+ config.task_creatable = lambda do |user|
84
+ YourPolicy.new(user).creatable?
85
+ end
86
+ config.task_editable = lambda do |task, user|
87
+ YourPolicy.new(user, task).editable?
88
+ end
89
+ config.task_closable = lambda do |task, user|
90
+ YourPolicy.new(user, task).closable?
91
+ end
92
+ config.task_approvable = lambda do |task, user|
93
+ YourPolicy.new(user, task).approvable?
94
+ end
95
+ config.task_executable = lambda do |task, user|
96
+ YourPolicy.new(user, task).executable?
97
+ end
98
+ ```
99
+
100
+ #### Setup the Logger
101
+ To storage the logfile
102
+ ```ruby
103
+ config.logging = lambda do |file, task|
104
+ LoggerModel.create!(task: task, file: file)
105
+ end
106
+ ```
107
+ And list the logfiles on Task page
108
+ ```ruby
109
+ config.logging_files = lambda do |task|
110
+ LoggerModel.where(task: task).map do |log|
111
+ log.file.expiring_url(30.minutes.to_i)
112
+ end
113
+ end
114
+ ```
115
+
116
+ #### Others
117
+ To change the Per page of the tasks list.
118
+ Default value: `20`
119
+ ```ruby
120
+ config.per_page = 10
121
+ ```
@@ -12,6 +12,7 @@ window.comments.clickEditComment = function(el) {
12
12
  status: false,
13
13
  maxHeight: '150px',
14
14
  showIcons: ['code'],
15
+ spellChecker: false,
15
16
  placeholder: 'Type your comment here...',
16
17
  renderingConfig: {
17
18
  codeSyntaxHighlighting: true,
@@ -24,6 +25,7 @@ window.comments.initAddNewComment = function(id) {
24
25
  status: false,
25
26
  maxHeight: '100px',
26
27
  showIcons: ['code'],
28
+ spellChecker: false,
27
29
  placeholder: 'Type your comment here...',
28
30
  renderingConfig: {
29
31
  codeSyntaxHighlighting: true,
@@ -1,7 +1,8 @@
1
1
  .g-height-50 { height: 50px; }
2
2
  .g-width-50 { width: 50px !important; }
3
3
  .g-bg-secondary { background-color: white !important; }
4
- .media-comment { margin-top:20px }
4
+ .media-comment { margin-top:20px; }
5
+ .media-comment .media-body { overflow-x: auto; }
5
6
 
6
7
  @media (min-width: 0) {
7
8
  .g-mr-15 { margin-right: 1.07143rem !important; }
@@ -6,6 +6,7 @@ module RailsExecution
6
6
  def create
7
7
  @new_comment = current_task.comments.new(owner: current_owner, content: params.dig(:comment, :content))
8
8
  if @new_comment.save
9
+ ::RailsExecution.configuration.notifier.new(current_task).add_comment(current_owner, @new_comment.content)
9
10
  current_task.activities.create(owner: current_owner, message: "Added a comment: #{@new_comment.content.truncate(30)}")
10
11
  else
11
12
  @alert = "Your comment can't adding!"
@@ -31,6 +31,7 @@ module RailsExecution
31
31
 
32
32
  if @task.save
33
33
  @task.add_files(params[:attachments]&.permit!.to_h, current_owner) if ::RailsExecution.configuration.file_upload
34
+ ::RailsExecution.configuration.notifier.new(@task).after_create
34
35
  flash[:notice] = 'Create the request is successful!'
35
36
  redirect_to action: :index
36
37
  else
@@ -38,6 +39,22 @@ module RailsExecution
38
39
  end
39
40
  end
40
41
 
42
+ def fork
43
+ raise(::RailsExecution::AccessDeniedError, 'Fork task') unless can_create_task?
44
+
45
+ @task = ::RailsExecution::Task.new({
46
+ status: :created,
47
+ owner_id: current_owner&.id,
48
+ owner_type: ::RailsExecution.configuration.owner_model.to_s,
49
+ title: current_task.title,
50
+ description: current_task.description,
51
+ script: current_task.script,
52
+ })
53
+ @task.syntax_status = ::RailsExecution::Services::SyntaxChecker.new(@task.script).call ? 'good' : 'bad'
54
+
55
+ render action: :new
56
+ end
57
+
41
58
  def show
42
59
  end
43
60
 
@@ -49,6 +66,7 @@ module RailsExecution
49
66
 
50
67
  if current_task.update(status: :closed)
51
68
  current_task.activities.create(owner: current_owner, message: 'Closed the task')
69
+ ::RailsExecution.configuration.notifier.new(current_task).after_close
52
70
  redirect_to(action: :show) and return
53
71
  else
54
72
  flash[:alert] = "Has problem when close this Task: #{current_task.errors.full_messages.join(', ')}"
@@ -66,6 +84,10 @@ module RailsExecution
66
84
  raise(::RailsExecution::AccessDeniedError, 'Edit task') unless can_edit_task?(current_task)
67
85
 
68
86
  @task = current_task
87
+ old_script = @task.script
88
+ old_reviewer_ids = @task.task_reviews.pluck(:owner_id)
89
+ checked_owner_ids = @task.task_reviews.checked.pluck(:owner_id)
90
+
69
91
  update_data = {
70
92
  title: params.dig(:task, :title),
71
93
  description: params.dig(:task, :description),
@@ -78,6 +100,8 @@ module RailsExecution
78
100
  if @task.update(update_data)
79
101
  @task.add_files(params[:attachments]&.permit!.to_h, current_owner) if ::RailsExecution.configuration.file_upload
80
102
  @task.activities.create(owner: current_owner, message: 'Updated the Task')
103
+ ::RailsExecution.configuration.notifier.new(@task).after_update_script(current_owner, checked_owner_ids) if old_script != @task.script
104
+ ::RailsExecution.configuration.notifier.new(@task).after_assign_reviewers(current_owner, @task.task_reviews.reload.pluck(:owner_id) - old_reviewer_ids)
81
105
  redirect_to action: :show
82
106
  else
83
107
  render action: :edit
@@ -99,6 +123,7 @@ module RailsExecution
99
123
  def reopen
100
124
  if current_task.update(status: :created)
101
125
  current_task.activities.create(owner: current_owner, message: 'Re-opened the Task')
126
+ ::RailsExecution.configuration.notifier.new(current_task).after_reopen
102
127
  flash[:notice] = 'Your task is re-opened'
103
128
  else
104
129
  flash[:alert] = "Re-open is failed: #{current_task.errors.full_messages.join(', ')}"
@@ -108,6 +133,7 @@ module RailsExecution
108
133
 
109
134
  def reject
110
135
  if ::RailsExecution::Services::Approvement.new(current_task, reviewer: current_owner).reject
136
+ ::RailsExecution.configuration.notifier.new(current_task).after_reject(current_owner)
111
137
  flash[:notice] = 'Your decision is updated!'
112
138
  else
113
139
  flash[:alert] = "Your decision is can't update!"
@@ -117,6 +143,7 @@ module RailsExecution
117
143
 
118
144
  def approve
119
145
  if ::RailsExecution::Services::Approvement.new(current_task, reviewer: current_owner).approve
146
+ ::RailsExecution.configuration.notifier.new(current_task).after_approve(current_owner)
120
147
  flash[:notice] = 'Your decision is updated!'
121
148
  else
122
149
  flash[:alert] = "Your decision is can't update!"
@@ -134,8 +161,10 @@ module RailsExecution
134
161
  if execute_service.call
135
162
  current_task.update(status: :completed)
136
163
  current_task.activities.create(owner: current_owner, message: 'Execute: The task is completed')
164
+ ::RailsExecution.configuration.notifier.new(current_task).after_execute_success(current_owner)
137
165
  flash[:notice] = 'This task is executed'
138
166
  else
167
+ ::RailsExecution.configuration.notifier.new(current_task).after_execute_fail(current_owner)
139
168
  flash[:alert] = "Sorry!!! This task can't execute right now"
140
169
  end
141
170
 
@@ -167,7 +196,7 @@ module RailsExecution
167
196
  helper_method :task_attachment_files
168
197
 
169
198
  def reviewing_accounts
170
- @reviewing_accounts ||= current_task.task_reviews
199
+ @reviewing_accounts ||= current_task.task_reviews.preload(:owner)
171
200
  end
172
201
  helper_method :reviewing_accounts
173
202
 
@@ -11,4 +11,6 @@ class RailsExecution::TaskReview < RailsExecution::AppModel
11
11
  rejected: 'rejected',
12
12
  }, _prefix: :is
13
13
 
14
+ scope :checked, -> { where(status: [:approved, :rejected]) }
15
+
14
16
  end
@@ -8,6 +8,6 @@
8
8
  %li= link_to 'Processing', tasks_path, class: "nav-link px-2 link-#{ current_page?(tasks_path) ? 'secondary' : 'dark' }"
9
9
  %li= link_to 'Completed', completed_tasks_path, class: "nav-link px-2 link-#{ current_page?(completed_tasks_path) ? 'secondary' : 'dark' }"
10
10
  %li= link_to 'Closed', closed_tasks_path, class: "nav-link px-2 link-#{ current_page?(closed_tasks_path) ? 'secondary' : 'dark' }"
11
- .col-md-3.text-end
11
+ .col-md-6.text-end
12
12
  = yield :page_actions
13
13
  = link_to 'New Task', new_task_path, class: 'btn btn-outline-primary ms-2', disabled: !can_create_task?
@@ -1,5 +1,5 @@
1
1
  = render partial: 'new_comment', locals: { comment: (new_comment || current_task.comments.new) }
2
- = render current_task.comments.ascending
2
+ = render current_task.comments.ascending.preload(:owner)
3
3
 
4
4
  :javascript
5
5
  hljs.highlightAll();
@@ -1,4 +1,4 @@
1
- = form_for task, html: { enctype: 'multipart/form-data' } do |f|
1
+ = form_for task, method: task.new_record? ? :post : :patch, html: { enctype: 'multipart/form-data' } do |f|
2
2
  .row
3
3
  - if task.errors.any?
4
4
  .col-12.text-danger.small.mt-3= task.errors.full_messages.join("\n")
@@ -4,6 +4,7 @@
4
4
  element: document.getElementById('task_description'),
5
5
  status: false,
6
6
  showIcons: ['code'],
7
+ spellChecker: false,
7
8
  placeholder: "Type description here...",
8
9
  renderingConfig: {
9
10
  codeSyntaxHighlighting: true,
@@ -4,6 +4,10 @@
4
4
  - elsif current_task.is_closed? && can_create_task?
5
5
  = link_to 'Re-Open', reopen_task_path(current_task), class: 'btn btn-outline-info', method: :patch, data: { confirm: 'Are you sure?' }
6
6
 
7
+ - if can_create_task?
8
+ = link_to fork_task_path(current_task), class: 'btn btn-outline-info ms-1 me-2' do
9
+ %i.bi.bi-diagram-2
10
+ Fork
7
11
  - if can_edit_task?(current_task)
8
12
  = link_to 'Edit', edit_task_path(current_task), class: 'btn btn-outline-warning me-2'
9
13
 
data/config/routes.rb CHANGED
@@ -9,6 +9,7 @@ RailsExecution::Engine.routes.draw do
9
9
 
10
10
  resources :tasks do
11
11
  member do
12
+ get :fork
12
13
  patch :reopen
13
14
  patch :reject
14
15
  patch :approve
@@ -60,4 +60,7 @@ RailsExecution.configuration do |config|
60
60
  # Paging
61
61
  # config.per_page = 30 # Default: 20
62
62
 
63
+ # Notify
64
+ # config.notifier = ::RailsExecution::Services::Notifier
65
+
63
66
  end
@@ -44,6 +44,9 @@ module RailsExecution
44
44
  # Paging
45
45
  attr_accessor :per_page
46
46
 
47
+ # Notify
48
+ attr_accessor :notifier
49
+
47
50
  def initialize
48
51
  self.solo_mode = true
49
52
 
@@ -67,6 +70,8 @@ module RailsExecution
67
70
 
68
71
  self.logging = -> (_log_file, _task) { }
69
72
  self.logging_files = -> (_task) { [] }
73
+
74
+ self.notifier = ::RailsExecution::Services::Notifier
70
75
  end
71
76
 
72
77
  end
@@ -34,7 +34,7 @@ module RailsExecution
34
34
  end
35
35
 
36
36
  def acceptable_file_types
37
- ::RailsExecution.configuration.acceptable_file_types.values
37
+ ::RailsExecution.configuration.acceptable_file_types.values.flatten
38
38
  end
39
39
 
40
40
  end
@@ -0,0 +1,27 @@
1
+ module RailsExecution
2
+ module Services
3
+ class Notifier
4
+
5
+ def initialize(task)
6
+ @task = task
7
+ end
8
+
9
+ def after_create; end
10
+ def after_close; end
11
+ def after_reopen; end
12
+ def after_update_script(_editor, _reviewer_ids); end
13
+ def after_assign_reviewers(_editor, _new_reviewer_ids); end
14
+ def after_reject(_reviewer); end
15
+ def after_approve(_reviewer); end
16
+ def after_execute_success(_executor); end
17
+ def after_execute_fail(_executor); end
18
+
19
+ def add_comment(_commenter, _content); end
20
+
21
+ private
22
+
23
+ attr_reader :task
24
+
25
+ end
26
+ end
27
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RailsExecution
4
- VERSION = '0.1.1'
4
+ VERSION = '0.1.2'
5
5
  end
@@ -9,6 +9,7 @@ require 'rails_execution/files/reader'
9
9
  require 'rails_execution/files/uploader'
10
10
  require 'rails_execution/services/paging'
11
11
  require 'rails_execution/services/executor'
12
+ require 'rails_execution/services/notifier'
12
13
  require 'rails_execution/services/execution'
13
14
  require 'rails_execution/services/approvement'
14
15
  require 'rails_execution/services/syntax_checker'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_execution
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Khoa Nguyen
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-11-04 00:00:00.000000000 Z
11
+ date: 2022-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: haml
@@ -124,6 +124,7 @@ files:
124
124
  - lib/rails_execution/services/approvement.rb
125
125
  - lib/rails_execution/services/execution.rb
126
126
  - lib/rails_execution/services/executor.rb
127
+ - lib/rails_execution/services/notifier.rb
127
128
  - lib/rails_execution/services/paging.rb
128
129
  - lib/rails_execution/services/syntax_checker.rb
129
130
  - lib/rails_execution/version.rb