Add external IDs to repositories [SCI-5990]

This commit is contained in:
Oleksii Kriuchykhin 2021-08-13 14:07:01 +02:00 committed by Martin Artnik
parent 958ee92db7
commit 0b74f34de7
18 changed files with 136 additions and 48 deletions

View file

@ -27,7 +27,7 @@ class RepositoriesController < ApplicationController
def index
respond_to do |format|
format.html do
render 'empty_index' if Repository.accessible_by_teams(current_team).blank?
render 'empty_index' if @repositories.blank?
end
format.json do
render json: prepare_repositories_datatable(@repositories, current_team, params)

View file

@ -5,18 +5,15 @@ module RepositoryDatatableHelper
def prepare_row_columns(repository_rows, repository, columns_mappings, team, options = {})
repository_rows.map do |record|
row = {
'DT_RowId': record.id,
'DT_RowAttr': { 'data-state': row_style(record) },
'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),
'recordInfoUrl': Rails.application.routes.url_helpers.repository_repository_row_path(repository, record)
}
row = if repository.is_a?(LinkedRepository)
linked_repository_default_columns(record)
else
repository_default_columns(record)
end
row['DT_RowId'] = record.id
row['DT_RowAttr'] = { 'data-state': row_style(record) }
row['recordInfoUrl'] = Rails.application.routes.url_helpers.repository_repository_row_path(repository, record)
unless options[:view_mode]
row['recordUpdateUrl'] =
@ -84,20 +81,29 @@ module RepositoryDatatableHelper
can_manage_repository_rows?(repository)
end
def default_table_order_as_js_array
Constants::REPOSITORY_TABLE_DEFAULT_STATE['order'].to_json
def repository_default_columns(record)
{
'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
def default_table_columns
Constants::REPOSITORY_TABLE_DEFAULT_STATE['columns'].to_json
end
def default_snapshot_table_order_as_js_array
Constants::REPOSITORY_SNAPSHOT_TABLE_DEFAULT_STATE['order'].to_json
end
def default_snapshot_table_columns
Constants::REPOSITORY_SNAPSHOT_TABLE_DEFAULT_STATE['columns'].to_json
def linked_repository_default_columns(record)
{
'1': assigned_row(record),
'2': escape_input(record.external_id),
'3': record.code,
'4': escape_input(record.name),
'5': I18n.l(record.created_at, format: :full),
'6': escape_input(record.created_by.full_name),
'7': (record.archived_on ? I18n.l(record.archived_on, format: :full) : ''),
'8': escape_input(record.archived_by&.full_name)
}
end
def display_cell_value(cell, team)

View 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

View file

@ -108,8 +108,8 @@ class Repository < RepositoryBase
end
end
def default_columns_count
Constants::REPOSITORY_TABLE_DEFAULT_STATE['columns'].length
def default_table_state
Constants::REPOSITORY_TABLE_DEFAULT_STATE
end
def i_shared?(team)

View file

@ -1,6 +1,9 @@
# frozen_string_literal: true
class RepositoryBase < ApplicationRecord
require 'sti_preload'
include StiPreload
include Discard::Model
self.table_name = 'repositories'
@ -32,6 +35,22 @@ class RepositoryBase < ApplicationRecord
cell_includes
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)
self.discarded_by_id = discarded_by_id
destroy

View file

@ -55,7 +55,7 @@ class RepositoryColumn < ApplicationRecord
# Calculate old_column_index - this can only be done before
# record is deleted when we still have its index
old_column_index = (
Constants::REPOSITORY_TABLE_DEFAULT_STATE['columns'].length +
repository.default_columns_count +
repository.repository_columns
.order(id: :asc)
.pluck(:id)

View file

@ -45,8 +45,8 @@ class RepositorySnapshot < RepositoryBase
repository_snapshot.reload
end
def default_columns_count
Constants::REPOSITORY_SNAPSHOT_TABLE_DEFAULT_STATE['columns'].length
def default_table_state
Constants::REPOSITORY_SNAPSHOT_TABLE_DEFAULT_STATE
end
def assigned_rows(my_module)

View file

@ -78,11 +78,10 @@ class RepositoryDatatableService
if search_value.present?
matched_by_user = repository_rows.joins(:created_by).where_attributes_like('users.full_name', search_value)
repository_row_matches = repository_rows
.where_attributes_like(
['repository_rows.name', RepositoryRow::PREFIXED_ID_SQL],
search_value
)
repository_row_search_fileds = ['repository_rows.name', RepositoryRow::PREFIXED_ID_SQL]
repository_row_search_fileds << 'repository_rows.external_id' if @repository.is_a?(LinkedRepository)
repository_row_matches = repository_rows.where_attributes_like(repository_row_search_fileds, search_value)
results = repository_rows.where(id: repository_row_matches)
results = results.or(repository_rows.where(id: matched_by_user))
@ -121,8 +120,9 @@ class RepositoryDatatableService
'repository_rows.created_at',
'users.full_name',
'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
array << 'repository_cell.value'
end

View file

@ -9,7 +9,7 @@ class RepositoryTableStateColumnUpdateService
def update_states_with_new_column(repository)
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(
repository: repository
).find_each do |table_state|
@ -49,7 +49,7 @@ class RepositoryTableStateColumnUpdateService
if state.dig('order', 0, 0).to_i == old_column_index
# Fallback to default order if user had table ordered by
# 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
state['order'][0][0] -= 1
end

View file

@ -26,7 +26,7 @@ class RepositoryTableStateService
def update_state(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')
@ -47,10 +47,10 @@ class RepositoryTableStateService
private
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
state = Constants::REPOSITORY_TABLE_DEFAULT_STATE.deep_dup
state = @repository.default_table_state.deep_dup
@repository.repository_columns.each_with_index do |_, index|
real_index = default_columns_num + index
state['columns'][real_index] = Constants::REPOSITORY_TABLE_STATE_CUSTOM_COLUMN_TEMPLATE

View file

@ -5,8 +5,8 @@
data-repository-name="<%= @repository_snapshot.name %>"
data-repository-snapshot-created="<%= l(@repository_snapshot.created_at, format: :full) %>"
data-assigned-items-count="<%= @repository_snapshot.repository_rows.count %>"
data-default-order="<%= default_snapshot_table_order_as_js_array %>"
data-default-table-columns="<%= default_snapshot_table_columns %>"
data-default-order="<%= @repository_snapshot.default_table_order_as_js_array %>"
data-default-table-columns="<%= @repository_snapshot.default_table_columns %>"
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-versions-sidebar-url="<%= full_view_sidebar_my_module_repository_snapshots_path(@my_module, @repository_snapshot.parent_id) %>"

View file

@ -2,8 +2,8 @@
data-id="<%= @repository.id %>"
data-type="live"
data-source="<%= index_dt_my_module_repository_path(@my_module, @repository) %>"
data-default-order="<%= default_table_order_as_js_array %>"
data-default-table-columns="<%= default_table_columns %>"
data-default-order="<%= @repository.default_table_order_as_js_array %>"
data-default-table-columns="<%= @repository.default_table_columns %>"
data-repository-name="<%= @repository.name %>"
data-assigned-items-count="<%= @my_module.repository_rows_count(@repository) %>"
data-load-state-url="<%= repository_load_table_state_path(@repository) %>"

View file

@ -20,8 +20,8 @@
data-columns-delete-text="<%= I18n.t('repositories.columns_delete') %>"
data-available-columns="<%= repository_available_columns_path(repository) %>"
data-columns-changed="<%= I18n.t('repositories.columns_changed') %>"
data-default-order="<%= default_table_order_as_js_array %>"
data-default-table-columns="<%= default_table_columns %>"
data-default-order="<%= @repository.default_table_order_as_js_array %>"
data-default-table-columns="<%= @repository.default_table_columns %>"
data-editable="<%= can_manage_repository_rows?(repository) %>"
data-snapshot-provisioning="<%= @snapshot_provisioning %>"
data-status-url="<%= repository_status_path(@repository) %>">
@ -32,6 +32,9 @@
<span class="sci-checkbox-label"></span>
</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-name"><%= t("repositories.table.row_name") %></th>
<th id="added-on" ><%= t("repositories.table.added_on") %></th>

View file

@ -386,4 +386,6 @@ class Extends
delete_individual_signature_request
delete_group_signature_request
)
STI_PRELOAD_CLASSES = %w(LinkedRepository)
end

View file

@ -1371,6 +1371,7 @@ en:
apply: "Apply"
table:
id: 'ID'
external_id: 'External ID'
assigned: "Assigned"
assigned_search: 'Search...'
assigned_tooltip: "%{tasks} tasks in &#10;%{experiments} experiments,&#10;%{projects} projects"

View 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
View 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

View file

@ -13,7 +13,7 @@ describe RepositoryRowsController, type: :controller do
RepositoryTableState.create(
repository: repository,
user: user,
state: Constants::REPOSITORY_TABLE_DEFAULT_STATE
state: repository.default_teble_state
)
end
let!(:repository_row) do