mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-12-11 06:35:58 +08:00
Add external IDs to repositories [SCI-5990]
This commit is contained in:
parent
958ee92db7
commit
0b74f34de7
18 changed files with 136 additions and 48 deletions
|
|
@ -27,7 +27,7 @@ class RepositoriesController < ApplicationController
|
||||||
def index
|
def index
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
render 'empty_index' if Repository.accessible_by_teams(current_team).blank?
|
render 'empty_index' if @repositories.blank?
|
||||||
end
|
end
|
||||||
format.json do
|
format.json do
|
||||||
render json: prepare_repositories_datatable(@repositories, current_team, params)
|
render json: prepare_repositories_datatable(@repositories, current_team, params)
|
||||||
|
|
|
||||||
|
|
@ -5,18 +5,15 @@ module RepositoryDatatableHelper
|
||||||
|
|
||||||
def prepare_row_columns(repository_rows, repository, columns_mappings, team, options = {})
|
def prepare_row_columns(repository_rows, repository, columns_mappings, team, options = {})
|
||||||
repository_rows.map do |record|
|
repository_rows.map do |record|
|
||||||
row = {
|
row = if repository.is_a?(LinkedRepository)
|
||||||
'DT_RowId': record.id,
|
linked_repository_default_columns(record)
|
||||||
'DT_RowAttr': { 'data-state': row_style(record) },
|
else
|
||||||
'1': assigned_row(record),
|
repository_default_columns(record)
|
||||||
'2': record.code,
|
end
|
||||||
'3': escape_input(record.name),
|
|
||||||
'4': I18n.l(record.created_at, format: :full),
|
row['DT_RowId'] = record.id
|
||||||
'5': escape_input(record.created_by.full_name),
|
row['DT_RowAttr'] = { 'data-state': row_style(record) }
|
||||||
'6': (record.archived_on ? I18n.l(record.archived_on, format: :full) : ''),
|
row['recordInfoUrl'] = Rails.application.routes.url_helpers.repository_repository_row_path(repository, record)
|
||||||
'7': escape_input(record.archived_by&.full_name),
|
|
||||||
'recordInfoUrl': Rails.application.routes.url_helpers.repository_repository_row_path(repository, record)
|
|
||||||
}
|
|
||||||
|
|
||||||
unless options[:view_mode]
|
unless options[:view_mode]
|
||||||
row['recordUpdateUrl'] =
|
row['recordUpdateUrl'] =
|
||||||
|
|
@ -84,20 +81,29 @@ module RepositoryDatatableHelper
|
||||||
can_manage_repository_rows?(repository)
|
can_manage_repository_rows?(repository)
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_table_order_as_js_array
|
def repository_default_columns(record)
|
||||||
Constants::REPOSITORY_TABLE_DEFAULT_STATE['order'].to_json
|
{
|
||||||
|
'1': assigned_row(record),
|
||||||
|
'2': record.code,
|
||||||
|
'3': escape_input(record.name),
|
||||||
|
'4': I18n.l(record.created_at, format: :full),
|
||||||
|
'5': escape_input(record.created_by.full_name),
|
||||||
|
'6': (record.archived_on ? I18n.l(record.archived_on, format: :full) : ''),
|
||||||
|
'7': escape_input(record.archived_by&.full_name)
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_table_columns
|
def linked_repository_default_columns(record)
|
||||||
Constants::REPOSITORY_TABLE_DEFAULT_STATE['columns'].to_json
|
{
|
||||||
end
|
'1': assigned_row(record),
|
||||||
|
'2': escape_input(record.external_id),
|
||||||
def default_snapshot_table_order_as_js_array
|
'3': record.code,
|
||||||
Constants::REPOSITORY_SNAPSHOT_TABLE_DEFAULT_STATE['order'].to_json
|
'4': escape_input(record.name),
|
||||||
end
|
'5': I18n.l(record.created_at, format: :full),
|
||||||
|
'6': escape_input(record.created_by.full_name),
|
||||||
def default_snapshot_table_columns
|
'7': (record.archived_on ? I18n.l(record.archived_on, format: :full) : ''),
|
||||||
Constants::REPOSITORY_SNAPSHOT_TABLE_DEFAULT_STATE['columns'].to_json
|
'8': escape_input(record.archived_by&.full_name)
|
||||||
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def display_cell_value(cell, team)
|
def display_cell_value(cell, team)
|
||||||
|
|
|
||||||
11
app/models/linked_repository.rb
Normal file
11
app/models/linked_repository.rb
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class LinkedRepository < Repository
|
||||||
|
def default_table_state
|
||||||
|
state = Constants::REPOSITORY_TABLE_DEFAULT_STATE.deep_dup
|
||||||
|
state['order'] = [[3, 'asc']]
|
||||||
|
state['ColReorder'] << state['ColReorder'].length
|
||||||
|
state['columns'].insert(1, Constants::REPOSITORY_TABLE_STATE_CUSTOM_COLUMN_TEMPLATE)
|
||||||
|
state
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -108,8 +108,8 @@ class Repository < RepositoryBase
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_columns_count
|
def default_table_state
|
||||||
Constants::REPOSITORY_TABLE_DEFAULT_STATE['columns'].length
|
Constants::REPOSITORY_TABLE_DEFAULT_STATE
|
||||||
end
|
end
|
||||||
|
|
||||||
def i_shared?(team)
|
def i_shared?(team)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class RepositoryBase < ApplicationRecord
|
class RepositoryBase < ApplicationRecord
|
||||||
|
require 'sti_preload'
|
||||||
|
|
||||||
|
include StiPreload
|
||||||
include Discard::Model
|
include Discard::Model
|
||||||
|
|
||||||
self.table_name = 'repositories'
|
self.table_name = 'repositories'
|
||||||
|
|
@ -32,6 +35,22 @@ class RepositoryBase < ApplicationRecord
|
||||||
cell_includes
|
cell_includes
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def default_table_state
|
||||||
|
raise NotImplementedError
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_table_columns
|
||||||
|
default_table_state['columns'].to_json
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_columns_count
|
||||||
|
default_table_state['columns'].length
|
||||||
|
end
|
||||||
|
|
||||||
|
def default_table_order_as_js_array
|
||||||
|
default_table_state['order'].to_json
|
||||||
|
end
|
||||||
|
|
||||||
def destroy_discarded(discarded_by_id = nil)
|
def destroy_discarded(discarded_by_id = nil)
|
||||||
self.discarded_by_id = discarded_by_id
|
self.discarded_by_id = discarded_by_id
|
||||||
destroy
|
destroy
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,7 @@ class RepositoryColumn < ApplicationRecord
|
||||||
# Calculate old_column_index - this can only be done before
|
# Calculate old_column_index - this can only be done before
|
||||||
# record is deleted when we still have its index
|
# record is deleted when we still have its index
|
||||||
old_column_index = (
|
old_column_index = (
|
||||||
Constants::REPOSITORY_TABLE_DEFAULT_STATE['columns'].length +
|
repository.default_columns_count +
|
||||||
repository.repository_columns
|
repository.repository_columns
|
||||||
.order(id: :asc)
|
.order(id: :asc)
|
||||||
.pluck(:id)
|
.pluck(:id)
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,8 @@ class RepositorySnapshot < RepositoryBase
|
||||||
repository_snapshot.reload
|
repository_snapshot.reload
|
||||||
end
|
end
|
||||||
|
|
||||||
def default_columns_count
|
def default_table_state
|
||||||
Constants::REPOSITORY_SNAPSHOT_TABLE_DEFAULT_STATE['columns'].length
|
Constants::REPOSITORY_SNAPSHOT_TABLE_DEFAULT_STATE
|
||||||
end
|
end
|
||||||
|
|
||||||
def assigned_rows(my_module)
|
def assigned_rows(my_module)
|
||||||
|
|
|
||||||
|
|
@ -78,11 +78,10 @@ class RepositoryDatatableService
|
||||||
if search_value.present?
|
if search_value.present?
|
||||||
matched_by_user = repository_rows.joins(:created_by).where_attributes_like('users.full_name', search_value)
|
matched_by_user = repository_rows.joins(:created_by).where_attributes_like('users.full_name', search_value)
|
||||||
|
|
||||||
repository_row_matches = repository_rows
|
repository_row_search_fileds = ['repository_rows.name', RepositoryRow::PREFIXED_ID_SQL]
|
||||||
.where_attributes_like(
|
repository_row_search_fileds << 'repository_rows.external_id' if @repository.is_a?(LinkedRepository)
|
||||||
['repository_rows.name', RepositoryRow::PREFIXED_ID_SQL],
|
|
||||||
search_value
|
repository_row_matches = repository_rows.where_attributes_like(repository_row_search_fileds, search_value)
|
||||||
)
|
|
||||||
results = repository_rows.where(id: repository_row_matches)
|
results = repository_rows.where(id: repository_row_matches)
|
||||||
results = results.or(repository_rows.where(id: matched_by_user))
|
results = results.or(repository_rows.where(id: matched_by_user))
|
||||||
|
|
||||||
|
|
@ -121,8 +120,9 @@ class RepositoryDatatableService
|
||||||
'repository_rows.created_at',
|
'repository_rows.created_at',
|
||||||
'users.full_name',
|
'users.full_name',
|
||||||
'repository_rows.archived_on',
|
'repository_rows.archived_on',
|
||||||
'archived_bies_repository_rows.full_name',
|
'archived_bies_repository_rows.full_name'
|
||||||
]
|
]
|
||||||
|
array.insert(1, 'repository_rows.external_id') if @repository.is_a?(LinkedRepository)
|
||||||
@repository.repository_columns.count.times do
|
@repository.repository_columns.count.times do
|
||||||
array << 'repository_cell.value'
|
array << 'repository_cell.value'
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ class RepositoryTableStateColumnUpdateService
|
||||||
def update_states_with_new_column(repository)
|
def update_states_with_new_column(repository)
|
||||||
raise ArgumentError, 'repository is empty' if repository.blank?
|
raise ArgumentError, 'repository is empty' if repository.blank?
|
||||||
|
|
||||||
columns_num = Constants::REPOSITORY_TABLE_DEFAULT_STATE['columns'].length + repository.repository_columns.count
|
columns_num = repository.default_columns_count + repository.repository_columns.count
|
||||||
RepositoryTableState.where(
|
RepositoryTableState.where(
|
||||||
repository: repository
|
repository: repository
|
||||||
).find_each do |table_state|
|
).find_each do |table_state|
|
||||||
|
|
@ -49,7 +49,7 @@ class RepositoryTableStateColumnUpdateService
|
||||||
if state.dig('order', 0, 0).to_i == old_column_index
|
if state.dig('order', 0, 0).to_i == old_column_index
|
||||||
# Fallback to default order if user had table ordered by
|
# Fallback to default order if user had table ordered by
|
||||||
# the deleted column
|
# the deleted column
|
||||||
state['order'] = Constants::REPOSITORY_TABLE_DEFAULT_STATE['order']
|
state['order'] = repository.default_table_state['order']
|
||||||
elsif state.dig('order', 0, 0).to_i > old_column_index
|
elsif state.dig('order', 0, 0).to_i > old_column_index
|
||||||
state['order'][0][0] -= 1
|
state['order'][0][0] -= 1
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ class RepositoryTableStateService
|
||||||
|
|
||||||
def update_state(state)
|
def update_state(state)
|
||||||
saved_state = load_state
|
saved_state = load_state
|
||||||
state['order'] = Constants::REPOSITORY_TABLE_DEFAULT_STATE['order'] if state.dig('order', 0, 0).to_i < 1
|
state['order'] = @repository.default_table_state['order'] if state.dig('order', 0, 0).to_i < 1
|
||||||
|
|
||||||
return if saved_state.state.except('time') == state.except('time')
|
return if saved_state.state.except('time') == state.except('time')
|
||||||
|
|
||||||
|
|
@ -47,10 +47,10 @@ class RepositoryTableStateService
|
||||||
private
|
private
|
||||||
|
|
||||||
def generate_default_state
|
def generate_default_state
|
||||||
default_columns_num = Constants::REPOSITORY_TABLE_DEFAULT_STATE['columns'].length
|
default_columns_num = @repository.default_columns_count
|
||||||
|
|
||||||
# This state should be strings-only
|
# This state should be strings-only
|
||||||
state = Constants::REPOSITORY_TABLE_DEFAULT_STATE.deep_dup
|
state = @repository.default_table_state.deep_dup
|
||||||
@repository.repository_columns.each_with_index do |_, index|
|
@repository.repository_columns.each_with_index do |_, index|
|
||||||
real_index = default_columns_num + index
|
real_index = default_columns_num + index
|
||||||
state['columns'][real_index] = Constants::REPOSITORY_TABLE_STATE_CUSTOM_COLUMN_TEMPLATE
|
state['columns'][real_index] = Constants::REPOSITORY_TABLE_STATE_CUSTOM_COLUMN_TEMPLATE
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
data-repository-name="<%= @repository_snapshot.name %>"
|
data-repository-name="<%= @repository_snapshot.name %>"
|
||||||
data-repository-snapshot-created="<%= l(@repository_snapshot.created_at, format: :full) %>"
|
data-repository-snapshot-created="<%= l(@repository_snapshot.created_at, format: :full) %>"
|
||||||
data-assigned-items-count="<%= @repository_snapshot.repository_rows.count %>"
|
data-assigned-items-count="<%= @repository_snapshot.repository_rows.count %>"
|
||||||
data-default-order="<%= default_snapshot_table_order_as_js_array %>"
|
data-default-order="<%= @repository_snapshot.default_table_order_as_js_array %>"
|
||||||
data-default-table-columns="<%= default_snapshot_table_columns %>"
|
data-default-table-columns="<%= @repository_snapshot.default_table_columns %>"
|
||||||
data-load-state-url="<%= repository_load_table_state_path(@repository_snapshot) %>"
|
data-load-state-url="<%= repository_load_table_state_path(@repository_snapshot) %>"
|
||||||
data-export-url="<%= export_repository_snapshot_my_module_repository_snapshot_path(@my_module, @repository_snapshot) %>"
|
data-export-url="<%= export_repository_snapshot_my_module_repository_snapshot_path(@my_module, @repository_snapshot) %>"
|
||||||
data-versions-sidebar-url="<%= full_view_sidebar_my_module_repository_snapshots_path(@my_module, @repository_snapshot.parent_id) %>"
|
data-versions-sidebar-url="<%= full_view_sidebar_my_module_repository_snapshots_path(@my_module, @repository_snapshot.parent_id) %>"
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,8 @@
|
||||||
data-id="<%= @repository.id %>"
|
data-id="<%= @repository.id %>"
|
||||||
data-type="live"
|
data-type="live"
|
||||||
data-source="<%= index_dt_my_module_repository_path(@my_module, @repository) %>"
|
data-source="<%= index_dt_my_module_repository_path(@my_module, @repository) %>"
|
||||||
data-default-order="<%= default_table_order_as_js_array %>"
|
data-default-order="<%= @repository.default_table_order_as_js_array %>"
|
||||||
data-default-table-columns="<%= default_table_columns %>"
|
data-default-table-columns="<%= @repository.default_table_columns %>"
|
||||||
data-repository-name="<%= @repository.name %>"
|
data-repository-name="<%= @repository.name %>"
|
||||||
data-assigned-items-count="<%= @my_module.repository_rows_count(@repository) %>"
|
data-assigned-items-count="<%= @my_module.repository_rows_count(@repository) %>"
|
||||||
data-load-state-url="<%= repository_load_table_state_path(@repository) %>"
|
data-load-state-url="<%= repository_load_table_state_path(@repository) %>"
|
||||||
|
|
|
||||||
|
|
@ -20,8 +20,8 @@
|
||||||
data-columns-delete-text="<%= I18n.t('repositories.columns_delete') %>"
|
data-columns-delete-text="<%= I18n.t('repositories.columns_delete') %>"
|
||||||
data-available-columns="<%= repository_available_columns_path(repository) %>"
|
data-available-columns="<%= repository_available_columns_path(repository) %>"
|
||||||
data-columns-changed="<%= I18n.t('repositories.columns_changed') %>"
|
data-columns-changed="<%= I18n.t('repositories.columns_changed') %>"
|
||||||
data-default-order="<%= default_table_order_as_js_array %>"
|
data-default-order="<%= @repository.default_table_order_as_js_array %>"
|
||||||
data-default-table-columns="<%= default_table_columns %>"
|
data-default-table-columns="<%= @repository.default_table_columns %>"
|
||||||
data-editable="<%= can_manage_repository_rows?(repository) %>"
|
data-editable="<%= can_manage_repository_rows?(repository) %>"
|
||||||
data-snapshot-provisioning="<%= @snapshot_provisioning %>"
|
data-snapshot-provisioning="<%= @snapshot_provisioning %>"
|
||||||
data-status-url="<%= repository_status_path(@repository) %>">
|
data-status-url="<%= repository_status_path(@repository) %>">
|
||||||
|
|
@ -32,6 +32,9 @@
|
||||||
<span class="sci-checkbox-label"></span>
|
<span class="sci-checkbox-label"></span>
|
||||||
</th>
|
</th>
|
||||||
<th id="assigned" data-unmanageable="true"><%= t("repositories.table.assigned") %></th>
|
<th id="assigned" data-unmanageable="true"><%= t("repositories.table.assigned") %></th>
|
||||||
|
<% if @repository.is_a?(LinkedRepository) %>
|
||||||
|
<th id="row-external-id"><%= t('repositories.table.external_id') %></th>
|
||||||
|
<% end %>
|
||||||
<th id="row-id"><%= t("repositories.table.id") %></th>
|
<th id="row-id"><%= t("repositories.table.id") %></th>
|
||||||
<th id="row-name"><%= t("repositories.table.row_name") %></th>
|
<th id="row-name"><%= t("repositories.table.row_name") %></th>
|
||||||
<th id="added-on" ><%= t("repositories.table.added_on") %></th>
|
<th id="added-on" ><%= t("repositories.table.added_on") %></th>
|
||||||
|
|
|
||||||
|
|
@ -386,4 +386,6 @@ class Extends
|
||||||
delete_individual_signature_request
|
delete_individual_signature_request
|
||||||
delete_group_signature_request
|
delete_group_signature_request
|
||||||
)
|
)
|
||||||
|
|
||||||
|
STI_PRELOAD_CLASSES = %w(LinkedRepository)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1371,6 +1371,7 @@ en:
|
||||||
apply: "Apply"
|
apply: "Apply"
|
||||||
table:
|
table:
|
||||||
id: 'ID'
|
id: 'ID'
|
||||||
|
external_id: 'External ID'
|
||||||
assigned: "Assigned"
|
assigned: "Assigned"
|
||||||
assigned_search: 'Search...'
|
assigned_search: 'Search...'
|
||||||
assigned_tooltip: "%{tasks} tasks in %{experiments} experiments, %{projects} projects"
|
assigned_tooltip: "%{tasks} tasks in %{experiments} experiments, %{projects} projects"
|
||||||
|
|
|
||||||
19
db/migrate/20210812095254_add_external_id_to_repositories.rb
Normal file
19
db/migrate/20210812095254_add_external_id_to_repositories.rb
Normal file
|
|
@ -0,0 +1,19 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require File.expand_path('app/helpers/database_helper')
|
||||||
|
|
||||||
|
class AddExternalIdToRepositories < ActiveRecord::Migration[6.1]
|
||||||
|
include DatabaseHelper
|
||||||
|
|
||||||
|
def up
|
||||||
|
add_column :repository_rows, :external_id, :string, null: true
|
||||||
|
add_index :repository_rows, :external_id, unique: true, name: 'unique_index_repository_rows_on_external_id'
|
||||||
|
add_gin_index_without_tags(:repository_rows, :external_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
remove_index :repository_rows, name: 'index_repository_rows_on_external_id'
|
||||||
|
remove_index :repository_rows, :external_id, unique: true, name: 'unique_index_repository_rows_on_external_id'
|
||||||
|
remove_column :repository_rows, :external_id, :string, null: true
|
||||||
|
end
|
||||||
|
end
|
||||||
27
lib/sti_preload.rb
Normal file
27
lib/sti_preload.rb
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module StiPreload
|
||||||
|
unless Rails.application.config.eager_load
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
included do
|
||||||
|
cattr_accessor :preloaded, instance_accessor: false
|
||||||
|
end
|
||||||
|
|
||||||
|
class_methods do
|
||||||
|
def descendants
|
||||||
|
preload_sti unless preloaded
|
||||||
|
super
|
||||||
|
end
|
||||||
|
|
||||||
|
def preload_sti
|
||||||
|
Extends::STI_PRELOAD_CLASSES.each do |type|
|
||||||
|
logger.debug("Preloading STI type #{type}")
|
||||||
|
type.constantize
|
||||||
|
end
|
||||||
|
|
||||||
|
self.preloaded = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -13,7 +13,7 @@ describe RepositoryRowsController, type: :controller do
|
||||||
RepositoryTableState.create(
|
RepositoryTableState.create(
|
||||||
repository: repository,
|
repository: repository,
|
||||||
user: user,
|
user: user,
|
||||||
state: Constants::REPOSITORY_TABLE_DEFAULT_STATE
|
state: repository.default_teble_state
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
let!(:repository_row) do
|
let!(:repository_row) do
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue