diff --git a/Gemfile b/Gemfile index e83f8a0fd..34ca6913d 100644 --- a/Gemfile +++ b/Gemfile @@ -58,7 +58,7 @@ gem 'jbuilder' # JSON structures via a Builder-style DSL gem 'logging', '~> 2.0.0' gem 'mime-types', '~> 3.4' gem 'nested_form_fields' -gem 'nokogiri', '~> 1.18.8' # HTML/XML parser +gem 'nokogiri', '~> 1.18.9' # HTML/XML parser gem 'noticed' gem 'oj' gem 'rails_autolink', '~> 1.1', '>= 1.1.6' @@ -70,7 +70,6 @@ gem 'rubyzip', '>= 2.3.0' # will load new rubyzip version gem 'scenic', '~> 1.4' gem 'sdoc', '~> 1.0', group: :doc gem 'silencer' # Silence certain Rails logs -gem 'sneaky-save', git: 'https://github.com/einzige/sneaky-save' gem 'turbolinks', '~> 5.2.0' gem 'underscore-rails' gem 'wicked_pdf' @@ -95,8 +94,12 @@ gem 'js-routes' gem 'tailwindcss-rails', '~> 2.4' gem 'base62' # Used for smart annotations -gem 'datadog' gem 'newrelic_rpm' +gem 'opentelemetry-exporter-otlp' +gem 'opentelemetry-instrumentation-pg' +gem 'opentelemetry-instrumentation-rails' +gem 'opentelemetry-propagator-xray' +gem 'opentelemetry-sdk' # Permission helper Gem gem 'canaid', git: 'https://github.com/scinote-eln/canaid' diff --git a/Gemfile.lock b/Gemfile.lock index 39eb4ba6f..7d2ec2351 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,10 +1,3 @@ -GIT - remote: https://github.com/einzige/sneaky-save - revision: ee71d0a00cd4ecdd575bd2a9aa8b8693915f4871 - specs: - sneaky-save (0.1.3) - activerecord (>= 3.2.0) - GIT remote: https://github.com/scinote-eln/canaid revision: bba1b817d1c9b0c7e0440a83d0f62848aabc0a1b @@ -43,29 +36,29 @@ GIT GEM remote: https://rubygems.org/ specs: - actioncable (7.2.2.1) - actionpack (= 7.2.2.1) - activesupport (= 7.2.2.1) + actioncable (7.2.2.2) + actionpack (= 7.2.2.2) + activesupport (= 7.2.2.2) nio4r (~> 2.0) websocket-driver (>= 0.6.1) zeitwerk (~> 2.6) - actionmailbox (7.2.2.1) - actionpack (= 7.2.2.1) - activejob (= 7.2.2.1) - activerecord (= 7.2.2.1) - activestorage (= 7.2.2.1) - activesupport (= 7.2.2.1) + actionmailbox (7.2.2.2) + actionpack (= 7.2.2.2) + activejob (= 7.2.2.2) + activerecord (= 7.2.2.2) + activestorage (= 7.2.2.2) + activesupport (= 7.2.2.2) mail (>= 2.8.0) - actionmailer (7.2.2.1) - actionpack (= 7.2.2.1) - actionview (= 7.2.2.1) - activejob (= 7.2.2.1) - activesupport (= 7.2.2.1) + actionmailer (7.2.2.2) + actionpack (= 7.2.2.2) + actionview (= 7.2.2.2) + activejob (= 7.2.2.2) + activesupport (= 7.2.2.2) mail (>= 2.8.0) rails-dom-testing (~> 2.2) - actionpack (7.2.2.1) - actionview (= 7.2.2.1) - activesupport (= 7.2.2.1) + actionpack (7.2.2.2) + actionview (= 7.2.2.2) + activesupport (= 7.2.2.2) nokogiri (>= 1.8.5) racc rack (>= 2.2.4, < 3.2) @@ -74,15 +67,15 @@ GEM rails-dom-testing (~> 2.2) rails-html-sanitizer (~> 1.6) useragent (~> 0.16) - actiontext (7.2.2.1) - actionpack (= 7.2.2.1) - activerecord (= 7.2.2.1) - activestorage (= 7.2.2.1) - activesupport (= 7.2.2.1) + actiontext (7.2.2.2) + actionpack (= 7.2.2.2) + activerecord (= 7.2.2.2) + activestorage (= 7.2.2.2) + activesupport (= 7.2.2.2) globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (7.2.2.1) - activesupport (= 7.2.2.1) + actionview (7.2.2.2) + activesupport (= 7.2.2.2) builder (~> 3.1) erubi (~> 1.11) rails-dom-testing (~> 2.2) @@ -92,14 +85,14 @@ GEM activemodel (>= 4.1) case_transform (>= 0.2) jsonapi-renderer (>= 0.1.1.beta1, < 0.3) - activejob (7.2.2.1) - activesupport (= 7.2.2.1) + activejob (7.2.2.2) + activesupport (= 7.2.2.2) globalid (>= 0.3.6) - activemodel (7.2.2.1) - activesupport (= 7.2.2.1) - activerecord (7.2.2.1) - activemodel (= 7.2.2.1) - activesupport (= 7.2.2.1) + activemodel (7.2.2.2) + activesupport (= 7.2.2.2) + activerecord (7.2.2.2) + activemodel (= 7.2.2.2) + activesupport (= 7.2.2.2) timeout (>= 0.4.0) activerecord-import (2.2.0) activerecord (>= 4.2) @@ -110,13 +103,13 @@ GEM multi_json (~> 1.11, >= 1.11.2) rack (>= 2.0.8, < 4) railties (>= 6.1) - activestorage (7.2.2.1) - actionpack (= 7.2.2.1) - activejob (= 7.2.2.1) - activerecord (= 7.2.2.1) - activesupport (= 7.2.2.1) + activestorage (7.2.2.2) + actionpack (= 7.2.2.2) + activejob (= 7.2.2.2) + activerecord (= 7.2.2.2) + activesupport (= 7.2.2.2) marcel (~> 1.0) - activesupport (7.2.2.1) + activesupport (7.2.2.2) base64 benchmark (>= 0.3) bigdecimal @@ -195,14 +188,14 @@ GEM aws-sigv4 (1.12.1) aws-eventstream (~> 1, >= 1.0.2) base62 (1.0.0) - base64 (0.2.0) + base64 (0.3.0) bcrypt (3.1.18) - benchmark (0.4.0) + benchmark (0.4.1) better_errors (2.10.1) erubi (>= 1.0.0) rack (>= 0.9.0) rouge (>= 1.0.0) - bigdecimal (3.2.0) + bigdecimal (3.2.2) bindata (2.5.0) binding_of_caller (1.0.0) debug_inspector (>= 0.0.1) @@ -292,13 +285,6 @@ GEM activerecord (>= 5.a) database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) - datadog (2.14.0) - datadog-ruby_core_source (~> 3.4) - libdatadog (~> 16.0.1.1.0) - libddwaf (~> 1.21.0.0.1) - logger - msgpack - datadog-ruby_core_source (3.4.0) date (3.4.1) debug_inspector (1.1.0) deface (1.9.0) @@ -361,6 +347,14 @@ GEM raabro (~> 1.4) globalid (1.2.1) activesupport (>= 6.1) + google-protobuf (4.31.1-arm64-darwin) + bigdecimal + rake (>= 13) + google-protobuf (4.31.1-x86_64-linux-gnu) + bigdecimal + rake (>= 13) + googleapis-common-protos-types (1.20.0) + google-protobuf (>= 3.18, < 5.a) graphviz (1.2.1) process-pipeline grover (1.2.3) @@ -430,12 +424,6 @@ GEM activerecord kaminari-core (= 1.2.2) kaminari-core (1.2.2) - libdatadog (16.0.1.1.0) - libdatadog (16.0.1.1.0-x86_64-linux) - libddwaf (1.21.0.0.1-arm64-darwin) - ffi (~> 1.0) - libddwaf (1.21.0.0.1-x86_64-linux) - ffi (~> 1.0) listen (3.8.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) @@ -486,9 +474,9 @@ GEM net-protocol newrelic_rpm (9.14.0) nio4r (2.7.4) - nokogiri (1.18.8-arm64-darwin) + nokogiri (1.18.9-arm64-darwin) racc (~> 1.4) - nokogiri (1.18.8-x86_64-linux-gnu) + nokogiri (1.18.9-x86_64-linux-gnu) racc (~> 1.4) noticed (1.6.3) http (>= 4.0.0) @@ -536,6 +524,82 @@ GEM validate_email validate_url webfinger (~> 2.0) + opentelemetry-api (1.5.0) + opentelemetry-common (0.22.0) + opentelemetry-api (~> 1.0) + opentelemetry-exporter-otlp (0.30.0) + google-protobuf (>= 3.18) + googleapis-common-protos-types (~> 1.3) + opentelemetry-api (~> 1.1) + opentelemetry-common (~> 0.20) + opentelemetry-sdk (~> 1.2) + opentelemetry-semantic_conventions + opentelemetry-helpers-sql (0.1.1) + opentelemetry-api (~> 1.0) + opentelemetry-helpers-sql-obfuscation (0.3.0) + opentelemetry-common (~> 0.21) + opentelemetry-instrumentation-action_mailer (0.4.0) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-active_support (~> 0.7) + opentelemetry-instrumentation-base (~> 0.23.0) + opentelemetry-instrumentation-action_pack (0.12.3) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.23.0) + opentelemetry-instrumentation-rack (~> 0.21) + opentelemetry-instrumentation-action_view (0.9.0) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-active_support (~> 0.7) + opentelemetry-instrumentation-base (~> 0.23.0) + opentelemetry-instrumentation-active_job (0.8.0) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.23.0) + opentelemetry-instrumentation-active_record (0.9.0) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.23.0) + opentelemetry-instrumentation-active_storage (0.1.1) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-active_support (~> 0.7) + opentelemetry-instrumentation-base (~> 0.23.0) + opentelemetry-instrumentation-active_support (0.8.0) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.23.0) + opentelemetry-instrumentation-base (0.23.0) + opentelemetry-api (~> 1.0) + opentelemetry-common (~> 0.21) + opentelemetry-registry (~> 0.1) + opentelemetry-instrumentation-concurrent_ruby (0.22.0) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.23.0) + opentelemetry-instrumentation-pg (0.30.1) + opentelemetry-api (~> 1.0) + opentelemetry-helpers-sql + opentelemetry-helpers-sql-obfuscation + opentelemetry-instrumentation-base (~> 0.23.0) + opentelemetry-instrumentation-rack (0.26.0) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.23.0) + opentelemetry-instrumentation-rails (0.36.0) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-action_mailer (~> 0.4.0) + opentelemetry-instrumentation-action_pack (~> 0.12.0) + opentelemetry-instrumentation-action_view (~> 0.9.0) + opentelemetry-instrumentation-active_job (~> 0.8.0) + opentelemetry-instrumentation-active_record (~> 0.9.0) + opentelemetry-instrumentation-active_storage (~> 0.1.0) + opentelemetry-instrumentation-active_support (~> 0.8.0) + opentelemetry-instrumentation-base (~> 0.23.0) + opentelemetry-instrumentation-concurrent_ruby (~> 0.22.0) + opentelemetry-propagator-xray (0.24.0) + opentelemetry-api (~> 1.0) + opentelemetry-registry (0.4.0) + opentelemetry-api (~> 1.1) + opentelemetry-sdk (1.8.0) + opentelemetry-api (~> 1.1) + opentelemetry-common (~> 0.20) + opentelemetry-registry (~> 0.2) + opentelemetry-semantic_conventions + opentelemetry-semantic_conventions (1.11.0) + opentelemetry-api (~> 1.0) orm_adapter (0.5.0) ostruct (0.6.0) overcommit (0.60.0) @@ -597,20 +661,20 @@ GEM rackup (1.0.1) rack (< 3) webrick - rails (7.2.2.1) - actioncable (= 7.2.2.1) - actionmailbox (= 7.2.2.1) - actionmailer (= 7.2.2.1) - actionpack (= 7.2.2.1) - actiontext (= 7.2.2.1) - actionview (= 7.2.2.1) - activejob (= 7.2.2.1) - activemodel (= 7.2.2.1) - activerecord (= 7.2.2.1) - activestorage (= 7.2.2.1) - activesupport (= 7.2.2.1) + rails (7.2.2.2) + actioncable (= 7.2.2.2) + actionmailbox (= 7.2.2.2) + actionmailer (= 7.2.2.2) + actionpack (= 7.2.2.2) + actiontext (= 7.2.2.2) + actionview (= 7.2.2.2) + activejob (= 7.2.2.2) + activemodel (= 7.2.2.2) + activerecord (= 7.2.2.2) + activestorage (= 7.2.2.2) + activesupport (= 7.2.2.2) bundler (>= 1.15.0) - railties (= 7.2.2.1) + railties (= 7.2.2.2) rails-controller-testing (1.0.5) actionpack (>= 5.0.1.rc1) actionview (>= 5.0.1.rc1) @@ -626,9 +690,9 @@ GEM actionview (> 3.1) activesupport (> 3.1) railties (> 3.1) - railties (7.2.2.1) - actionpack (= 7.2.2.1) - activesupport (= 7.2.2.1) + railties (7.2.2.2) + actionpack (= 7.2.2.2) + activesupport (= 7.2.2.2) irb (~> 1.13) rackup (>= 1.0.0) rake (>= 12.2) @@ -698,7 +762,7 @@ GEM rack (>= 1.1) rubocop (>= 1.33.0, < 2.0) ruby-progressbar (1.13.0) - ruby-saml (1.18.0) + ruby-saml (1.18.1) nokogiri (>= 1.13.10) rexml ruby-vips (2.1.4) @@ -750,7 +814,7 @@ GEM railties (>= 6.0.0) tailwindcss-rails (2.4.0-x86_64-linux) railties (>= 6.0.0) - thor (1.3.2) + thor (1.4.0) tilt (2.4.0) timecop (0.9.6) timeout (0.4.3) @@ -836,7 +900,6 @@ DEPENDENCIES cssbundling-rails cucumber-rails database_cleaner - datadog deface (~> 1.9) delayed_job_active_record devise (~> 4.9.4) @@ -866,7 +929,7 @@ DEPENDENCIES mime-types (~> 3.4) nested_form_fields newrelic_rpm - nokogiri (~> 1.18.8) + nokogiri (~> 1.18.9) noticed oj omniauth (~> 2.1) @@ -876,6 +939,11 @@ DEPENDENCIES omniauth-rails_csrf_protection (~> 1.0) omniauth-saml omniauth_openid_connect + opentelemetry-exporter-otlp + opentelemetry-instrumentation-pg + opentelemetry-instrumentation-rails + opentelemetry-propagator-xray + opentelemetry-sdk overcommit pg (~> 1.5) pg_search @@ -907,7 +975,6 @@ DEPENDENCIES shoulda-matchers silencer simplecov - sneaky-save! sprockets-rails tailwindcss-rails (~> 2.4) timecop diff --git a/VERSION b/VERSION index c798851e9..372cf402c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.43.0.1 +1.44.0 diff --git a/app/assets/javascripts/protocols/new_protocol.js b/app/assets/javascripts/protocols/new_protocol.js index 1b8735365..70493cdf7 100644 --- a/app/assets/javascripts/protocols/new_protocol.js +++ b/app/assets/javascripts/protocols/new_protocol.js @@ -3,17 +3,6 @@ const protocolModal = '#newProtocolModal'; const submitButton = $('.create-protocol-button'); - let roleSelector = `${protocolModal} #protocol_role_selector`; - dropdownSelector.init(roleSelector, { - noEmptyOption: true, - singleSelect: true, - closeOnSelect: true, - selectAppearance: 'simple', - onChange: function() { - $('#protocol_default_public_user_role_id').val(dropdownSelector.getValues(roleSelector)); - } - }); - $(protocolModal) .on('input', '#protocol_name', function() { if ($(this).val().length >= GLOBAL_CONSTANTS.NAME_MIN_LENGTH) { @@ -22,11 +11,6 @@ submitButton.attr('disabled', 'disabled'); } }) - .on('change', '#protocol_visibility', function() { - let checked = $(this)[0].checked; - $('#roleSelectWrapper').toggleClass('hidden', !checked); - $('#protocol_default_public_user_role_id').prop('disabled', !checked); - }) .on('submit', function() { submitButton.attr('disabled', 'disabled'); }) diff --git a/app/assets/javascripts/protocols/protocolsio.js b/app/assets/javascripts/protocols/protocolsio.js index 65dde90dd..ad2c1cda9 100644 --- a/app/assets/javascripts/protocols/protocolsio.js +++ b/app/assets/javascripts/protocols/protocolsio.js @@ -198,15 +198,6 @@ var protocolsIO = function() { e.stopPropagation(); animateSpinner(modal, true); - const visibility = $('#protocol-preview-modal .modal-footer #visibility').prop('checked'); - const defaultPublicUserRoleId = $('#protocol-preview-modal .modal-footer #default_public_user_role_id') - .prop('value'); - const visibilityField = $('#protocol-preview-modal #protocol_visibility'); - const defaultPublicUserRoleIdField = $('#protocol-preview-modal #protocol_default_public_user_role_id'); - - visibilityField.prop('value', visibility ? 'visible' : 'hidden'); - defaultPublicUserRoleIdField.prop('value', defaultPublicUserRoleId); - $.ajax({ type: 'POST', url: url, @@ -291,24 +282,6 @@ var protocolsIO = function() { $('form.protocols-search-bar').submit(); function initProtocolModalPreview() { - $('#protocol-preview-modal').on('change', '#visibility', function() { - const checkbox = this; - $('#protocol-preview-modal #roleSelectWrapper').toggleClass('hidden', !checkbox.checked); - }); - - - const roleSelector = '#protocol-preview-modal #role_selector'; - - dropdownSelector.init(roleSelector, { - noEmptyOption: true, - singleSelect: true, - closeOnSelect: true, - selectAppearance: 'simple', - onChange: function() { - $('#protocol-preview-modal #default_public_user_role_id').val(dropdownSelector.getValues(roleSelector)); - } - }); - $('#protocol-preview-modal') .on('ajax:error', 'form', function(e, error) { let msg = error.responseJSON.error; diff --git a/app/assets/javascripts/users/settings/teams/show.js b/app/assets/javascripts/users/settings/teams/show.js index d9a887b2a..cd213e4b6 100644 --- a/app/assets/javascripts/users/settings/teams/show.js +++ b/app/assets/javascripts/users/settings/teams/show.js @@ -150,7 +150,11 @@ if (data.status === 'done') { // Reload the whole table HelperModule.flashAlertMsg(jobData.success_message, 'success'); - usersDatatable.ajax.reload(); + if(jobData.redirect_url) { + window.location.href = jobData.redirect_url; + } else { + usersDatatable.ajax.reload(); + } animateSpinner(null, false); $('#destroy-user-team-modal').modal('hide'); clearInterval(jobStatusInterval); diff --git a/app/controllers/access_permissions/base_controller.rb b/app/controllers/access_permissions/base_controller.rb index 4e0da28db..4b493fbee 100644 --- a/app/controllers/access_permissions/base_controller.rb +++ b/app/controllers/access_permissions/base_controller.rb @@ -75,6 +75,8 @@ module AccessPermissions end propagate_job + + render json: { user_role_id: @assignment.user_role_id }, status: :ok rescue ActiveRecord::RecordInvalid render json: { flash: t('access_permissions.update.failure') }, status: :unprocessable_entity end @@ -106,7 +108,7 @@ module AccessPermissions end def show_user_group_assignments - render json: @model.user_group_assignments.includes(:user_role, :user_group).order('user_groups.name ASC'), + render json: @model.user_group_assignments.where(team: current_team).includes(:user_role, :user_group).order('user_groups.name ASC'), each_serializer: UserGroupAssignmentSerializer, user: current_user end @@ -122,7 +124,7 @@ module AccessPermissions private def model_parameter - @model.class.permission_class.name.parameterize.to_sym + @model.class.permission_class.model_name.param_key end def manage_permission_constant diff --git a/app/controllers/access_permissions/experiments_controller.rb b/app/controllers/access_permissions/experiments_controller.rb index 813b6bb2a..0f661007e 100644 --- a/app/controllers/access_permissions/experiments_controller.rb +++ b/app/controllers/access_permissions/experiments_controller.rb @@ -7,7 +7,7 @@ module AccessPermissions def update if permitted_params[:user_role_id] == 'reset' parent_assignment = @project.public_send(:"#{assignment_type}_assignments").find_or_initialize_by( - "#{assignment_type}_id": permitted_params[:"#{assignment_type}_id"], + "#{assignment_type}_id": permitted_params[:"#{assignment_type}_id"] || current_team.id, team: current_team ) @@ -24,16 +24,18 @@ module AccessPermissions ) end - UserAssignments::PropagateAssignmentJob.perform_later(@assignment, destroy: permitted_params[:user_role_id] == 'reset') + UserAssignments::PropagateAssignmentJob.perform_later(@assignment) case assignment_type + when :team + log_activity(:experiment_access_changed_all_team_members, team: @assignment.team.id, role: @assignment.user_role.name) when :user_group log_activity(:experiment_access_changed_user_group, user_group: @assignment.user_group.id, role: @assignment.user_role.name) when :user log_activity(:change_user_role_on_experiment, user_target: @assignment.user.id, role: @assignment.user_role.name) end - render json: {}, status: :ok + render json: { user_role_id: @assignment.user_role_id }, status: :ok end private diff --git a/app/controllers/access_permissions/my_modules_controller.rb b/app/controllers/access_permissions/my_modules_controller.rb index 9a42e6eb0..62cc95a0c 100644 --- a/app/controllers/access_permissions/my_modules_controller.rb +++ b/app/controllers/access_permissions/my_modules_controller.rb @@ -8,7 +8,7 @@ module AccessPermissions def update if permitted_params[:user_role_id] == 'reset' parent_assignment = @experiment.public_send(:"#{assignment_type}_assignments").find_or_initialize_by( - "#{assignment_type}_id": permitted_params[:"#{assignment_type}_id"], + "#{assignment_type}_id": permitted_params[:"#{assignment_type}_id"] || current_team.id, team: current_team ) @@ -26,11 +26,15 @@ module AccessPermissions end case assignment_type + when :team + log_activity(:my_module_access_changed_all_team_members, team: @assignment.team.id, role: @assignment.user_role.name) when :user_group log_activity(:my_module_access_changed_user_group, user_group: @assignment.user_group.id, role: @assignment.user_role.name) when :user log_activity(:change_user_role_on_my_module, user_target: @assignment.user.id, role: @assignment.user_role.name) end + + render json: { user_role_id: @assignment.user_role_id }, status: :ok end private diff --git a/app/controllers/access_permissions/repositories_controller.rb b/app/controllers/access_permissions/repositories_controller.rb index 82a72fd53..7a1b6a136 100644 --- a/app/controllers/access_permissions/repositories_controller.rb +++ b/app/controllers/access_permissions/repositories_controller.rb @@ -15,7 +15,7 @@ module AccessPermissions end def check_read_permissions - render_403 unless can_read_repository?(@model) || can_manage_team?(@model.team) + render_403 unless can_manage_repository_users?(@model) || can_read_repository?(@model) end end end diff --git a/app/controllers/api/v1/experiment_user_assignments_controller.rb b/app/controllers/api/v1/experiment_user_assignments_controller.rb index 65b0e238b..6ef48346c 100644 --- a/app/controllers/api/v1/experiment_user_assignments_controller.rb +++ b/app/controllers/api/v1/experiment_user_assignments_controller.rb @@ -35,12 +35,7 @@ module Api @user_assignment.update!(user_assignment_params.merge(assigned: :manually)) - UserAssignments::PropagateAssignmentJob.perform_later( - @experiment, - @user_assignment.user_id, - @user_assignment.user_role, - current_user.id - ) + UserAssignments::PropagateAssignmentJob.perform_later(@user_assignment) log_change_activity diff --git a/app/controllers/api/v1/inventories_controller.rb b/app/controllers/api/v1/inventories_controller.rb index 7c4089615..b148aa520 100644 --- a/app/controllers/api/v1/inventories_controller.rb +++ b/app/controllers/api/v1/inventories_controller.rb @@ -13,6 +13,7 @@ module Api def index inventories = timestamps_filter(@team.repositories).active + .readable_by_user(current_user) .page(params.dig(:page, :number)) .per(params.dig(:page, :size)) diff --git a/app/controllers/api/v1/project_user_assignments_controller.rb b/app/controllers/api/v1/project_user_assignments_controller.rb index a51814181..ba3218cab 100644 --- a/app/controllers/api/v1/project_user_assignments_controller.rb +++ b/app/controllers/api/v1/project_user_assignments_controller.rb @@ -110,10 +110,7 @@ module Api def propagate_job(user_assignment, destroy: false) UserAssignments::PropagateAssignmentJob.perform_later( - @project, - user_assignment.user.id, - user_assignment.user_role, - current_user.id, + user_assignment, destroy: destroy ) end diff --git a/app/controllers/api/v1/projects_controller.rb b/app/controllers/api/v1/projects_controller.rb index c1f667465..fd253aeff 100644 --- a/app/controllers/api/v1/projects_controller.rb +++ b/app/controllers/api/v1/projects_controller.rb @@ -32,32 +32,57 @@ module Api def create raise PermissionError.new(Project, :create) unless can_create_projects?(@team) - project = @team.projects.build(project_params.merge!(created_by: current_user)) + ActiveRecord::Base.transaction do + project = @team.projects.build(project_params.merge!(created_by: current_user)) - if project.visible? # set default viewer role for public projects - project.default_public_user_role = UserRole.predefined.find_by(name: I18n.t('user_roles.predefined.viewer')) + project.save! + + if project_params[:visibility] == 'visible' + project.team_assignments.create!( + team: project.team, + user_role: UserRole.find_predefined_viewer_role, + assigned_by: current_user, + assigned: :manually + ) + end + + render jsonapi: project, serializer: ProjectSerializer, scope: { metadata: params['with-metadata'] == 'true' }, status: :created end - - project.save! - - render jsonapi: project, serializer: ProjectSerializer, scope: { metadata: params['with-metadata'] == 'true' }, status: :created end def update @project.assign_attributes(project_params) - return render body: nil, status: :no_content unless @project.changed? + return render body: nil, status: :no_content if !@project.changed? && project_params[:visibility].blank? - if @project.archived_changed? - if @project.archived? - @project.archived_by = current_user - else - @project.restored_by = current_user + ActiveRecord::Base.transaction do + if @project.archived_changed? + if @project.archived? + @project.archived_by = current_user + else + @project.restored_by = current_user + end end + @project.last_modified_by = current_user + @project.save! + + if project_params[:visibility].present? + team_assignment = @project.team_assignments.find_by(team: @team) + + if project_params[:visibility] == 'hidden' && team_assignment.present? + team_assignment.destroy! + elsif project_params[:visibility] == 'visible' && team_assignment.blank? + @project.team_assignments.create!( + team: @project.team, + user_role: UserRole.find_predefined_viewer_role, + assigned_by: current_user, + assigned: :manually + ) + end + end + + render jsonapi: @project, serializer: ProjectSerializer, scope: { metadata: params['with-metadata'] == 'true' }, status: :ok end - @project.last_modified_by = current_user - @project.save! - render jsonapi: @project, serializer: ProjectSerializer, scope: { metadata: params['with-metadata'] == 'true' }, status: :ok end def activities diff --git a/app/controllers/api/v1/task_inventory_items_controller.rb b/app/controllers/api/v1/task_inventory_items_controller.rb index c93ced8e5..e43d74ff9 100644 --- a/app/controllers/api/v1/task_inventory_items_controller.rb +++ b/app/controllers/api/v1/task_inventory_items_controller.rb @@ -7,16 +7,18 @@ module Api before_action :load_project before_action :load_experiment before_action :load_task - before_action :load_my_module_repository_row, only: :update + before_action :load_inventory_item, only: %i(show destroy update) + before_action :load_task_inventory_item, only: %i(update destroy) + before_action :check_repository_view_permissions, only: :show before_action :check_stock_consumption_update_permissions, only: :update before_action :check_task_assign_permissions, only: %i(create destroy) def index - items = - timestamps_filter(@task.repository_rows).includes(repository_cells: :repository_column) - .preload(repository_cells: :value) - .page(params.dig(:page, :number)) - .per(params.dig(:page, :size)) + items = @task.repository_rows.where(repository_id: Repository.readable_by_user(current_user).select(:id)) + items = timestamps_filter(items).includes(repository_cells: :repository_column) + .preload(repository_cells: :value) + .page(params.dig(:page, :number)) + .per(params.dig(:page, :size)) render jsonapi: items, each_serializer: TaskInventoryItemSerializer, show_repository: true, @@ -25,7 +27,7 @@ module Api end def show - render jsonapi: @task.repository_rows.find(params.require(:id)), + render jsonapi: @inventory_item, serializer: TaskInventoryItemSerializer, show_repository: true, my_module: @task, @@ -39,21 +41,21 @@ module Api @task.my_module_repository_rows.create!(repository_row: @inventory_item, assigned_by: current_user) - render jsonapi: @task.repository_rows, - each_serializer: TaskInventoryItemSerializer, + render jsonapi: @inventory_item, + serializer: TaskInventoryItemSerializer, show_repository: true, my_module: @task, include: include_params end def update - @my_module_repository_row.consume_stock( + @task_inventory_item.consume_stock( current_user, repository_row_params[:attributes][:stock_consumption], repository_row_params[:attributes][:stock_consumption_comment] ) - render jsonapi: @my_module_repository_row.repository_row, + render jsonapi: @inventory_item, serializer: TaskInventoryItemSerializer, show_repository: true, my_module: @task, @@ -61,29 +63,27 @@ module Api end def destroy - @inventory_item = @task.repository_rows.find(params.require(:id)) - - raise PermissionError.new(Repository, :read) unless @inventory_item && can_read_repository?(@inventory_item.repository) - - @task.my_module_repository_rows.find_by(repository_row: @inventory_item).destroy! + @task_inventory_item.destroy! render body: nil end private - def load_my_module_repository_row - @my_module_repository_row = @task.repository_rows - .find(params.require(:id)) - .my_module_repository_rows - .find_by(my_module: @task) + def load_inventory_item + @inventory_item = @task.repository_rows.find(params.require(:id)) + end + + def load_task_inventory_item + @task_inventory_item = @task.my_module_repository_rows.find_by!(repository_row: @inventory_item) + end + + def check_repository_view_permissions + raise PermissionError.new(RepositoryRow, :read_repository) unless can_read_repository?(@inventory_item.repository) end def check_stock_consumption_update_permissions - unless can_update_my_module_stock_consumption?(@task) && - can_manage_repository_rows?(@my_module_repository_row.repository_row.repository) - raise PermissionError.new(RepositoryRow, :update_stock_consumption) - end + raise PermissionError.new(RepositoryRow, :update_stock_consumption) if @inventory_item.archived? || !can_update_my_module_stock_consumption?(@task) end def check_task_assign_permissions diff --git a/app/controllers/dashboard/calendars_controller.rb b/app/controllers/dashboard/calendars_controller.rb index 8242ee40f..6bed36ca3 100644 --- a/app/controllers/dashboard/calendars_controller.rb +++ b/app/controllers/dashboard/calendars_controller.rb @@ -9,13 +9,13 @@ module Dashboard date = params[:date].to_date start_date = date.beginning_of_month - 8.days end_date = date.end_of_month + 15.days - due_dates = current_user.my_modules.readable_by_user(current_user).active.uncomplete - .joins(experiment: :project) - .where(experiments: { archived: false }) - .where(projects: { archived: false }) - .where(my_modules: { due_date: start_date..end_date }) - .joins(:protocols).where(protocols: { team_id: current_team.id }) - .pluck(:due_date) + due_dates = MyModule.readable_by_user(current_user).active.uncomplete + .joins(experiment: :project) + .where(experiments: { archived: false }) + .where(projects: { archived: false }) + .where(my_modules: { due_date: start_date..end_date }) + .joins(:protocols).where(protocols: { team_id: current_team.id }) + .pluck(:due_date) render json: { events: due_dates.map { |i| { date: i.to_date } } } end @@ -23,12 +23,12 @@ module Dashboard date = params[:date].to_date start_date = date.beginning_of_day end_date = date.end_of_day - my_modules = current_user.my_modules.readable_by_user(current_user).active.uncomplete - .joins(experiment: :project) - .where(experiments: { archived: false }) - .where(projects: { archived: false }) - .where(my_modules: { due_date: start_date..end_date }) - .where(projects: { team_id: current_team.id }) + my_modules = MyModule.readable_by_user(current_user).active.uncomplete + .joins(experiment: :project) + .where(experiments: { archived: false }) + .where(projects: { archived: false }) + .where(my_modules: { due_date: start_date..end_date }) + .where(projects: { team_id: current_team.id }) render json: { html: render_to_string(partial: 'shared/my_modules_list_partial', locals: { my_modules: my_modules }, diff --git a/app/controllers/dashboard/current_tasks_controller.rb b/app/controllers/dashboard/current_tasks_controller.rb index a61a2c787..85cbd1b46 100644 --- a/app/controllers/dashboard/current_tasks_controller.rb +++ b/app/controllers/dashboard/current_tasks_controller.rb @@ -34,7 +34,7 @@ module Dashboard .search_by_name(current_user, current_team, params[:query]).select(:id, :name) unless params[:mode] == 'team' - projects = projects.where(id: current_user.my_modules.joins(:experiment) + projects = projects.where(id: MyModule.readable_by_user(current_user).joins(:experiment) .group(:project_id).select(:project_id).pluck(:project_id)) end render json: projects.map { |i| { value: i.id, label: escape_input(i.name) } }, status: :ok @@ -51,7 +51,7 @@ module Dashboard .search_by_name(current_user, current_team, params[:query]).select(:id, :name) unless params[:mode] == 'team' - experiments = experiments.where(id: current_user.my_modules + experiments = experiments.where(id: MyModule.readable_by_user(current_user) .group(:experiment_id).select(:experiment_id).pluck(:experiment_id)) end render json: experiments.map { |i| { value: i.id, label: escape_input(i.name) } }, status: :ok diff --git a/app/controllers/experiments_controller.rb b/app/controllers/experiments_controller.rb index acb418e61..67cc028e6 100644 --- a/app/controllers/experiments_controller.rb +++ b/app/controllers/experiments_controller.rb @@ -47,7 +47,7 @@ class ExperimentsController < ApplicationController end def assigned_users - render json: User.where(id: @experiment.user_assignments.select(:user_id)), + render json: @experiment.users, each_serializer: UserSerializer, user: current_user end diff --git a/app/controllers/external_protocols_controller.rb b/app/controllers/external_protocols_controller.rb index c38826e5f..8bfe34f37 100644 --- a/app/controllers/external_protocols_controller.rb +++ b/app/controllers/external_protocols_controller.rb @@ -118,7 +118,7 @@ class ExternalProtocolsController < ApplicationController def create_protocol_params params .require(:protocol) - .permit(:name, :authors, :published_on, :protocol_type, :description, :visibility, :default_public_user_role_id) + .permit(:name, :authors, :published_on, :protocol_type, :description) .except(:steps) end diff --git a/app/controllers/form_field_values_controller.rb b/app/controllers/form_field_values_controller.rb index 4b4f577e7..6fb2b6305 100644 --- a/app/controllers/form_field_values_controller.rb +++ b/app/controllers/form_field_values_controller.rb @@ -18,7 +18,7 @@ class FormFieldValuesController < ApplicationController log_form_field_value_create_activity form_field_value_annotation if @form_field_value.is_a?(FormTextFieldValue) - render json: @form_field_value, serializer: FormFieldValueSerializer, user: current_user + render json: @form_field_value, serializer: FormFieldValueSerializer, scope: { user: current_user } end private @@ -52,7 +52,7 @@ class FormFieldValuesController < ApplicationController smart_annotation_notification( old_text: @form_field_value.text_previously_was, new_text: @form_field_value.text, - subject: step.protocol, + subject: step, title: t('notifications.form_field_value_title', user: current_user.full_name, field: @form_field_value.form_field.name, diff --git a/app/controllers/label_templates_controller.rb b/app/controllers/label_templates_controller.rb index dcb312dac..710b71d42 100644 --- a/app/controllers/label_templates_controller.rb +++ b/app/controllers/label_templates_controller.rb @@ -5,7 +5,7 @@ class LabelTemplatesController < ApplicationController include TeamsHelper before_action :check_feature_enabled, except: %i(index zpl_preview list) - before_action :load_label_templates, only: %i(index datatable list) + before_action :load_label_templates, only: %i(index list) before_action :load_label_template, only: %i(show set_default update template_tags) before_action :check_view_permissions, except: %i(create duplicate set_default delete update) before_action :check_manage_permissions, only: %i(create duplicate set_default delete update) diff --git a/app/controllers/my_modules_controller.rb b/app/controllers/my_modules_controller.rb index 2a0883402..781e4f3d5 100644 --- a/app/controllers/my_modules_controller.rb +++ b/app/controllers/my_modules_controller.rb @@ -47,7 +47,7 @@ class MyModulesController < ApplicationController def new @my_module = @experiment.my_modules.new - assigned_users = User.where(id: @experiment.user_assignments.select(:user_id)) + assigned_users = @experiment.users render json: { html: render_to_string( diff --git a/app/controllers/navigations_controller.rb b/app/controllers/navigations_controller.rb index 964ca12e4..b11fa6f9d 100644 --- a/app/controllers/navigations_controller.rb +++ b/app/controllers/navigations_controller.rb @@ -60,22 +60,16 @@ class NavigationsController < ApplicationController end def settings_menu_links - links = [ - { - name: I18n.t('users.settings.sidebar.teams'), url: teams_path - }, { - name: I18n.t('users.settings.sidebar.account_nav.addons'), url: addons_path - } - ] - - if can_create_acitivity_filters? - links.push({ name: I18n.t('users.settings.sidebar.webhooks'), url: users_settings_webhooks_path }) - end + links = [{ name: I18n.t('users.settings.sidebar.teams'), url: teams_path }] + links << { name: I18n.t('users.settings.sidebar.groups'), url: users_settings_team_user_groups_path(current_team) } if can_manage_team?(current_team) + links << { name: I18n.t('users.settings.sidebar.account_nav.addons'), url: addons_path } private_methods.select { |i| i.to_s[/^settings_menu_links_[a-z]*_extension$/] }.each do |method| links = __send__(method, links) end + links << { name: I18n.t('users.settings.sidebar.webhooks'), url: users_settings_webhooks_path } if can_create_acitivity_filters? + links end diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index b89a7a110..a864845a2 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -86,7 +86,6 @@ class ProjectsController < ApplicationController end def update - default_public_user_role_name_before_update = @project.default_public_user_role&.name old_status = @project.status @project.assign_attributes(project_update_params) return_error = false @@ -105,14 +104,6 @@ class ProjectsController < ApplicationController end message_edited = @project.name_changed? || @project.description_changed? - message_visibility = if !@project.visibility_changed? - nil - elsif @project.visible? - t('projects.activity.visibility_visible') - else - t('projects.activity.visibility_hidden') - end - message_archived = if !@project.archived_changed? nil elsif @project.archived? @@ -124,41 +115,14 @@ class ProjectsController < ApplicationController start_date_changes = @project.changes[:start_date] due_date_changes = @project.changes[:due_date] - default_public_user_role_name = nil - if !@project.visibility_changed? && @project.default_public_user_role_id_changed? - @project.visibility_will_change! # triggers assignment sync - default_public_user_role_name = UserRole.find(project_params[:default_public_user_role_id]).name - end - @project.last_modified_by = current_user if !return_error && @project.save # Add activities if needed - if message_visibility.present? && @project.visible? - log_activity(:project_grant_access_to_all_team_members, - @project, - { visibility: message_visibility, - role: @project.default_public_user_role.name, - team: @project.team.id }) - end - if message_visibility.present? && !@project.visible? - log_activity(:project_remove_access_from_all_team_members, - @project, - { visibility: message_visibility, - role: default_public_user_role_name_before_update, - team: @project.team.id }) - end - log_activity(:edit_project) if message_edited.present? log_activity(:archive_project) if message_archived == 'archive' log_activity(:restore_project) if message_archived == 'restore' - if default_public_user_role_name.present? - log_activity(:project_access_changed_all_team_members, - @project, - { team: @project.team.id, role: default_public_user_role_name }) - end - if supervised_by_id_changes.present? log_activity(:remove_head_of_project, @project, { user_target: supervised_by_id_changes[0] }) if supervised_by_id_changes[0].present? # remove head of project log_activity(:set_head_of_project, @project, { user_target: supervised_by_id_changes[1] }) if supervised_by_id_changes[1].present? # add head of project @@ -320,9 +284,8 @@ class ProjectsController < ApplicationController def project_params params.require(:project) .permit( - :name, :visibility, + :name, :archived, :project_folder_id, - :default_public_user_role_id, :due_date, :start_date, :description @@ -331,7 +294,7 @@ class ProjectsController < ApplicationController def project_update_params params.require(:project) - .permit(:name, :visibility, :archived, :default_public_user_role_id, :due_date, :start_date, :description, :status, :supervised_by_id) + .permit(:name, :archived, :due_date, :start_date, :description, :status, :supervised_by_id) end def view_type_params diff --git a/app/controllers/protocols_controller.rb b/app/controllers/protocols_controller.rb index 1bf70f38b..a96270be6 100644 --- a/app/controllers/protocols_controller.rb +++ b/app/controllers/protocols_controller.rb @@ -1092,7 +1092,7 @@ class ProtocolsController < ApplicationController end def create_params - params.require(:protocol).permit(:name, :default_public_user_role_id, :visibility) + params.require(:protocol).permit(:name) end def check_protocolsio_import_permissions diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index d56dfd84e..37b2466d5 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -12,7 +12,7 @@ class RepositoriesController < ApplicationController before_action :switch_team_with_param, only: %i(index) before_action :load_repository, except: %i(index create create_modal archive restore actions_toolbar export_repositories list) - before_action :load_repositories, only: %i(index list actions_toolbar) + before_action :load_repositories, only: %i(index actions_toolbar) before_action :load_repositories_for_archiving, only: :archive before_action :load_repositories_for_restoring, only: :restore before_action :check_view_permissions, except: %i(index create_modal create update destroy parse_sheet @@ -44,7 +44,14 @@ class RepositoriesController < ApplicationController end def list - results = @repositories.select(:id, :name, 'LOWER(repositories.name)') + repositories = if params[:appendable] == 'true' + Repository.appendable_by_user(current_user) + elsif params[:manageable] == 'true' + Repository.with_granted_permissions(current_user, RepositoryPermissions::ROWS_UPDATE, current_team) + else + Repository.readable_by_user(current_user, current_team) + end + results = repositories.select(:id, :name, 'LOWER(repositories.name)') results = results.name_like(params[:query]) if params[:query].present? results = results.joins(:repository_rows).distinct if params[:non_empty].present? results = results.active if params[:active].present? @@ -482,9 +489,7 @@ class RepositoriesController < ApplicationController def load_repositories @repositories = - if params[:appendable] == 'true' - Repository.appendable_by_user(current_user) - elsif can_manage_team?(current_team) + if can_manage_team?(current_team) # Team owners see all repositories in the team current_team.repositories.or(Repository.shared_with_team(current_team)) else diff --git a/app/controllers/repository_row_connections_controller.rb b/app/controllers/repository_row_connections_controller.rb index d05d47913..3e6955ae7 100644 --- a/app/controllers/repository_row_connections_controller.rb +++ b/app/controllers/repository_row_connections_controller.rb @@ -145,19 +145,23 @@ class RepositoryRowConnectionsController < ApplicationController repository_connections.map do |connection| repository_row = @relation_type == 'parent' ? connection.parent : connection.child - - { - name: repository_row.name_with_label, - code: repository_row.code, - path: repository_repository_row_path(repository_row.repository, repository_row), - repository_name: repository_row.repository.name_with_label, - repository_path: repository_path(repository_row.repository), - unlink_path: repository_repository_row_repository_row_connection_path( - repository_row.repository, - repository_row, - connection - ) - } + if can_read_repository?(repository_row.repository) + { + name: repository_row.name_with_label, + code: repository_row.code, + path: repository_repository_row_path(repository_row.repository, repository_row), + repository_name: repository_row.repository.name_with_label, + repository_path: repository_path(repository_row.repository), + can_connect_rows: can_connect_repository_rows?(repository_row.repository), + unlink_path: repository_repository_row_repository_row_connection_path( + repository_row.repository, + repository_row, + connection + ) + } + else + { name: I18n.t('repositories.item_card.relationships.private_item_name') } + end end end diff --git a/app/controllers/repository_rows_controller.rb b/app/controllers/repository_rows_controller.rb index 1366d2331..3b5f0866d 100644 --- a/app/controllers/repository_rows_controller.rb +++ b/app/controllers/repository_rows_controller.rb @@ -213,6 +213,8 @@ class RepositoryRowsController < ApplicationController { repository_row: @repository_row.id, repository_column: update_params['repository_cells']&.keys&.first || I18n.t('repositories.table.row_name') }) + + record_annotation_notification(@repository_row, row_cell_update.cell) if row_cell_update.cell && row_cell_update.cell.value_type == 'RepositoryTextValue' end @reminders_present = @repository_row.repository_cells.with_active_reminder(@current_user).any? diff --git a/app/controllers/team_shared_objects_controller.rb b/app/controllers/team_shared_objects_controller.rb index fbbb25509..1132bb993 100644 --- a/app/controllers/team_shared_objects_controller.rb +++ b/app/controllers/team_shared_objects_controller.rb @@ -25,13 +25,9 @@ class TeamSharedObjectsController < ApplicationController case global_permission_level when :shared_read - UserAssignment.where(assignable: @model).where.not(team: @model.team).update!(user_role: UserRole.find_predefined_viewer_role) - TeamAssignment.where(assignable: @model).where.not(team: @model.team).update!(user_role: UserRole.find_predefined_viewer_role) - UserGroupAssignment.where(assignable: @model).where.not(team: @model.team).update!(user_role: UserRole.find_predefined_viewer_role) + @model.demote_all_sharing_assignments_to_viewer! when :not_shared - UserAssignment.where(assignable: @model).where.not(team: @model.team).destroy_all - TeamAssignment.where(assignable: @model).where.not(team: @model.team).destroy_all - UserGroupAssignment.where(assignable: @model).where.not(team: @model.team).destroy_all + @model.destroy_all_sharing_assignments! end case @model diff --git a/app/controllers/users/passwords_controller.rb b/app/controllers/users/passwords_controller.rb index 9b9644ab8..99c38f15e 100644 --- a/app/controllers/users/passwords_controller.rb +++ b/app/controllers/users/passwords_controller.rb @@ -5,9 +5,19 @@ class Users::PasswordsController < Devise::PasswordsController # end # POST /resource/password - # def create - # super - # end + def create + self.resource = resource_class.send_reset_password_instructions(resource_params) + yield resource if block_given? + + if resource.errors.added?(:email, :blank) + flash.now[:alert] = I18n.t('devise.errors.email.empty') + self.resource = resource_class.new + render :new + else + set_flash_message!(:notice, :send_instructions) + respond_with({}, location: after_sending_reset_password_instructions_path_for(resource_name)) + end + end # GET /resource/password/edit?reset_password_token=abcdef # def edit @@ -25,7 +35,7 @@ class Users::PasswordsController < Devise::PasswordsController flash_message = resource.active_for_authentication? ? :updated : :updated_not_active set_flash_message!(:notice, flash_message) resource.after_database_authentication if check_database_authentication?(resource) - sign_in(resource_name, resource) + sign_in(resource_name, resource, event: :authentication) else set_flash_message!(:notice, :updated_not_active) end diff --git a/app/controllers/users/settings/user_groups_controller.rb b/app/controllers/users/settings/user_groups_controller.rb index 92dc0c1e5..12e8530f7 100644 --- a/app/controllers/users/settings/user_groups_controller.rb +++ b/app/controllers/users/settings/user_groups_controller.rb @@ -5,10 +5,10 @@ module Users class UserGroupsController < ApplicationController before_action :load_team before_action :set_breadcrumbs_items, only: %i(index show) - before_action :check_user_groups_enabled + before_action :check_user_groups_enabled, except: :users before_action :load_user_group, except: %i(index unassigned_users actions_toolbar create) - before_action :check_read_permissions, only: %i(index show unassigned_users actions_toolbar users) - before_action :check_manage_permissions, except: %i(index show unassigned_users actions_toolbar users) + before_action :check_read_permissions, only: %i(users) + before_action :check_manage_permissions, except: %i(users) def index respond_to do |format| @@ -58,7 +58,7 @@ module Users end render json: { message: t('user_groups.create.success') }, status: :created else - render json: { errors: t('user_groups.create.error') }, status: :unprocessable_entity + render json: { error: @user_group.errors.full_messages.join(", ") }, status: :unprocessable_entity end end diff --git a/app/controllers/users/settings/user_teams_controller.rb b/app/controllers/users/settings/user_teams_controller.rb index ebf1ccbe4..f316ee7a6 100644 --- a/app/controllers/users/settings/user_teams_controller.rb +++ b/app/controllers/users/settings/user_teams_controller.rb @@ -109,11 +109,13 @@ module Users ) end + redirect_url = teams_path if params[:leave] + generate_notification(current_user, @user_assignment.user, @user_assignment.assignable, false) - render json: { status: :ok, job_id: job_id, success_message: success_message } + render json: { status: :ok, job_id: job_id, success_message: success_message, redirect_url: redirect_url } end end diff --git a/app/helpers/comment_helper.rb b/app/helpers/comment_helper.rb index 81aa82646..ba6dc2566 100644 --- a/app/helpers/comment_helper.rb +++ b/app/helpers/comment_helper.rb @@ -162,7 +162,7 @@ module CommentHelper smart_annotation_notification( old_text: old_text, new_text: comment.message, - subject: step.protocol, + subject: step, title: t('notifications.step_comment_annotation_title', step: step.name, user: current_user.full_name), diff --git a/app/helpers/user_roles_helper.rb b/app/helpers/user_roles_helper.rb index 7b03ebdbf..94f24db15 100644 --- a/app/helpers/user_roles_helper.rb +++ b/app/helpers/user_roles_helper.rb @@ -7,7 +7,7 @@ module UserRolesHelper viewer_role = UserRole.find_predefined_viewer_role roles = [[viewer_role.name, viewer_role.id]] else - permission_group = "#{object.class.name}Permissions".constantize + permission_group = "#{object.class.permission_class}Permissions".constantize permissions = permission_group.constants.map { |const| permission_group.const_get(const) } roles = user_roles_subset_by_permissions(permissions).order(id: :asc).pluck(:name, :id) diff --git a/app/javascript/vue/experiments/list.vue b/app/javascript/vue/experiments/list.vue index 87e335554..4e08b764c 100644 --- a/app/javascript/vue/experiments/list.vue +++ b/app/javascript/vue/experiments/list.vue @@ -171,6 +171,7 @@ export default { cellRendererParams: { statusesList: this.statusesList }, + notSelectable: true, minWidth: 180 }, { diff --git a/app/javascript/vue/experiments/renderers/status.vue b/app/javascript/vue/experiments/renderers/status.vue index 78fe66385..ef31f362a 100644 --- a/app/javascript/vue/experiments/renderers/status.vue +++ b/app/javascript/vue/experiments/renderers/status.vue @@ -39,9 +39,16 @@ export default { }, methods: { optionRenderer(option) { + let color = 'bg-sn-grey-500'; + if (option[0] === 'in_progress') { + color = 'bg-sn-science-blue'; + } else if (option[0] === 'done') { + color = 'bg-sn-alert-green'; + } + return `
-
+
${option[1]}
`; }, diff --git a/app/javascript/vue/item_relationships/RepositoryItemRelationshipsModal.vue b/app/javascript/vue/item_relationships/RepositoryItemRelationshipsModal.vue index 6e1d1bc1a..c641e324a 100644 --- a/app/javascript/vue/item_relationships/RepositoryItemRelationshipsModal.vue +++ b/app/javascript/vue/item_relationships/RepositoryItemRelationshipsModal.vue @@ -33,6 +33,7 @@