Merge pull request #1073 from ZmagoD/zd_SCI_2206

add ID column to repository [fixes SCI-2206]
This commit is contained in:
Zmago Devetak 2018-04-04 15:39:59 +02:00 committed by GitHub
commit d1f3a65279
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 88 additions and 45 deletions

View file

@ -47,7 +47,7 @@ var RepositoryDatatable = (function(global) {
originalHeader = $(TABLE_ID + ' thead').children().clone(); originalHeader = $(TABLE_ID + ' thead').children().clone();
viewAssigned = 'assigned'; viewAssigned = 'assigned';
TABLE = $(TABLE_ID).DataTable({ TABLE = $(TABLE_ID).DataTable({
order: [[2, 'desc']], order: [[3, 'desc']],
dom: "R<'row'<'col-sm-9-custom toolbar'l><'col-sm-3-custom'f>>tpi", dom: "R<'row'<'col-sm-9-custom toolbar'l><'col-sm-3-custom'f>>tpi",
stateSave: true, stateSave: true,
processing: true, processing: true,
@ -84,7 +84,12 @@ var RepositoryDatatable = (function(global) {
orderable: true, orderable: true,
sWidth: '1%' sWidth: '1%'
}, { }, {
targets: 2, targets: 2,
searchable: true,
orderable: true,
sWidth: '1%'
}, {
targets: 3,
render: function(data, type, row) { render: function(data, type, row) {
return "<a href='" + row.recordInfoUrl + "'" + return "<a href='" + row.recordInfoUrl + "'" +
"class='record-info-link'>" + data + '</a>'; "class='record-info-link'>" + data + '</a>';
@ -255,15 +260,18 @@ var RepositoryDatatable = (function(global) {
case 'assigned': case 'assigned':
val = -2; val = -2;
break; break;
case 'row-name': case 'row-id':
val = -3; val = -3;
break; break
case 'added-by': case 'row-name':
val = -4; val = -4;
break; break;
case 'added-on': case 'added-by':
val = -5; val = -5;
break; break;
case 'added-on':
val = -6;
break;
default: default:
val = th.attr('id'); val = th.attr('id');
} }

View file

@ -10,9 +10,10 @@ module RepositoryDatatableHelper
row = { row = {
'DT_RowId': record.id, 'DT_RowId': record.id,
'1': assigned_row(record, assigned_rows), '1': assigned_row(record, assigned_rows),
'2': escape_input(record.name), '2': record.id,
'3': I18n.l(record.created_at, format: :full), '3': escape_input(record.name),
'4': escape_input(record.created_by.full_name), '4': I18n.l(record.created_at, format: :full),
'5': escape_input(record.created_by.full_name),
'recordEditUrl': Rails.application.routes.url_helpers 'recordEditUrl': Rails.application.routes.url_helpers
.edit_repository_repository_row_path( .edit_repository_repository_row_path(
repository, repository,

View file

@ -68,14 +68,25 @@ module SearchableModel
end end
else else
unless attrs.empty? unless attrs.empty?
# quick fix to enable searching by repositoy_row id
id_index = { present: false }
where_str = where_str =
(attrs.map.with_index do |a, i| (attrs.map.with_index do |a, i|
"(trim_html_tags(#{a})) #{like} :t#{i} OR " if a == 'repository_rows.id'
id_index = { present: true, val: i }
"(#{a}) = :t#{i} OR "
else
"(trim_html_tags(#{a})) #{like} :t#{i} OR "
end
end end
).join[0..-5] ).join[0..-5]
vals = ( vals = (
attrs.map.with_index do |_, i| attrs.map.with_index do |_, i|
["t#{i}".to_sym, "%#{sanitize_sql_like(query.to_s)}%"] if id_index[:present] && id_index[:val] == i
["t#{i}".to_sym, sanitize_sql_like(query).to_i]
else
["t#{i}".to_sym, "%#{sanitize_sql_like(query.to_s)}%"]
end
end end
).to_h ).to_h

View file

@ -343,6 +343,7 @@ class MyModule < ApplicationRecord
.where(repository_id: repository_id) .where(repository_id: repository_id)
.order(created_at: order).find_each do |row| .order(created_at: order).find_each do |row|
row_json = [] row_json = []
row_json << row.id
row_json << row.name row_json << row.name
row_json << I18n.l(row.created_at, format: :full) row_json << I18n.l(row.created_at, format: :full)
row_json << row.created_by.full_name row_json << row.created_by.full_name
@ -351,6 +352,7 @@ class MyModule < ApplicationRecord
# Prepare column headers # Prepare column headers
headers = [ headers = [
I18n.t('repositories.table.id'),
I18n.t('repositories.table.row_name'), I18n.t('repositories.table.row_name'),
I18n.t('repositories.table.added_on'), I18n.t('repositories.table.added_on'),
I18n.t('repositories.table.added_by') I18n.t('repositories.table.added_by')

View file

@ -55,7 +55,9 @@ class RepositoryDatatableService
def search(value) def search(value)
includes_json = { repository_cells: Extends::REPOSITORY_SEARCH_INCLUDES } includes_json = { repository_cells: Extends::REPOSITORY_SEARCH_INCLUDES }
searchable_attributes = ['repository_rows.name', 'users.full_name'] + searchable_attributes = ['repository_rows.name',
'users.full_name',
'repository_rows.id'] +
Extends::REPOSITORY_EXTRA_SEARCH_ATTR Extends::REPOSITORY_EXTRA_SEARCH_ATTR
RepositoryRow.left_outer_joins(:created_by) RepositoryRow.left_outer_joins(:created_by)
@ -76,6 +78,7 @@ class RepositoryDatatableService
def sortable_columns def sortable_columns
array = [ array = [
'assigned', 'assigned',
'repository_rows.id',
'repository_rows.name', 'repository_rows.name',
'repository_rows.created_at', 'repository_rows.created_at',
'users.full_name' 'users.full_name'

View file

@ -24,10 +24,12 @@ module RepositoryZipExport
when -1, -2 when -1, -2
next next
when -3 when -3
I18n.t('repositories.table.row_name') I18n.t('repositories.table.id')
when -4 when -4
I18n.t('repositories.table.added_by') I18n.t('repositories.table.row_name')
when -5 when -5
I18n.t('repositories.table.added_by')
when -6
I18n.t('repositories.table.added_on') I18n.t('repositories.table.added_on')
else else
column = RepositoryColumn.find_by_id(c_id) column = RepositoryColumn.find_by_id(c_id)
@ -44,10 +46,12 @@ module RepositoryZipExport
when -1, -2 when -1, -2
next next
when -3 when -3
row.name row.id
when -4 when -4
row.created_by.full_name row.name
when -5 when -5
row.created_by.full_name
when -6
I18n.l(row.created_at, format: :full) I18n.l(row.created_at, format: :full)
else else
cell = row.repository_cells cell = row.repository_cells

View file

@ -13,12 +13,17 @@
</ol> </ol>
<p> <p>
<span> <span>
<%= t "repository_row.modal_info.added_on" %> <%=t 'repository_row.modal_info.ID' %>
<%= @repository_row.id %>
</span>
<br>
<span>
<%= t "repository_row.modal_info.added_on" %>:
<%= l @repository_row.created_at, format: :full %> <%= l @repository_row.created_at, format: :full %>
</span> </span>
<br> <br>
<span> <span>
<%= t "repository_row.modal_info.added_by" %> <%= t "repository_row.modal_info.added_by" %>:
<%= @repository_row.created_by.full_name %> <%= @repository_row.created_by.full_name %>
</span> </span>
<% @repository_row.repository_cells.each do |repository_cell| %> <% @repository_row.repository_cells.each do |repository_cell| %>

View file

@ -3,7 +3,7 @@
data-current-uri="<%= request.original_url %>" data-current-uri="<%= request.original_url %>"
data-repository-id="<%= repository.id %>" data-repository-id="<%= repository.id %>"
data-source="<%= repository_index_link %>" data-source="<%= repository_index_link %>"
data-num-columns="<%= 5 + repository.repository_columns.count %>" data-num-columns="<%= 6 + repository.repository_columns.count %>"
data-create-record="<%= repository_repository_rows_path(repository) %>" data-create-record="<%= repository_repository_rows_path(repository) %>"
data-delete-record="<%= repository_delete_records_path(repository) %>" data-delete-record="<%= repository_delete_records_path(repository) %>"
data-max-dropdown-length="<%= Constants::NAME_TRUNCATION_LENGTH_DROPDOWN %>" data-max-dropdown-length="<%= Constants::NAME_TRUNCATION_LENGTH_DROPDOWN %>"
@ -16,6 +16,7 @@
<tr> <tr>
<th id="checkbox"><input name="select_all" value="1" type="checkbox"></th> <th id="checkbox"><input name="select_all" value="1" type="checkbox"></th>
<th id="assigned"><%= t("repositories.table.assigned") %></th> <th id="assigned"><%= t("repositories.table.assigned") %></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>
<th id="added-by"><%= t("repositories.table.added_by") %></th> <th id="added-by"><%= t("repositories.table.added_by") %></th>

View file

@ -6,13 +6,11 @@
</h5> </h5>
<p> <p>
<% repository_row.repository_cells.each do |cell| %> <span>
<span> <%=t 'repository_row.modal_info.ID' %>
<%=t "search.index.repositories.custom_column", column: cell.repository_column.name %> <%= repository_row.id %>
<%= highlight cell.value.data, search_query.strip.split(/\s+/) %> </span>
</span> <br />
<br>
<% end %>
<span> <span>
<%=t "search.index.repositories.added_on" %> <%=t "search.index.repositories.added_on" %>
<%=l repository_row.created_at, format: :full %> <%=l repository_row.created_at, format: :full %>
@ -22,6 +20,13 @@
<%=t "search.index.repositories.added_by" %> <%=t "search.index.repositories.added_by" %>
<%= highlight repository_row.created_by.full_name, search_query.strip.split(/\s+/) %> <%= highlight repository_row.created_by.full_name, search_query.strip.split(/\s+/) %>
</span> </span>
<% repository_row.repository_cells.each do |cell| %>
<span>
<%=t "search.index.repositories.custom_column", column: cell.repository_column.name %>
<%= highlight cell.value.data, search_query.strip.split(/\s+/) %>
</span>
<br>
<% end %>
</p> </p>
<p> <p>

View file

@ -158,7 +158,7 @@ class Constants
COLOR_DOVE_GRAY = '#666666'.freeze # $color-dove-gray COLOR_DOVE_GRAY = '#666666'.freeze # $color-dove-gray
COLOR_EMPEROR = '#555555'.freeze # $color-emperor COLOR_EMPEROR = '#555555'.freeze # $color-emperor
COLOR_BLACK = '#000000'.freeze # $color-black COLOR_BLACK = '#000000'.freeze # $color-black
#============================================================================= #=============================================================================
# External URLs # External URLs
@ -842,17 +842,17 @@ class Constants
REPOSITORY_TABLE_DEFAULT_STATE = { REPOSITORY_TABLE_DEFAULT_STATE = {
'time' => 0, 'time' => 0,
'start' => 0, 'start' => 0,
'length' => 5, 'length' => 6,
'order' => [[2, 'desc']], 'order' => [[3, 'desc']],
'search' => { 'search' => '', 'search' => { 'search' => '',
'smart' => true, 'smart' => true,
'regex' => false, 'regex' => false,
'caseInsensitive' => true }, 'caseInsensitive' => true },
'columns' => [], 'columns' => [],
'assigned' => 'assigned', 'assigned' => 'assigned',
'ColReorder' => [*0..4] 'ColReorder' => [*0..5]
} }
5.times do 6.times do
REPOSITORY_TABLE_DEFAULT_STATE['columns'] << { REPOSITORY_TABLE_DEFAULT_STATE['columns'] << {
'visible' => true, 'visible' => true,
'search' => { 'search' => '', 'search' => { 'search' => '',

View file

@ -918,6 +918,7 @@ en:
breadcrumbs: breadcrumbs:
repositories: "Repositories" repositories: "Repositories"
table: table:
id: 'ID'
assigned: "Assigned" assigned: "Assigned"
row_name: "Name" row_name: "Name"
added_on: "Added on" added_on: "Added on"
@ -1003,6 +1004,7 @@ en:
head_title: "Inventories | %{library}" head_title: "Inventories | %{library}"
repository_row: repository_row:
modal_info: modal_info:
ID: 'ID:'
head_title: "Information for item '%{repository_row}'" head_title: "Information for item '%{repository_row}'"
added_on: "Added on" added_on: "Added on"
added_by: "Added by" added_by: "Added by"

View file

@ -62,7 +62,7 @@ describe RepositoryRowsController, type: :controller do
describe 'json object' do describe 'json object' do
it 'returns a valid object' do it 'returns a valid object' do
params = { order: { 0 => { column: '3', dir: 'asc' } }, params = { order: { 0 => { column: '4', dir: 'asc' } },
drow: '0', drow: '0',
search: { value: '' }, search: { value: '' },
length: '10', length: '10',
@ -77,7 +77,7 @@ describe RepositoryRowsController, type: :controller do
describe 'pagination' do describe 'pagination' do
it 'returns first 10 records' do it 'returns first 10 records' do
params = { order: { 0 => { column: '3', dir: 'asc' } }, params = { order: { 0 => { column: '4', dir: 'asc' } },
drow: '0', drow: '0',
search: { value: '' }, search: { value: '' },
length: '10', length: '10',
@ -86,11 +86,11 @@ describe RepositoryRowsController, type: :controller do
get :index, params: params, format: :json get :index, params: params, format: :json
response_body = JSON.parse(response.body) response_body = JSON.parse(response.body)
expect(response_body['data'].length).to eq 10 expect(response_body['data'].length).to eq 10
expect(response_body['data'].first['2']).to eq 'row (0)' expect(response_body['data'].first['3']).to eq 'row (0)'
end end
it 'returns next 10 records' do it 'returns next 10 records' do
params = { order: { 0 => { column: '3', dir: 'asc' } }, params = { order: { 0 => { column: '4', dir: 'asc' } },
drow: '0', drow: '0',
search: { value: '' }, search: { value: '' },
length: '10', length: '10',
@ -99,11 +99,11 @@ describe RepositoryRowsController, type: :controller do
get :index, params: params, format: :json get :index, params: params, format: :json
response_body = JSON.parse(response.body) response_body = JSON.parse(response.body)
expect(response_body['data'].length).to eq 10 expect(response_body['data'].length).to eq 10
expect(response_body['data'].first['2']).to eq 'row (10)' expect(response_body['data'].first['3']).to eq 'row (10)'
end end
it 'returns first 25 records' do it 'returns first 25 records' do
params = { order: { 0 => { column: '2', dir: 'desc' } }, params = { order: { 0 => { column: '4', dir: 'desc' } },
drow: '0', drow: '0',
search: { value: '' }, search: { value: '' },
length: '25', length: '25',

View file

@ -52,7 +52,7 @@ describe RepositoryDatatableService do
context 'object' do context 'object' do
let(:params) do let(:params) do
{ order: { 0 => { column: '2', dir: 'asc' } }, { order: { 0 => { column: '3', dir: 'asc' } },
search: { value: 'row' } } search: { value: 'row' } }
end end
@ -65,7 +65,7 @@ describe RepositoryDatatableService do
contitions = subject.send(:build_conditions, params) contitions = subject.send(:build_conditions, params)
expect(contitions[:search_value]).to eq 'row' expect(contitions[:search_value]).to eq 'row'
expect(contitions[:order_by_column]).to eq( expect(contitions[:order_by_column]).to eq(
{ column: 2, dir: 'asc' } { column: 3, dir: 'asc' }
) )
end end
end end
@ -73,7 +73,7 @@ describe RepositoryDatatableService do
describe '#sortable_columns' do describe '#sortable_columns' do
it 'returns an array of all columns that are sortable' do it 'returns an array of all columns that are sortable' do
columns = subject.send(:sortable_columns) columns = subject.send(:sortable_columns)
expect(columns.length).to eq 5 expect(columns.length).to eq 6
end end
end end
@ -92,7 +92,7 @@ describe RepositoryDatatableService do
describe 'ordering' do describe 'ordering' do
it 'is ordered by row name asc' do it 'is ordered by row name asc' do
params = { order: { 0 => { column: '2', dir: 'asc' } }, params = { order: { 0 => { column: '3', dir: 'asc' } },
search: { value: '' } } search: { value: '' } }
subject = RepositoryDatatableService.new(repository, subject = RepositoryDatatableService.new(repository,
params, params,
@ -102,7 +102,7 @@ describe RepositoryDatatableService do
end end
it 'is ordered by row name desc' do it 'is ordered by row name desc' do
params = { order: { 0 => { column: '2', dir: 'desc' } }, params = { order: { 0 => { column: '3', dir: 'desc' } },
search: { value: '' } } search: { value: '' } }
subject = RepositoryDatatableService.new(repository, subject = RepositoryDatatableService.new(repository,
params, params,
@ -121,7 +121,7 @@ describe RepositoryDatatableService do
end end
it 'returns only the searched entity' do it 'returns only the searched entity' do
params = { order: { 0 => { column: '2', dir: 'desc' } }, params = { order: { 0 => { column: '4', dir: 'desc' } },
search: { value: 'test' } } search: { value: 'test' } }
subject = RepositoryDatatableService.new(repository, subject = RepositoryDatatableService.new(repository,
params, params,

View file

@ -8,13 +8,14 @@
"data": { "data": {
"type": "array", "type": "array",
"items":{ "items":{
"required": ["DT_RowId", "1", "2", "3", "4", "recordEditUrl", "recordUpdateUrl", "recordInfoUrl"], "required": ["DT_RowId", "1", "2", "3", "4", "5", "recordEditUrl", "recordUpdateUrl", "recordInfoUrl"],
"properties": { "properties": {
"DT_RowId": { "type": "integer" }, "DT_RowId": { "type": "integer" },
"1": { "type": "string" }, "1": { "type": "string" },
"2": { "type": "string" }, "2": { "type": "integer" },
"3": { "type": "string" }, "3": { "type": "string" },
"4": { "type": "string" }, "4": { "type": "string" },
"5": { "type": "string" },
"recordEditUrl": { "type": "string" }, "recordEditUrl": { "type": "string" },
"recordUpdateUrl": { "type": "string" }, "recordUpdateUrl": { "type": "string" },
"recordInfoUrl": { "type": "string" } "recordInfoUrl": { "type": "string" }