mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-13 16:45:18 +08:00
Merge pull request #1851 from okriuchykhin/ok_SCI_3436
Implement saving of attachments ordering on steps [SCI-3436]
This commit is contained in:
commit
db7c6435b3
11 changed files with 94 additions and 21 deletions
|
@ -667,13 +667,20 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reorder attachments
|
// Reorder attachments
|
||||||
global.reorderAttachments = function reorderAtt(stepId, sortType) {
|
global.reorderAttachments = function reorderAtt(elem, stepId, sortType) {
|
||||||
var label_value = $("#dd-att-step-" + stepId + "> .dropdown-menu > li > a[data-order=" + sortType + "]").html();
|
var label_value = $("#dd-att-step-" + stepId + "> .dropdown-menu > li > a[data-order=" + sortType + "]").html();
|
||||||
$("#dd-att-step-" + stepId + "-label").html(label_value);
|
$("#dd-att-step-" + stepId + "-label").html(label_value);
|
||||||
$('#att-' + stepId + ' a.file-preview-link').each(function(){
|
$('#att-' + stepId + ' a.file-preview-link').each(function(){
|
||||||
var elm = $(this)
|
var elm = $(this)
|
||||||
elm.parent().css('order', elm.attr('data-order-' + sortType));
|
elm.parent().css('order', elm.attr('data-order-' + sortType));
|
||||||
})
|
});
|
||||||
|
|
||||||
|
$.post(
|
||||||
|
$(elem).closest('.dropdown-menu').data('stateSavePath'),
|
||||||
|
{ assets: { order: sortType } },
|
||||||
|
null,
|
||||||
|
'json',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// On init
|
// On init
|
||||||
|
|
|
@ -3,12 +3,11 @@ class StepsController < ApplicationController
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
include StepsActions
|
include StepsActions
|
||||||
|
|
||||||
before_action :load_vars, only: %i(edit update destroy show toggle_step_state
|
before_action :load_vars, only: %i(edit update destroy show toggle_step_state checklistitem_state update_view_state)
|
||||||
checklistitem_state)
|
|
||||||
before_action :load_vars_nested, only: [:new, :create]
|
before_action :load_vars_nested, only: [:new, :create]
|
||||||
before_action :convert_table_contents_to_utf8, only: [:create, :update]
|
before_action :convert_table_contents_to_utf8, only: [:create, :update]
|
||||||
|
|
||||||
before_action :check_view_permissions, only: [:show]
|
before_action :check_view_permissions, only: %i(show update_view_state)
|
||||||
before_action :check_manage_permissions, only: %i(new create edit update
|
before_action :check_manage_permissions, only: %i(new create edit update
|
||||||
destroy)
|
destroy)
|
||||||
before_action :check_complete_and_checkbox_permissions, only:
|
before_action :check_complete_and_checkbox_permissions, only:
|
||||||
|
@ -190,6 +189,17 @@ class StepsController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def update_view_state
|
||||||
|
view_state = @step.current_view_state(current_user)
|
||||||
|
view_state.state['assets']['sort'] = params.require(:assets).require(:order)
|
||||||
|
view_state.save! if view_state.changed?
|
||||||
|
respond_to do |format|
|
||||||
|
format.json do
|
||||||
|
render json: {}, status: :ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def destroy
|
def destroy
|
||||||
if @step.can_destroy?
|
if @step.can_destroy?
|
||||||
# Update position on other steps of this module
|
# Update position on other steps of this module
|
||||||
|
|
|
@ -8,11 +8,19 @@ module MyModulesHelper
|
||||||
end
|
end
|
||||||
|
|
||||||
def ordered_assets(step)
|
def ordered_assets(step)
|
||||||
step.assets.order(:file_updated_at)
|
view_state = step.current_view_state(current_user)
|
||||||
|
sort = case view_state.state.dig('assets', 'sort')
|
||||||
|
when 'old' then { created_at: :asc }
|
||||||
|
when 'atoz' then { file_file_name: :asc }
|
||||||
|
when 'ztoa' then { file_file_name: :desc }
|
||||||
|
else { created_at: :desc }
|
||||||
end
|
end
|
||||||
|
|
||||||
def az_ordered_assets_index(step, asset_id)
|
step.assets.order(sort)
|
||||||
step.assets.order('LOWER(file_file_name)').pluck(:id).index(asset_id)
|
end
|
||||||
|
|
||||||
|
def az_ordered_assets_index(assets, asset_id)
|
||||||
|
assets.sort_by(&:file_file_name).map(&:id).index(asset_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def number_of_samples(my_module)
|
def number_of_samples(my_module)
|
||||||
|
|
|
@ -7,6 +7,18 @@ module ViewableModel
|
||||||
has_many :view_states, as: :viewable, dependent: :destroy
|
has_many :view_states, as: :viewable, dependent: :destroy
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# This module requres that the class which includes it implements these methods:
|
||||||
|
# => default_view_state, returning hash with default state representation
|
||||||
|
# => validate_view_state(view_state), custom validator for the state hash
|
||||||
|
|
||||||
|
def default_view_state
|
||||||
|
raise NotImplementedError, 'default_view_state should be implemented!'
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate_view_state(_view_state)
|
||||||
|
raise NotImplementedError, 'validate_view_state(view_state) should be implemented!'
|
||||||
|
end
|
||||||
|
|
||||||
def current_view_state(user)
|
def current_view_state(user)
|
||||||
state = view_states.where(user: user).take
|
state = view_states.where(user: user).take
|
||||||
state || view_states.create!(user: user, state: default_view_state)
|
state || view_states.create!(user: user, state: default_view_state)
|
||||||
|
|
|
@ -2,6 +2,7 @@ class Step < ApplicationRecord
|
||||||
include SearchableModel
|
include SearchableModel
|
||||||
include SearchableByNameModel
|
include SearchableByNameModel
|
||||||
include TinyMceImages
|
include TinyMceImages
|
||||||
|
include ViewableModel
|
||||||
|
|
||||||
auto_strip_attributes :name, :description, nullify: false
|
auto_strip_attributes :name, :description, nullify: false
|
||||||
validates :name,
|
validates :name,
|
||||||
|
@ -65,6 +66,16 @@ class Step < ApplicationRecord
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def default_view_state
|
||||||
|
{ 'assets' => { 'sort' => 'new' } }
|
||||||
|
end
|
||||||
|
|
||||||
|
def validate_view_state(view_state)
|
||||||
|
unless %w(new old atoz ztoa).include?(view_state.state.dig('assets', 'sort'))
|
||||||
|
view_state.errors.add(:state, :wrong_state)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def destroy(current_user)
|
def destroy(current_user)
|
||||||
@current_user = current_user
|
@current_user = current_user
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,13 @@ class Team < ApplicationRecord
|
||||||
'filter' => 'active' } }
|
'filter' => 'active' } }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def validate_view_state(view_state)
|
||||||
|
unless %w(new old atoz ztoa).include?(view_state.state.dig('projects', 'cards', 'sort')) &&
|
||||||
|
%w(active archived).include?(view_state.state.dig('projects', 'filter'))
|
||||||
|
view_state.errors.add(:state, :wrong_state)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def search_users(query = nil)
|
def search_users(query = nil)
|
||||||
a_query = "%#{query}%"
|
a_query = "%#{query}%"
|
||||||
users.where.not(confirmed_at: nil)
|
users.where.not(confirmed_at: nil)
|
||||||
|
|
|
@ -8,4 +8,13 @@ class ViewState < ApplicationRecord
|
||||||
scope: %i(viewable_type user_id),
|
scope: %i(viewable_type user_id),
|
||||||
message: :not_unique
|
message: :not_unique
|
||||||
}
|
}
|
||||||
|
|
||||||
|
validate :validate_state_content
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def validate_state_content
|
||||||
|
return unless state.present?
|
||||||
|
viewable.validate_view_state(self)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
status: asset_status,
|
status: asset_status,
|
||||||
'present-url': present_url,
|
'present-url': present_url,
|
||||||
'preview-url': asset_file_preview_path(asset),
|
'preview-url': asset_file_preview_path(asset),
|
||||||
'order-atoz': az_ordered_assets_index(step, asset.id),
|
'order-atoz': order_atoz,
|
||||||
'order-ztoa': assets_count - az_ordered_assets_index(step, asset.id),
|
'order-ztoa': order_ztoa,
|
||||||
'order-old': i,
|
'order-old': i,
|
||||||
'order-new': assets_count - i,
|
'order-new': assets_count - i,
|
||||||
} do %>
|
} do %>
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
<% assets = ordered_assets step %>
|
<% assets = ordered_assets(step) %>
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<hr>
|
<hr>
|
||||||
</div>
|
</div>
|
||||||
|
@ -6,7 +6,7 @@
|
||||||
|
|
||||||
<div class="title">
|
<div class="title">
|
||||||
<h4>
|
<h4>
|
||||||
<%= t('protocols.steps.files', count: assets.count) %>
|
<%= t('protocols.steps.files', count: assets.length) %>
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
|
@ -18,14 +18,17 @@
|
||||||
<% end %>
|
<% end %>
|
||||||
<div class="dropdown attachments-order" id="dd-att-step-<%= step.id %>">
|
<div class="dropdown attachments-order" id="dd-att-step-<%= step.id %>">
|
||||||
<button class="btn btn-default dropdown-toggle" type="button" id="sortMenu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
<button class="btn btn-default dropdown-toggle" type="button" id="sortMenu" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
|
||||||
<span id="dd-att-step-<%= step.id %>-label"><%= t('protocols.steps.attachments.sort_new').html_safe %></span>
|
<span id="dd-att-step-<%= step.id %>-label">
|
||||||
|
<%= t("protocols.steps.attachments.sort.#{step.current_view_state(current_user).state.dig('assets', 'sort')}_html") %>
|
||||||
|
</span>
|
||||||
<span class="caret"></span>
|
<span class="caret"></span>
|
||||||
</button>
|
</button>
|
||||||
<ul class="dropdown-menu" aria-labelledby="sortMenu">
|
<ul class="dropdown-menu" aria-labelledby="sortMenu" data-state-save-path="<%= update_view_state_step_path(step.id) %>">
|
||||||
<% ['new', 'old', 'atoz', 'ztoa'].each do |sort| %>
|
<% ['new', 'old', 'atoz', 'ztoa'].each do |sort| %>
|
||||||
<li>
|
<li>
|
||||||
<a data-order="<%= sort %>" onClick="reorderAttachments('<%= step.id %>', '<%= sort %>')">
|
<a data-order="<%= sort %>" onClick="reorderAttachments(this, '<%= step.id %>', '<%= sort %>')">
|
||||||
<%= t('protocols.steps.attachments.sort_' + sort ).html_safe %></a>
|
<%= t("protocols.steps.attachments.sort.#{sort}_html") %>
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<% end %>
|
<% end %>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -36,8 +39,10 @@
|
||||||
|
|
||||||
<div class="col-xs-12 attachments" id="att-<%= step.id %>">
|
<div class="col-xs-12 attachments" id="att-<%= step.id %>">
|
||||||
<% assets.each_with_index do |asset, i| %>
|
<% assets.each_with_index do |asset, i| %>
|
||||||
|
<% order_atoz = az_ordered_assets_index(assets, asset.id) %>
|
||||||
|
<% order_ztoa = assets.length - az_ordered_assets_index(assets, asset.id) %>
|
||||||
<%= render partial: 'steps/attachments/item.html.erb',
|
<%= render partial: 'steps/attachments/item.html.erb',
|
||||||
locals: { asset: asset, i: i, assets_count: assets.count, step: step } %>
|
locals: { asset: asset, i: i, assets_count: assets.length, step: step, order_atoz: order_atoz, order_ztoa: order_ztoa } %>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
<hr>
|
<hr>
|
||||||
|
|
|
@ -75,6 +75,8 @@ en:
|
||||||
attributes:
|
attributes:
|
||||||
viewable_id:
|
viewable_id:
|
||||||
not_unique: "State already exists for this user and parent object"
|
not_unique: "State already exists for this user and parent object"
|
||||||
|
state:
|
||||||
|
wrong_state: "Wrong parameters"
|
||||||
|
|
||||||
helpers:
|
helpers:
|
||||||
label:
|
label:
|
||||||
|
@ -1761,10 +1763,11 @@ en:
|
||||||
complete_title: "Complete Step"
|
complete_title: "Complete Step"
|
||||||
uncomplete_title: "Uncomplete Step"
|
uncomplete_title: "Uncomplete Step"
|
||||||
attachments:
|
attachments:
|
||||||
sort_new: "Newest first ↓"
|
sort:
|
||||||
sort_old: "Oldest first ↑"
|
new_html: "Newest first ↓"
|
||||||
sort_atoz: "Name ↓"
|
old_html: "Oldest first ↑"
|
||||||
sort_ztoa: "Name ↑"
|
atoz_html: "Name ↓"
|
||||||
|
ztoa_html: "Name ↑"
|
||||||
modified_label: "Modified:"
|
modified_label: "Modified:"
|
||||||
new:
|
new:
|
||||||
add_step_title: "Add new step"
|
add_step_title: "Add new step"
|
||||||
|
|
|
@ -435,6 +435,7 @@ Rails.application.routes.draw do
|
||||||
post 'toggle_step_state'
|
post 'toggle_step_state'
|
||||||
get 'move_down'
|
get 'move_down'
|
||||||
get 'move_up'
|
get 'move_up'
|
||||||
|
post 'update_view_state'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue