From 2c5ce1b5541db4fe1994c69cee4d85f4ba6fd9cb Mon Sep 17 00:00:00 2001 From: MontrealSergiy Date: Tue, 16 Apr 2024 16:32:10 -0400 Subject: [PATCH 01/12] data providers copy policy form/controller (simple) --- .../controllers/data_providers_controller.rb | 9 +++++--- BrainPortal/app/helpers/show_table_helper.rb | 4 +++- .../app/views/data_providers/show.html.erb | 22 ++++++++++++++++--- 3 files changed, 28 insertions(+), 7 deletions(-) diff --git a/BrainPortal/app/controllers/data_providers_controller.rb b/BrainPortal/app/controllers/data_providers_controller.rb index 24cd5e3f7..d1c906e14 100644 --- a/BrainPortal/app/controllers/data_providers_controller.rb +++ b/BrainPortal/app/controllers/data_providers_controller.rb @@ -152,7 +152,7 @@ def create_personal format.json { render :json => @provider } end end - + require 'pry' def update #:nodoc: @user = current_user id = params[:id] @@ -178,9 +178,12 @@ def update #:nodoc: # Fields that stay the same if the form provides a blank entry: new_data_provider_attr.delete :cloud_storage_client_token if new_data_provider_attr[:cloud_storage_client_token].blank? + binding.pry + if @provider.update_attributes_with_logging(new_data_provider_attr, current_user, @provider.attributes.keys + []) + mass_flags = 'dp_no_copy_new|dp_no_copy_toggle|rr_no_sync_new|rr_no_sync_toggle' # few_special flags that control other + # todo cast params to hash for rails 5.1 as `ActionController::Parameters` no longer inherits from hash + meta_flags_for_restrictions = (params[:meta] || {}).keys.grep(/\Adp_no_copy_\d+\z|\Arr_no_sync_\d+|#{mass_flags}\z/) - if @provider.update_attributes_with_logging(new_data_provider_attr, current_user, @provider.attributes.keys) - meta_flags_for_restrictions = (params[:meta] || {}).keys.grep(/\Adp_no_copy_\d+\z|\Arr_no_sync_\d+\z/) add_meta_data_from_form(@provider, [:must_move, :no_uploads, :no_viewers, :browse_gid] + meta_flags_for_restrictions) flash[:notice] = "Provider successfully updated." respond_to do |format| diff --git a/BrainPortal/app/helpers/show_table_helper.rb b/BrainPortal/app/helpers/show_table_helper.rb index 9fd6ed491..2207e4444 100644 --- a/BrainPortal/app/helpers/show_table_helper.rb +++ b/BrainPortal/app/helpers/show_table_helper.rb @@ -197,12 +197,14 @@ def edit_cell(field, options = {}, &block) # As +boolean_edit_cell+ is a specialization of +edit_cell+, +field+, # +&block+ and +options+ are handled the same way (save for the defaults # outlined above). + # +input_options+ apply only to the checkbox itself (works only in edit mode and in absence of block) def boolean_edit_cell(field, cur_value, checked_value = "1", unchecked_value = "0", options = {}, &block) options[:content] ||= @template.disabled_checkbox(cur_value == checked_value) + input_options = options.delete(:input_options) || {} if block_given? edit_cell(field, options, &block) else - edit_cell(field, options) { @template.hidden_field_tag(field, unchecked_value) + @template.check_box_tag(field, checked_value, cur_value == checked_value) } + edit_cell(field, options) { @template.hidden_field_tag(field, unchecked_value) + @template.check_box_tag(field, checked_value, cur_value == checked_value, input_options) } end end diff --git a/BrainPortal/app/views/data_providers/show.html.erb b/BrainPortal/app/views/data_providers/show.html.erb index fd5de1b3d..70aac7ee9 100644 --- a/BrainPortal/app/views/data_providers/show.html.erb +++ b/BrainPortal/app/views/data_providers/show.html.erb @@ -224,11 +224,27 @@ <%= show_table(@provider, :as => :data_provider, :width => 5, :header => 'Files can be copied or moved to these other Data Providers', :edit_condition => (check_role(:admin_user) || @provider.user_id == current_user.id)) do |t| %> <% if dps_by_category[:official] %> - <% t.row(:class => 'subheader') { "Official Storage".html_safe } %> + + <% meta_key = "dp_no_copy_toggle" %> + <% t.boolean_edit_cell("meta[_dummy_field]", @provider.meta[meta_key].to_s, "", "disabled", :header => "Toggle all", :class => 'checkbox_label') do %> + <%#= select_all_checkbox("dp_box", :persistant_name => meta_key, :id => :existing_select_all) %> + <%= select_all_checkbox("dp_box", :id => :existing_select_all) %> + <% end %> + <% meta_key = "dp_no_copy_new" %> + <% t.boolean_edit_cell("meta[#{meta_key}]", @provider.meta[meta_key].to_s, "", "disabled", :header => "Default to", :class => 'checkbox_label') %> + <% t.cell("on all future providers", :no_header => "explanations")do %> +   (on all the future providers) + <% end %> + <% t.blank_row %> + <% t.row(:class => 'subheader') do %> + Official Storage + <% end %> + <% dps_by_category[:official].sort_by(&:name).each do |dp| %> <% meta_key = "dp_no_copy_#{dp.id}" %> - <% t.boolean_edit_cell("meta[#{meta_key}]", @provider.meta[meta_key].to_s, "", "disabled", :header => "#{dp.name}", :class => 'checkbox_label') %> + <% t.boolean_edit_cell("meta[#{meta_key}]", @provider.meta[meta_key].to_s, "", "disabled", :header => "#{dp.name}", :class => 'checkbox_label', :input_options => { class: "dp_box" } ) %> <% end%> + <% end%> <% t.blank_row %> @@ -237,7 +253,7 @@ <% t.row(:class => 'subheader') { "User or Site Storage".html_safe } %> <% dps_by_category[:user].sort_by(&:name).each do |dp| %> <% meta_key = "dp_no_copy_#{dp.id}" %> - <% t.boolean_edit_cell("meta[#{meta_key}]", @provider.meta[meta_key].to_s, "", "disabled", :header => "#{dp.name}", :class => 'checkbox_label') %> + <% t.boolean_edit_cell("meta[#{meta_key}]", @provider.meta[meta_key].to_s, "", "disabled", :header => "#{dp.name}", :class => 'checkbox_label', :input_options => { class: "dp_box" }) %> <% end%> <% end%> <% end%> From 5ef346eeff261d17cd7220bcd01641574955b699 Mon Sep 17 00:00:00 2001 From: MontrealSergiy Date: Tue, 16 Apr 2024 16:33:27 -0400 Subject: [PATCH 02/12] dp policy (simple) - use callback to assign to rules to default --- BrainPortal/app/models/data_provider.rb | 28 +++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/BrainPortal/app/models/data_provider.rb b/BrainPortal/app/models/data_provider.rb index 96e0f22e6..5c40af253 100644 --- a/BrainPortal/app/models/data_provider.rb +++ b/BrainPortal/app/models/data_provider.rb @@ -247,6 +247,8 @@ class DataProvider < ApplicationRecord # Resource usage is kept forever even if data provider is destroyed. has_many :resource_usage + after_create :update_copy_policies + api_attr_visible :name, :type, :user_id, :group_id, :online, :read_only, :description # This value is used to trigger DP cache wipes @@ -809,6 +811,32 @@ def provider_move_to_otherprovider(userfile, otherprovider, options = {}) true end + # updates copying policies for exisiting dataproviders + def update_copy_policies + + # Define the conditions to select records + conditions = { + ar_table_name: 'data_providers', + meta_key: 'dp_no_copy_new', + meta_value: 'disabled' + } + + # Select the records based on the conditions + records_to_insert = MetaDataStore.where(conditions).pluck(:ar_id).map do |ar_id| + { + ar_table_name: 'data_providers', + ar_id: ar_id, + meta_key: "dp_no_copy_#{self.id}", + meta_value: 'disabled' + } + end + + # Insert the selected records + MetaDataStore.create(records_to_insert) # might be slow, yet in Rails 6, can be updated + # to insert_all for SQL-like performance + end + + # Copy a +userfile+ from the current provider to +otherprovider+. # Returns the new userfile if data was actually copied, true if # no copy was necessary, and false if anything was amiss. From 68213229099aedc91ddaa0298bddca783b438bc7 Mon Sep 17 00:00:00 2001 From: MontrealSergiy Date: Wed, 17 Apr 2024 12:32:07 -0400 Subject: [PATCH 03/12] dp policy - simple toggle box --- BrainPortal/app/views/data_providers/show.html.erb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/BrainPortal/app/views/data_providers/show.html.erb b/BrainPortal/app/views/data_providers/show.html.erb index 70aac7ee9..d255a7e9f 100644 --- a/BrainPortal/app/views/data_providers/show.html.erb +++ b/BrainPortal/app/views/data_providers/show.html.erb @@ -225,8 +225,8 @@ <%= show_table(@provider, :as => :data_provider, :width => 5, :header => 'Files can be copied or moved to these other Data Providers', :edit_condition => (check_role(:admin_user) || @provider.user_id == current_user.id)) do |t| %> <% if dps_by_category[:official] %> - <% meta_key = "dp_no_copy_toggle" %> - <% t.boolean_edit_cell("meta[_dummy_field]", @provider.meta[meta_key].to_s, "", "disabled", :header => "Toggle all", :class => 'checkbox_label') do %> + + <% t.boolean_edit_cell("Toggle all", 0, :header => "All", :class => 'checkbox_label') do %> <%#= select_all_checkbox("dp_box", :persistant_name => meta_key, :id => :existing_select_all) %> <%= select_all_checkbox("dp_box", :id => :existing_select_all) %> <% end %> From 430480efde87f1a087e22e1ae79a56a3587bcc49 Mon Sep 17 00:00:00 2001 From: MontrealSergiy Date: Fri, 19 Apr 2024 16:58:00 -0400 Subject: [PATCH 04/12] dp policy - simple toggle box layout --- BrainPortal/app/views/data_providers/show.html.erb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/BrainPortal/app/views/data_providers/show.html.erb b/BrainPortal/app/views/data_providers/show.html.erb index d255a7e9f..af595082e 100644 --- a/BrainPortal/app/views/data_providers/show.html.erb +++ b/BrainPortal/app/views/data_providers/show.html.erb @@ -225,8 +225,10 @@ <%= show_table(@provider, :as => :data_provider, :width => 5, :header => 'Files can be copied or moved to these other Data Providers', :edit_condition => (check_role(:admin_user) || @provider.user_id == current_user.id)) do |t| %> <% if dps_by_category[:official] %> - - <% t.boolean_edit_cell("Toggle all", 0, :header => "All", :class => 'checkbox_label') do %> + <% t.row(:class => 'subheader') do %> + Mass controls + <% end %> + <% t.boolean_edit_cell("Unsaved toggle", "", "", "", :header => "Toggle all", :class => 'checkbox_label') do %> <%#= select_all_checkbox("dp_box", :persistant_name => meta_key, :id => :existing_select_all) %> <%= select_all_checkbox("dp_box", :id => :existing_select_all) %> <% end %> From 856b9d41d4cbe5a4518ab5c27eeafeeb9462a887 Mon Sep 17 00:00:00 2001 From: MontrealSergiy Date: Tue, 23 Apr 2024 09:43:35 -0400 Subject: [PATCH 05/12] dp policy - simple toggle box layout --- .../controllers/data_providers_controller.rb | 5 +- BrainPortal/app/models/data_provider.rb | 19 +++-- .../app/views/data_providers/show.html.erb | 36 +++++++-- BrainPortal/public/javascripts/cbrain.js | 2 + .../cbrain/data_providers/tribox.js | 78 +++++++++++++++++++ 5 files changed, 125 insertions(+), 15 deletions(-) create mode 100644 BrainPortal/public/javascripts/cbrain/data_providers/tribox.js diff --git a/BrainPortal/app/controllers/data_providers_controller.rb b/BrainPortal/app/controllers/data_providers_controller.rb index d1c906e14..0303337a5 100644 --- a/BrainPortal/app/controllers/data_providers_controller.rb +++ b/BrainPortal/app/controllers/data_providers_controller.rb @@ -152,7 +152,7 @@ def create_personal format.json { render :json => @provider } end end - require 'pry' + def update #:nodoc: @user = current_user id = params[:id] @@ -178,9 +178,8 @@ def update #:nodoc: # Fields that stay the same if the form provides a blank entry: new_data_provider_attr.delete :cloud_storage_client_token if new_data_provider_attr[:cloud_storage_client_token].blank? - binding.pry if @provider.update_attributes_with_logging(new_data_provider_attr, current_user, @provider.attributes.keys + []) - mass_flags = 'dp_no_copy_new|dp_no_copy_toggle|rr_no_sync_new|rr_no_sync_toggle' # few_special flags that control other + mass_flags = 'dp_no_copy_default|rr_no_sync_default' # few_special flags that control other # todo cast params to hash for rails 5.1 as `ActionController::Parameters` no longer inherits from hash meta_flags_for_restrictions = (params[:meta] || {}).keys.grep(/\Adp_no_copy_\d+\z|\Arr_no_sync_\d+|#{mass_flags}\z/) diff --git a/BrainPortal/app/models/data_provider.rb b/BrainPortal/app/models/data_provider.rb index 5c40af253..b046fd523 100644 --- a/BrainPortal/app/models/data_provider.rb +++ b/BrainPortal/app/models/data_provider.rb @@ -817,7 +817,7 @@ def update_copy_policies # Define the conditions to select records conditions = { ar_table_name: 'data_providers', - meta_key: 'dp_no_copy_new', + meta_key: 'dp_no_copy_default', meta_value: 'disabled' } @@ -1407,11 +1407,20 @@ def rr_allowed_syncing!(server_does_what = "access the files of", rr = RemoteRes # Returns true if the DataProvider is allowed to copy or move files to the # other DataProvider +other_dp+ . - # The information for this restriction is maintained - # as a blacklist in the meta data store. + # The information for this restriction is maintained by default value + # along with a white- and blacklist, whitelist in the meta data store. def dp_allows_copy?(other_dp) - meta_key_disabled = "dp_no_copy_#{other_dp.id}" - self.meta[meta_key_disabled].blank? + meta_key = "dp_no_copy_#{other_dp.id}" + # if there is no explicit flag for particular provider + # fall back on the default policy + default = self.meta["dp_no_copy_default"] + return ( self.meta[meta_key].presence || default ) != "disabled" + # hacky equivalent of + # return true if self.meta[meta_key] == 'copy' # yes if whitelisted + # self.meta[meta_key].blank? && default != "disabled" # otherwise by dafault + + + end # Works like dp_allows_copy? but raises an exception if the diff --git a/BrainPortal/app/views/data_providers/show.html.erb b/BrainPortal/app/views/data_providers/show.html.erb index af595082e..93a270f4c 100644 --- a/BrainPortal/app/views/data_providers/show.html.erb +++ b/BrainPortal/app/views/data_providers/show.html.erb @@ -22,6 +22,8 @@ # -%> + + <% title 'Data Provider Info' %> <% has_owner_access = (check_role(:admin_user) || @provider.user_id == current_user.id) %> @@ -229,13 +231,15 @@ Mass controls <% end %> <% t.boolean_edit_cell("Unsaved toggle", "", "", "", :header => "Toggle all", :class => 'checkbox_label') do %> - <%#= select_all_checkbox("dp_box", :persistant_name => meta_key, :id => :existing_select_all) %> - <%= select_all_checkbox("dp_box", :id => :existing_select_all) %> + <%#= select_all_checkbox("dp_box", :persistant_name => meta_key, :id => :dp_select_all) %> + <%= select_all_checkbox("dp_box", :id => :dp_select_all) %> <% end %> - <% meta_key = "dp_no_copy_new" %> - <% t.boolean_edit_cell("meta[#{meta_key}]", @provider.meta[meta_key].to_s, "", "disabled", :header => "Default to", :class => 'checkbox_label') %> + <% default_key = "dp_no_copy_default" %> + + <% default_value = @provider.meta[default_key] || "copy" %> + <% t.boolean_edit_cell("meta[#{default_key}]", default_value, "copy", "disabled", :header => "Default to", :class => 'checkbox_label') %> <% t.cell("on all future providers", :no_header => "explanations")do %> -   (on all the future providers) +   on all new (in italic) and the future providers <% end %> <% t.blank_row %> <% t.row(:class => 'subheader') do %> @@ -244,7 +248,14 @@ <% dps_by_category[:official].sort_by(&:name).each do |dp| %> <% meta_key = "dp_no_copy_#{dp.id}" %> - <% t.boolean_edit_cell("meta[#{meta_key}]", @provider.meta[meta_key].to_s, "", "disabled", :header => "#{dp.name}", :class => 'checkbox_label', :input_options => { class: "dp_box" } ) %> + <% meta_value = @provider.meta[meta_key] %> + <% if meta_value.present? %> + <% t.boolean_edit_cell("meta[#{meta_key}]", meta_value, "copy", "disabled", :header => "#{dp.name}", :class => 'checkbox_label', :input_options => { class: "dp_box" } ) %> + <% else %> + <%# for not yet blacklisted/whitelisted, italic header %> + <%# javascript to set checkbox to indeterminate state %> + <% t.boolean_edit_cell("meta[#{meta_key}]", default_value, "copy", "disable", :header => "#{dp.name}".html_safe, :class => 'checkbox_label', :input_options => { class: "dp_box indeterminate" } ) %> + <% end %> <% end%> <% end%> @@ -255,7 +266,14 @@ <% t.row(:class => 'subheader') { "User or Site Storage".html_safe } %> <% dps_by_category[:user].sort_by(&:name).each do |dp| %> <% meta_key = "dp_no_copy_#{dp.id}" %> - <% t.boolean_edit_cell("meta[#{meta_key}]", @provider.meta[meta_key].to_s, "", "disabled", :header => "#{dp.name}", :class => 'checkbox_label', :input_options => { class: "dp_box" }) %> + <% meta_value = @provider.meta[meta_key] %> + <% if meta_value.present? %> + <% t.boolean_edit_cell("meta[#{meta_key}]", meta_value, "copy", "disabled", :header => "#{dp.name}", :class => 'checkbox_label', :input_options => { class: "dp_box" } ) %> + <% else %> + <%# for not yet blacklisted/whitelisted, italic header %> + <%# javascript will set checkbox to indeterminate state %> + <% t.boolean_edit_cell("meta[#{meta_key}]", default_value, "copy", "disable", :header => "#{dp.name}".html_safe, :class => 'checkbox_label', :input_options => { class: "dp_box indeterminate" } ) %> + <% end %> <% end%> <% end%> <% end%> @@ -309,3 +327,7 @@ <%= render :partial => "layouts/log_report", :locals => { :log => @provider.getlog, :title => "Data Provider Log" } %> <% end %> +<% content_for :scripts do %> + <%= javascript_include_tag 'cbrain/data_providers/tribox' %> +<% end %> + diff --git a/BrainPortal/public/javascripts/cbrain.js b/BrainPortal/public/javascripts/cbrain.js index 8dd335e87..f10e1ad41 100644 --- a/BrainPortal/public/javascripts/cbrain.js +++ b/BrainPortal/public/javascripts/cbrain.js @@ -640,6 +640,8 @@ $('.' + checkbox_class).each(function(index, element) { element.checked = header_box.prop('checked'); + // todo add artificial event, e.g. to propagage changes with tri-state checkboxes + // smth like element.trigger("code-change") }); }; diff --git a/BrainPortal/public/javascripts/cbrain/data_providers/tribox.js b/BrainPortal/public/javascripts/cbrain/data_providers/tribox.js new file mode 100644 index 000000000..7cdbef3d6 --- /dev/null +++ b/BrainPortal/public/javascripts/cbrain/data_providers/tribox.js @@ -0,0 +1,78 @@ +// +// <%- +// # +// # CBRAIN Project +// # +// # Copyright (C) 2008-2012 +// # The Royal Institution for the Advancement of Learning +// # McGill University +// # +// # This program is free software: you can redistribute it and/or modify +// # it under the terms of the GNU General Public License as published by +// # the Free Software Foundation, either version 3 of the License, or +// # (at your option) any later version. +// # +// # This program is distributed in the hope that it will be useful, +// # but WITHOUT ANY WARRANTY; without even the implied warranty of +// # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// # GNU General Public License for more details. +// # +// # You should have received a copy of the GNU General Public License +// # along with this program. If not, see . +// # +// -%> + +// JS to add indetermitate state to certanain checkboxes + +// indeterminate state on can be set with JS +// all elements with empty value are set as indeterminate +jQuery(".show_table_edit_link").on("click", + function() { + $(".dp_box.indeterminate").each( + function () { + $(this).prop("indeterminate", true); + let prev = $(this).prev(); + let val = prev.val(); + if ( val != '' ) { + prev.val(""); + } + } + ); + $(".dp_box.indeterminate").click( + function () { + $(this).val('copy'); + let prev = $(this).prev(); + prev.val("disable"); } + ) + + + + + } +); + +// make indeterminate elements determinate again +jQuery(".show_table").on("click code-change", ".dp_box.indeterminate", function() { + $(this).each(function() { + // $(this).prop("indeterminate", false); // usually happens automatically + $(this).val('copy') + // change value of hidden element back to disabled + $(this).prev().val("disabled") + }); +}); + + +// makes indetermintate checkbox determinate +// function determinize(el) { +// el.prop("indeterminate", false); +// // change value of hidden element +// el.prev().val('copy'); +// } + +// all elements with empty value are set as indeterminate + + + + + + From 7598c19378522f38f4200ab8ef79c321372ea8a3 Mon Sep 17 00:00:00 2001 From: MontrealSergiy Date: Thu, 25 Apr 2024 16:34:48 -0400 Subject: [PATCH 06/12] dp policy - indeterminate class css and minor improvements --- .../app/assets/stylesheets/cbrain.css.erb | 10 ++++ .../app/views/data_providers/show.html.erb | 13 +++-- .../cbrain/data_providers/tribox.js | 49 +++++++++---------- 3 files changed, 40 insertions(+), 32 deletions(-) diff --git a/BrainPortal/app/assets/stylesheets/cbrain.css.erb b/BrainPortal/app/assets/stylesheets/cbrain.css.erb index b925a5dd2..b6b3cf9d0 100644 --- a/BrainPortal/app/assets/stylesheets/cbrain.css.erb +++ b/BrainPortal/app/assets/stylesheets/cbrain.css.erb @@ -2655,3 +2655,13 @@ img { .no-close .ui-dialog-titlebar-close { display: none; } + +.indefinite { + color: steelblue !important; +} + +.indefinite_checkbox_label { + color: steelblue !important; + + font-weight: normal !important; +} \ No newline at end of file diff --git a/BrainPortal/app/views/data_providers/show.html.erb b/BrainPortal/app/views/data_providers/show.html.erb index 93a270f4c..f7d70487e 100644 --- a/BrainPortal/app/views/data_providers/show.html.erb +++ b/BrainPortal/app/views/data_providers/show.html.erb @@ -22,7 +22,6 @@ # -%> - <% title 'Data Provider Info' %> @@ -230,7 +229,7 @@ <% t.row(:class => 'subheader') do %> Mass controls <% end %> - <% t.boolean_edit_cell("Unsaved toggle", "", "", "", :header => "Toggle all", :class => 'checkbox_label') do %> + <% t.boolean_edit_cell("Unsaved toggle", "", "", "", :header => "Reset old to", :class => 'checkbox_label') do %> <%#= select_all_checkbox("dp_box", :persistant_name => meta_key, :id => :dp_select_all) %> <%= select_all_checkbox("dp_box", :id => :dp_select_all) %> <% end %> @@ -238,8 +237,8 @@ <% default_value = @provider.meta[default_key] || "copy" %> <% t.boolean_edit_cell("meta[#{default_key}]", default_value, "copy", "disabled", :header => "Default to", :class => 'checkbox_label') %> - <% t.cell("on all future providers", :no_header => "explanations")do %> -   on all new (in italic) and the future providers + <% t.cell("on all future providers", :no_header => "explanations", :class => "indefinite_checkbox_label") do %> +   on all new (in italic ) and the future providers <% end %> <% t.blank_row %> <% t.row(:class => 'subheader') do %> @@ -253,8 +252,8 @@ <% t.boolean_edit_cell("meta[#{meta_key}]", meta_value, "copy", "disabled", :header => "#{dp.name}", :class => 'checkbox_label', :input_options => { class: "dp_box" } ) %> <% else %> <%# for not yet blacklisted/whitelisted, italic header %> - <%# javascript to set checkbox to indeterminate state %> - <% t.boolean_edit_cell("meta[#{meta_key}]", default_value, "copy", "disable", :header => "#{dp.name}".html_safe, :class => 'checkbox_label', :input_options => { class: "dp_box indeterminate" } ) %> + <%# javascript will set checkbox's indeterminate state attribute %> + <% t.boolean_edit_cell("meta[#{meta_key}]", default_value, "copy", "disable", :header => "#{dp.name}".html_safe, :class => 'checkbox_label indefinite_checkbox_label', :input_options => { class: "dp_box indeterminate" } ) %> <% end %> <% end%> @@ -272,7 +271,7 @@ <% else %> <%# for not yet blacklisted/whitelisted, italic header %> <%# javascript will set checkbox to indeterminate state %> - <% t.boolean_edit_cell("meta[#{meta_key}]", default_value, "copy", "disable", :header => "#{dp.name}".html_safe, :class => 'checkbox_label', :input_options => { class: "dp_box indeterminate" } ) %> + <% t.boolean_edit_cell("meta[#{meta_key}]", default_value, "copy", "disable", :header => "#{dp.name}".html_safe, :class => 'checkbox_label indefinite_checkbox_label', :input_options => { class: "dp_box indeterminate" } ) %> <% end %> <% end%> <% end%> diff --git a/BrainPortal/public/javascripts/cbrain/data_providers/tribox.js b/BrainPortal/public/javascripts/cbrain/data_providers/tribox.js index 7cdbef3d6..1d645cd76 100644 --- a/BrainPortal/public/javascripts/cbrain/data_providers/tribox.js +++ b/BrainPortal/public/javascripts/cbrain/data_providers/tribox.js @@ -1,28 +1,26 @@ // -// <%- -// # -// # CBRAIN Project -// # -// # Copyright (C) 2008-2012 -// # The Royal Institution for the Advancement of Learning -// # McGill University -// # -// # This program is free software: you can redistribute it and/or modify -// # it under the terms of the GNU General Public License as published by -// # the Free Software Foundation, either version 3 of the License, or -// # (at your option) any later version. -// # -// # This program is distributed in the hope that it will be useful, -// # but WITHOUT ANY WARRANTY; without even the implied warranty of -// # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// # GNU General Public License for more details. -// # -// # You should have received a copy of the GNU General Public License -// # along with this program. If not, see . -// # -// -%> - -// JS to add indetermitate state to certanain checkboxes +// CBRAIN Project +// +// Copyright (C) 2008-2012 +// The Royal Institution for the Advancement of Learning +// McGill University +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +// + +// JS to add indetermitate state to checkboxes with indeterninate style // indeterminate state on can be set with JS // all elements with empty value are set as indeterminate @@ -31,9 +29,10 @@ jQuery(".show_table_edit_link").on("click", $(".dp_box.indeterminate").each( function () { $(this).prop("indeterminate", true); + $(this).val(""); let prev = $(this).prev(); let val = prev.val(); - if ( val != '' ) { + if ( val != "" ) { prev.val(""); } } From 172ed5b022d89c6f48985224bb1f7891b579990e Mon Sep 17 00:00:00 2001 From: MontrealSergiy Date: Fri, 26 Apr 2024 14:17:36 -0400 Subject: [PATCH 07/12] dp policy - indeterminate class simpler js --- .../app/views/data_providers/show.html.erb | 4 ++-- .../cbrain/data_providers/tribox.js | 24 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/BrainPortal/app/views/data_providers/show.html.erb b/BrainPortal/app/views/data_providers/show.html.erb index f7d70487e..b90dbbd7f 100644 --- a/BrainPortal/app/views/data_providers/show.html.erb +++ b/BrainPortal/app/views/data_providers/show.html.erb @@ -253,7 +253,7 @@ <% else %> <%# for not yet blacklisted/whitelisted, italic header %> <%# javascript will set checkbox's indeterminate state attribute %> - <% t.boolean_edit_cell("meta[#{meta_key}]", default_value, "copy", "disable", :header => "#{dp.name}".html_safe, :class => 'checkbox_label indefinite_checkbox_label', :input_options => { class: "dp_box indeterminate" } ) %> + <% t.boolean_edit_cell("meta[#{meta_key}]", default_value, "copy", "disabled", :header => "#{dp.name}".html_safe, :class => 'checkbox_label indefinite_checkbox_label', :input_options => { class: "dp_box indeterminate" } ) %> <% end %> <% end%> @@ -271,7 +271,7 @@ <% else %> <%# for not yet blacklisted/whitelisted, italic header %> <%# javascript will set checkbox to indeterminate state %> - <% t.boolean_edit_cell("meta[#{meta_key}]", default_value, "copy", "disable", :header => "#{dp.name}".html_safe, :class => 'checkbox_label indefinite_checkbox_label', :input_options => { class: "dp_box indeterminate" } ) %> + <% t.boolean_edit_cell("meta[#{meta_key}]", default_value, "copy", "disabled", :header => "#{dp.name}".html_safe, :class => 'checkbox_label indefinite_checkbox_label', :input_options => { class: "dp_box indeterminate" } ) %> <% end %> <% end%> <% end%> diff --git a/BrainPortal/public/javascripts/cbrain/data_providers/tribox.js b/BrainPortal/public/javascripts/cbrain/data_providers/tribox.js index 1d645cd76..06c77fd85 100644 --- a/BrainPortal/public/javascripts/cbrain/data_providers/tribox.js +++ b/BrainPortal/public/javascripts/cbrain/data_providers/tribox.js @@ -24,35 +24,35 @@ // indeterminate state on can be set with JS // all elements with empty value are set as indeterminate -jQuery(".show_table_edit_link").on("click", - function() { +$(".show_table_edit_link").click( + function () { $(".dp_box.indeterminate").each( function () { $(this).prop("indeterminate", true); $(this).val(""); let prev = $(this).prev(); let val = prev.val(); - if ( val != "" ) { + if (val == "disabled") { prev.val(""); } } - ); + ) + } + ); + + $(".dp_box.indeterminate").click( function () { $(this).val('copy'); let prev = $(this).prev(); - prev.val("disable"); } + prev.val("disable"); + } ) - - - } -); - // make indeterminate elements determinate again -jQuery(".show_table").on("click code-change", ".dp_box.indeterminate", function() { - $(this).each(function() { +jQuery(".show_table").on("click code-change", ".dp_box.indeterminate", function () { + $(this).each(function () { // $(this).prop("indeterminate", false); // usually happens automatically $(this).val('copy') // change value of hidden element back to disabled From 960490430aad95603f9b86612bce60f2795b7613 Mon Sep 17 00:00:00 2001 From: MontrealSergiy Date: Tue, 30 Apr 2024 09:15:17 -0400 Subject: [PATCH 08/12] dp policy - add server panel, misc improvements --- .../app/assets/stylesheets/cbrain.css.erb | 4 +- BrainPortal/app/models/data_provider.rb | 33 ++-------- .../app/views/data_providers/show.html.erb | 60 ++++++++++++------- .../cbrain/data_providers/tribox.js | 2 +- 4 files changed, 47 insertions(+), 52 deletions(-) diff --git a/BrainPortal/app/assets/stylesheets/cbrain.css.erb b/BrainPortal/app/assets/stylesheets/cbrain.css.erb index b6b3cf9d0..4c9d3873c 100644 --- a/BrainPortal/app/assets/stylesheets/cbrain.css.erb +++ b/BrainPortal/app/assets/stylesheets/cbrain.css.erb @@ -2656,11 +2656,11 @@ img { display: none; } -.indefinite { +.indeterminate { color: steelblue !important; } -.indefinite_checkbox_label { +.indeterminate_box_label { color: steelblue !important; font-weight: normal !important; diff --git a/BrainPortal/app/models/data_provider.rb b/BrainPortal/app/models/data_provider.rb index b046fd523..0eec1e1ad 100644 --- a/BrainPortal/app/models/data_provider.rb +++ b/BrainPortal/app/models/data_provider.rb @@ -247,8 +247,6 @@ class DataProvider < ApplicationRecord # Resource usage is kept forever even if data provider is destroyed. has_many :resource_usage - after_create :update_copy_policies - api_attr_visible :name, :type, :user_id, :group_id, :online, :read_only, :description # This value is used to trigger DP cache wipes @@ -811,31 +809,6 @@ def provider_move_to_otherprovider(userfile, otherprovider, options = {}) true end - # updates copying policies for exisiting dataproviders - def update_copy_policies - - # Define the conditions to select records - conditions = { - ar_table_name: 'data_providers', - meta_key: 'dp_no_copy_default', - meta_value: 'disabled' - } - - # Select the records based on the conditions - records_to_insert = MetaDataStore.where(conditions).pluck(:ar_id).map do |ar_id| - { - ar_table_name: 'data_providers', - ar_id: ar_id, - meta_key: "dp_no_copy_#{self.id}", - meta_value: 'disabled' - } - end - - # Insert the selected records - MetaDataStore.create(records_to_insert) # might be slow, yet in Rails 6, can be updated - # to insert_all for SQL-like performance - end - # Copy a +userfile+ from the current provider to +otherprovider+. # Returns the new userfile if data was actually copied, true if @@ -1392,8 +1365,10 @@ def self.cleanup_leftover_cache_files(do_it=false, options={}) # as a blacklist in the meta data store. def rr_allowed_syncing?(rr = RemoteResource.current_resource, check_dp = self) rr ||= RemoteResource.current_resource - meta_key_disabled = "rr_no_sync_#{rr.id}" - check_dp.meta[meta_key_disabled].blank? + meta_key = "rr_no_sync_#{rr.id}" + default = check_dp.meta["rr_no_sync_default"] || 'allowed' + policy = ( self.meta[meta_key].presence || default ) + return policy.length > 7 # it is faster check length end # Works like rr_allowed_syncing? but raise an exception when the diff --git a/BrainPortal/app/views/data_providers/show.html.erb b/BrainPortal/app/views/data_providers/show.html.erb index b90dbbd7f..c1c985912 100644 --- a/BrainPortal/app/views/data_providers/show.html.erb +++ b/BrainPortal/app/views/data_providers/show.html.erb @@ -29,6 +29,16 @@ <% is_userkey_dp = @provider.is_a?(UserkeyFlatDirSshDataProvider) %> <% needs_ssh_config = @provider.is_a?(SshDataProvider) || @provider.is_a?(SmartDataProviderInterface) %> +<% def tribox(t, model, meta_key, meta_value, default_value, cls) # creates tristate checkbox for table + if meta_value.present? + t.boolean_edit_cell("meta[#{meta_key}]", meta_value, "allowed", "disabled", :header => "#{model.name}", :class => 'checkbox_label', :input_options => { class: cls } ) + else + t.boolean_edit_cell("meta[#{meta_key}]", default_value, "allowed", "disabled", :header => "#{model.name}".html_safe, :class => 'checkbox_label indeterminate_box_label', :input_options => { class: "#{cls} indeterminate" } ) + end + end +%> + +