rails_execution 0.1.1 → 0.1.2

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 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