mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-09-20 23:16:15 +08:00
Merge pull request #2839 from okriuchykhin/ok_SCI_4978
Move some consequence executon into background process [SCI-4978]
This commit is contained in:
commit
51d69f9442
|
@ -1,6 +1,8 @@
|
||||||
/* global I18n dropdownSelector HelperModule animateSpinner */
|
/* global I18n dropdownSelector HelperModule animateSpinner */
|
||||||
/* eslint-disable no-use-before-define */
|
/* eslint-disable no-use-before-define */
|
||||||
|
|
||||||
|
const STATUS_POLLING_INTERVAL = 5000;
|
||||||
|
|
||||||
function initTaskCollapseState() {
|
function initTaskCollapseState() {
|
||||||
let taskView = '.my-modules-protocols-index';
|
let taskView = '.my-modules-protocols-index';
|
||||||
let taskSection = '.task-section-caret';
|
let taskSection = '.task-section-caret';
|
||||||
|
@ -236,7 +238,20 @@ function bindEditTagsAjax() {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function checkStatusState() {
|
||||||
|
$.getJSON($('.status-flow-dropdown').data('status-check-url'), (statusData) => {
|
||||||
|
if (statusData.status_changing) {
|
||||||
|
setTimeout(() => { checkStatusState(); }, STATUS_POLLING_INTERVAL);
|
||||||
|
} else {
|
||||||
|
location.reload();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function applyTaskStatusChangeCallBack() {
|
function applyTaskStatusChangeCallBack() {
|
||||||
|
if ($('.status-flow-dropdown').data('status-changing')) {
|
||||||
|
setTimeout(() => { checkStatusState(); }, STATUS_POLLING_INTERVAL);
|
||||||
|
}
|
||||||
$('.task-flows').on('click', '#dropdownTaskFlowList > li[data-state-id]', function() {
|
$('.task-flows').on('click', '#dropdownTaskFlowList > li[data-state-id]', function() {
|
||||||
var list = $('#dropdownTaskFlowList');
|
var list = $('#dropdownTaskFlowList');
|
||||||
var item = $(this);
|
var item = $(this);
|
||||||
|
|
|
@ -31,7 +31,8 @@ class MyModuleRepositorySnapshotsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
repository_snapshot = @repository.provision_snapshot(@my_module, current_user)
|
repository_snapshot = RepositorySnapshot.create_preliminary(@repository, @my_module, current_user)
|
||||||
|
RepositorySnapshotProvisioningJob.perform_later(repository_snapshot)
|
||||||
|
|
||||||
render json: {
|
render json: {
|
||||||
html: render_to_string(partial: 'my_modules/repositories/full_view_version',
|
html: render_to_string(partial: 'my_modules/repositories/full_view_version',
|
||||||
|
|
|
@ -11,8 +11,7 @@ class MyModulesController < ApplicationController
|
||||||
before_action :load_projects_tree, only: %i(protocols results activities archive)
|
before_action :load_projects_tree, only: %i(protocols results activities archive)
|
||||||
before_action :check_archive_and_restore_permissions, only: %i(update)
|
before_action :check_archive_and_restore_permissions, only: %i(update)
|
||||||
before_action :check_manage_permissions, only: %i(description due_date update_description update_protocol_description)
|
before_action :check_manage_permissions, only: %i(description due_date update_description update_protocol_description)
|
||||||
before_action :check_view_permissions, except: %i(update update_description update_protocol_description
|
before_action :check_view_permissions, except: %i(update update_description update_protocol_description)
|
||||||
toggle_task_state)
|
|
||||||
before_action :check_update_state_permissions, only: :update_state
|
before_action :check_update_state_permissions, only: :update_state
|
||||||
before_action :set_inline_name_editing, only: %i(protocols results activities archive)
|
before_action :set_inline_name_editing, only: %i(protocols results activities archive)
|
||||||
|
|
||||||
|
@ -46,6 +45,14 @@ class MyModulesController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def status_state
|
||||||
|
respond_to do |format|
|
||||||
|
format.json do
|
||||||
|
render json: { status_changing: @my_module.status_changing? }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def activities
|
def activities
|
||||||
params[:subjects] = {
|
params[:subjects] = {
|
||||||
MyModule: [@my_module.id]
|
MyModule: [@my_module.id]
|
||||||
|
|
24
app/jobs/my_module_status_consequences_job.rb
Normal file
24
app/jobs/my_module_status_consequences_job.rb
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class MyModuleStatusConsequencesJob < ApplicationJob
|
||||||
|
queue_as :high_priority
|
||||||
|
|
||||||
|
def perform(my_module, my_module_status_consequences)
|
||||||
|
error_raised = false
|
||||||
|
my_module.transaction do
|
||||||
|
my_module_status_consequences.each do |consequence|
|
||||||
|
consequence.call(my_module)
|
||||||
|
end
|
||||||
|
my_module.update!(status_changing: false)
|
||||||
|
rescue StandardError => e
|
||||||
|
Rails.logger.error(e.message)
|
||||||
|
Rails.logger.error(e.backtrace.join("\n"))
|
||||||
|
error_raised = true
|
||||||
|
end
|
||||||
|
if error_raised
|
||||||
|
my_module.my_module_status = my_module.changing_from_my_module_status
|
||||||
|
my_module.status_changing = false
|
||||||
|
my_module.save!
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -27,11 +27,7 @@ class MyModule < ApplicationRecord
|
||||||
validate :check_status, if: :my_module_status_id_changed?
|
validate :check_status, if: :my_module_status_id_changed?
|
||||||
validate :check_status_conditions, if: :my_module_status_id_changed?
|
validate :check_status_conditions, if: :my_module_status_id_changed?
|
||||||
validate :check_status_implications, unless: proc { |mm|
|
validate :check_status_implications, unless: proc { |mm|
|
||||||
mm.my_module_status_id_changed? ||
|
(mm.changed_attributes.keys - %w(my_module_status_id x y my_module_group_id workflow_order status_changing)).blank?
|
||||||
mm.x_changed? ||
|
|
||||||
mm.y_changed? ||
|
|
||||||
mm.my_module_group_id_changed? ||
|
|
||||||
mm.workflow_order_changed?
|
|
||||||
}
|
}
|
||||||
|
|
||||||
belongs_to :created_by,
|
belongs_to :created_by,
|
||||||
|
@ -53,6 +49,7 @@ class MyModule < ApplicationRecord
|
||||||
belongs_to :experiment, inverse_of: :my_modules, touch: true
|
belongs_to :experiment, inverse_of: :my_modules, touch: true
|
||||||
belongs_to :my_module_group, inverse_of: :my_modules, optional: true
|
belongs_to :my_module_group, inverse_of: :my_modules, optional: true
|
||||||
belongs_to :my_module_status, optional: true
|
belongs_to :my_module_status, optional: true
|
||||||
|
belongs_to :changing_from_my_module_status, optional: true, class_name: 'MyModuleStatus'
|
||||||
delegate :my_module_status_flow, to: :my_module_status, allow_nil: true
|
delegate :my_module_status_flow, to: :my_module_status, allow_nil: true
|
||||||
has_many :results, inverse_of: :my_module, dependent: :destroy
|
has_many :results, inverse_of: :my_module, dependent: :destroy
|
||||||
has_many :my_module_tags, inverse_of: :my_module, dependent: :destroy
|
has_many :my_module_tags, inverse_of: :my_module, dependent: :destroy
|
||||||
|
@ -568,10 +565,17 @@ class MyModule < ApplicationRecord
|
||||||
end
|
end
|
||||||
|
|
||||||
def exec_status_consequences
|
def exec_status_consequences
|
||||||
return if my_module_status.blank?
|
return if my_module_status.blank? || status_changing
|
||||||
|
|
||||||
my_module_status.my_module_status_consequences.each do |consequence|
|
self.changing_from_my_module_status_id = my_module_status_id_was if my_module_status_id_was.present?
|
||||||
consequence.call(self)
|
|
||||||
|
if my_module_status.my_module_status_consequences.any?(&:runs_in_background?)
|
||||||
|
self.status_changing = true
|
||||||
|
MyModuleStatusConsequencesJob.perform_later(self, my_module_status.my_module_status_consequences.to_a)
|
||||||
|
else
|
||||||
|
my_module_status.my_module_status_consequences.each do |consequence|
|
||||||
|
consequence.call(self)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,4 +2,8 @@
|
||||||
|
|
||||||
class MyModuleStatusConsequence < ApplicationRecord
|
class MyModuleStatusConsequence < ApplicationRecord
|
||||||
belongs_to :my_module_status
|
belongs_to :my_module_status
|
||||||
|
|
||||||
|
def runs_in_background?
|
||||||
|
false
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,9 +2,18 @@
|
||||||
|
|
||||||
module MyModuleStatusConsequences
|
module MyModuleStatusConsequences
|
||||||
class RepositorySnapshot < MyModuleStatusConsequence
|
class RepositorySnapshot < MyModuleStatusConsequence
|
||||||
|
def runs_in_background?
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
def call(my_module)
|
def call(my_module)
|
||||||
my_module.assigned_repositories.each do |repository|
|
my_module.assigned_repositories.each do |repository|
|
||||||
repository.provision_snapshot(my_module)
|
repository_snapshot = ::RepositorySnapshot.create_preliminary(repository, my_module)
|
||||||
|
service = Repositories::SnapshotProvisioningService.call(repository_snapshot: repository_snapshot)
|
||||||
|
unless service.succeed?
|
||||||
|
repository_snapshot.failed!
|
||||||
|
raise StandardError, service.errors
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -209,21 +209,6 @@ class Repository < RepositoryBase
|
||||||
importer.run
|
importer.run
|
||||||
end
|
end
|
||||||
|
|
||||||
def provision_snapshot(my_module, created_by = nil)
|
|
||||||
created_by ||= self.created_by
|
|
||||||
repository_snapshot = dup.becomes(RepositorySnapshot)
|
|
||||||
repository_snapshot.assign_attributes(type: RepositorySnapshot.name,
|
|
||||||
original_repository: self,
|
|
||||||
my_module: my_module,
|
|
||||||
created_by: created_by,
|
|
||||||
team: my_module.experiment.project.team,
|
|
||||||
permission_level: Extends::SHARED_INVENTORIES_PERMISSION_LEVELS[:not_shared])
|
|
||||||
repository_snapshot.provisioning!
|
|
||||||
repository_snapshot.reload
|
|
||||||
RepositorySnapshotProvisioningJob.perform_later(repository_snapshot)
|
|
||||||
repository_snapshot
|
|
||||||
end
|
|
||||||
|
|
||||||
def assigned_rows(my_module)
|
def assigned_rows(my_module)
|
||||||
repository_rows.joins(:my_module_repository_rows).where(my_module_repository_rows: { my_module_id: my_module.id })
|
repository_rows.joins(:my_module_repository_rows).where(my_module_repository_rows: { my_module_id: my_module.id })
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,6 +26,19 @@ class RepositorySnapshot < RepositoryBase
|
||||||
.order(:parent_id, updated_at: :desc)
|
.order(:parent_id, updated_at: :desc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def self.create_preliminary(repository, my_module, created_by = nil)
|
||||||
|
created_by ||= repository.created_by
|
||||||
|
repository_snapshot = repository.dup.becomes(RepositorySnapshot)
|
||||||
|
repository_snapshot.assign_attributes(type: RepositorySnapshot.name,
|
||||||
|
original_repository: repository,
|
||||||
|
my_module: my_module,
|
||||||
|
created_by: created_by,
|
||||||
|
team: my_module.experiment.project.team,
|
||||||
|
permission_level: Extends::SHARED_INVENTORIES_PERMISSION_LEVELS[:not_shared])
|
||||||
|
repository_snapshot.provisioning!
|
||||||
|
repository_snapshot.reload
|
||||||
|
end
|
||||||
|
|
||||||
def default_columns_count
|
def default_columns_count
|
||||||
Constants::REPOSITORY_SNAPSHOT_TABLE_DEFAULT_STATE['length']
|
Constants::REPOSITORY_SNAPSHOT_TABLE_DEFAULT_STATE['length']
|
||||||
end
|
end
|
||||||
|
|
|
@ -11,6 +11,7 @@ Canaid::Permissions.register_for(MyModule) do
|
||||||
.each do |perm|
|
.each do |perm|
|
||||||
can perm do |_, my_module|
|
can perm do |_, my_module|
|
||||||
my_module.active? &&
|
my_module.active? &&
|
||||||
|
!my_module.status_changing? &&
|
||||||
my_module.experiment.active? &&
|
my_module.experiment.active? &&
|
||||||
my_module.experiment.project.active?
|
my_module.experiment.project.active?
|
||||||
end
|
end
|
||||||
|
|
|
@ -40,6 +40,10 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
<div class="status-label" style="--state-color: <%= my_module.my_module_status.color %>">
|
<div class="status-label" style="--state-color: <%= my_module.my_module_status.color %>">
|
||||||
|
<% if my_module.status_changing %>
|
||||||
|
<i class="fas fa-spinner fa-spin"></i>
|
||||||
|
<span><%= t('experiments.canvas.full_zoom.status_transitioning_label') %></span>
|
||||||
|
<% end %>
|
||||||
<%= my_module.my_module_status.name %>
|
<%= my_module.my_module_status.name %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
<% status = my_module.my_module_status %>
|
<% status = my_module.my_module_status %>
|
||||||
<div class="status-label"><%= t('my_module_statuses.dropdown.status_label') %></div>
|
<div class="status-label">
|
||||||
<div class="dropdown sci-dropdown status-flow-dropdown">
|
<%= t('my_module_statuses.dropdown.status_label') %>
|
||||||
<button class="btn btn-secondary dropdown-toggle"
|
</div>
|
||||||
|
<div class="dropdown sci-dropdown status-flow-dropdown"
|
||||||
|
data-status-changing="<%= my_module.status_changing %>"
|
||||||
|
data-status-check-url="<%= status_state_my_module_path(my_module) %>">
|
||||||
|
<button class="btn btn-secondary dropdown-toggle <%= 'disabled' if my_module.status_changing %>"
|
||||||
type="button"
|
type="button"
|
||||||
data-toggle="dropdown"
|
data-toggle="dropdown"
|
||||||
aria-haspopup="true"
|
aria-haspopup="true"
|
||||||
aria-expanded="true"
|
aria-expanded="true"
|
||||||
style="<%= "background-color: #{status.color}" %>;">
|
style="<%= "background-color: #{status.color}" %>;">
|
||||||
<span><%= status.name %></span>
|
<span>
|
||||||
|
<% if my_module.status_changing %>
|
||||||
|
<i class="fas fa-spinner fa-spin"></i>
|
||||||
|
<span><%= t('my_module_statuses.dropdown.status_transitioning_label') %></span>
|
||||||
|
<% end %>
|
||||||
|
<%= status.name %>
|
||||||
|
</span>
|
||||||
<span class="caret pull-right"></span>
|
<span class="caret pull-right"></span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" aria-labelledby="dropdownTaskFlow" id="dropdownTaskFlowList" data-link-url="<%= update_state_my_module_url(my_module) %>">
|
<ul class="dropdown-menu" aria-labelledby="dropdownTaskFlow" id="dropdownTaskFlowList" data-link-url="<%= update_state_my_module_url(my_module) %>">
|
||||||
|
|
|
@ -989,6 +989,7 @@ en:
|
||||||
full_zoom:
|
full_zoom:
|
||||||
due_date: "Due date"
|
due_date: "Due date"
|
||||||
no_due_date: "not set"
|
no_due_date: "not set"
|
||||||
|
status_transitioning_label: "Transitioning to:"
|
||||||
modal_manage_users:
|
modal_manage_users:
|
||||||
modal_title: "Manage users for"
|
modal_title: "Manage users for"
|
||||||
no_users: "No users"
|
no_users: "No users"
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
en:
|
en:
|
||||||
my_module_statuses:
|
my_module_statuses:
|
||||||
dropdown:
|
dropdown:
|
||||||
status_label: Status
|
status_label: 'Status'
|
||||||
move_label: Move to
|
status_transitioning_label: 'Transitioning to:'
|
||||||
return_label: Return to
|
move_label: 'Move to'
|
||||||
view_flow_label: View task flow
|
return_label: 'Return to'
|
||||||
|
view_flow_label: 'View task flow'
|
||||||
update_status:
|
update_status:
|
||||||
error:
|
error:
|
||||||
no_permission: You dont have permission to change the status
|
no_permission: 'You dont have permission to change the status'
|
||||||
conditions:
|
conditions:
|
||||||
error:
|
error:
|
||||||
my_module_not_active: 'Task should be active'
|
my_module_not_active: 'Task should be active'
|
||||||
|
|
|
@ -392,6 +392,7 @@ Rails.application.routes.draw do
|
||||||
post 'activities'
|
post 'activities'
|
||||||
get 'activities_tab' # Activities in tab view for single module
|
get 'activities_tab' # Activities in tab view for single module
|
||||||
get 'due_date'
|
get 'due_date'
|
||||||
|
get 'status_state'
|
||||||
patch 'description',
|
patch 'description',
|
||||||
to: 'my_modules#update_description',
|
to: 'my_modules#update_description',
|
||||||
as: 'update_description'
|
as: 'update_description'
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AddStatusChangingFlagToMyModule < ActiveRecord::Migration[6.0]
|
||||||
|
def change
|
||||||
|
change_table :my_modules do |t|
|
||||||
|
t.boolean :status_changing, default: false
|
||||||
|
t.references :changing_from_my_module_status, foreign_key: { to_table: :my_module_statuses }, index: false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -851,7 +851,9 @@ CREATE TABLE public.my_modules (
|
||||||
state smallint DEFAULT 0,
|
state smallint DEFAULT 0,
|
||||||
completed_on timestamp without time zone,
|
completed_on timestamp without time zone,
|
||||||
started_on timestamp without time zone,
|
started_on timestamp without time zone,
|
||||||
my_module_status_id bigint
|
my_module_status_id bigint,
|
||||||
|
status_changing boolean DEFAULT false,
|
||||||
|
changing_from_my_module_status_id bigint
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
@ -6397,6 +6399,14 @@ ALTER TABLE ONLY public.repository_number_values
|
||||||
ADD CONSTRAINT fk_rails_3df53c9b27 FOREIGN KEY (created_by_id) REFERENCES public.users(id);
|
ADD CONSTRAINT fk_rails_3df53c9b27 FOREIGN KEY (created_by_id) REFERENCES public.users(id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: my_modules fk_rails_4768515e2e; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.my_modules
|
||||||
|
ADD CONSTRAINT fk_rails_4768515e2e FOREIGN KEY (changing_from_my_module_status_id) REFERENCES public.my_module_statuses(id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: projects fk_rails_47aee20018; Type: FK CONSTRAINT; Schema: public; Owner: -
|
-- Name: projects fk_rails_47aee20018; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
|
@ -7626,6 +7636,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||||
('20200709142830'),
|
('20200709142830'),
|
||||||
('20200713142353'),
|
('20200713142353'),
|
||||||
('20200714082503'),
|
('20200714082503'),
|
||||||
('20200826143431');
|
('20200826143431'),
|
||||||
|
('20200909121441');
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue