Merge pull request #2377 from biosistemika/master

Master >> Develop
This commit is contained in:
Urban Rotnik 2020-01-29 14:25:11 +01:00 committed by GitHub
commit fc14bf05be
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
25 changed files with 114 additions and 170 deletions

View file

@ -1 +1 @@
1.17.10
1.18.1

View file

@ -108,18 +108,18 @@
var permissionCBs = form.find("input[name='write_permissions[]']");
var permissionChanges = form.find("input[name='permission_changes']");
var submitBtn = form.find('input[type="submit"]');
var selectAllCheckbox = form.find('.all-teams .simple-checkbox');
var selectAllCheckbox = form.find('.all-teams .sci-checkbox');
form.find('.teams-list').find('input.simple-checkbox, .permission-selector')
form.find('.teams-list').find('input.sci-checkbox, .permission-selector')
.toggleClass('hidden', selectAllCheckbox.is(':checked'));
form.find('.all-teams .trigger-checkbox')
form.find('.all-teams .sci-toggle-checkbox')
.toggleClass('hidden', !selectAllCheckbox.is(':checked'))
.attr('disabled', !selectAllCheckbox.is(':checked'));
selectAllCheckbox.change(function() {
form.find('.teams-list').find('input.simple-checkbox, .permission-selector')
form.find('.teams-list').find('input.sci-checkbox, .permission-selector')
.toggleClass('hidden', this.checked);
form.find('.all-teams .trigger-checkbox').toggleClass('hidden', !this.checked)
form.find('.all-teams .sci-toggle-checkbox').toggleClass('hidden', !this.checked)
.attr('disabled', !this.checked);
});

View file

@ -17,6 +17,7 @@ var RepositoryDatatable = (function(global) {
var SELECT_ALL_SELECTOR = "#checkbox > input[name=select_all]"
var rowsSelected = [];
var rowsLocked = [];
// Tells whether we're currently viewing or editing table
var currentMode = 'viewMode';
@ -76,6 +77,11 @@ var RepositoryDatatable = (function(global) {
$('#copyRepositoryRecords').prop('disabled', false);
$('#assignRepositoryRecords').prop('disabled', false);
$('#unassignRepositoryRecords').prop('disabled', false);
if (rowsSelected.some(r=> rowsLocked.indexOf(r) >= 0)) { // Some selected rows is rowsLocked
$('#editRepositoryRecord').prop('disabled', true);
$('#deleteRepositoryRecordsButton').prop('disabled', true);
}
$('#editDeleteCopy').show();
}
} else if (currentMode === 'editMode') {
@ -422,8 +428,9 @@ var RepositoryDatatable = (function(global) {
orderable: false,
className: 'dt-body-center',
sWidth: '1%',
render: function() {
return "<input class='repository-row-selector sci-checkbox' type='checkbox'><span class='sci-checkbox-label'></span>";
render: function(data, type, row) {
return `<input class='repository-row-selector sci-checkbox' type='checkbox' data-editable="${row.recordEditable}">
<span class='sci-checkbox-label'></span>`;
}
}, {
// Assigned column is not searchable
@ -433,11 +440,13 @@ var RepositoryDatatable = (function(global) {
orderable: true,
className: 'assigned-column',
sWidth: '1%',
render: function(data) {
render: function(data, type, row) {
let content = data;
if (EDITABLE) {
content = '<i class="repository-row-edit-icon fas fa-pencil-alt"></i>' + content;
let icon = '<i class="repository-row-edit-icon fas fa-pencil-alt"></i>';
if (!row.recordEditable) {
icon = `<i class="repository-row-lock-icon fas fa-lock" title="${I18n.t('repositories.table.locked_item')}"></i>`;
}
content = icon + content;
return content;
}
}, {
@ -461,6 +470,7 @@ var RepositoryDatatable = (function(global) {
sSearch: I18n.t('general.filter_dots')
},
rowCallback: function(row, data) {
$(row).attr('data-editable', data.recordEditable);
// Get row ID
let rowId = data.DT_RowId;
// If row ID is in the list of selected row IDs
@ -576,6 +586,10 @@ var RepositoryDatatable = (function(global) {
$('.dataTables_filter').find('label').remove();
$('.main-actions, .pagination-row').removeClass('hidden');
$(TABLE_ID).find('tr[data-editable=false]').each(function(_, e) {
rowsLocked.push(parseInt($(e).attr('id'), 10));
});
}
});

View file

@ -24,12 +24,12 @@ var RepositoryStatusColumnType = (function() {
$.each($statusRows, (index, statusRow) => {
var $row = $(statusRow);
var $statusField = $row.find('.status-item-field');
var iconPlaceholder = $row.find(iconId).attr('emoji');
var icon = $row.find(iconId).attr('emoji');
var stringLength = $statusField.val().length;
if (stringLength < GLOBAL_CONSTANTS.NAME_MIN_LENGTH
|| stringLength > GLOBAL_CONSTANTS.NAME_MAX_LENGTH
|| !iconPlaceholder) {
|| !icon) {
$row.addClass('error').attr('data-error-text', I18n.t('libraries.manange_modal_column.status_type.errors.icon_and_name_error'));
} else {
$row.removeClass('error');
@ -55,6 +55,7 @@ var RepositoryStatusColumnType = (function() {
var iconElement = this;
picker.on('emoji', emoji => {
$(iconElement).attr('emoji', emoji).html(twemoji.parse(emoji));
validateForm();
});
if (picker.pickerVisible) {

View file

@ -21,8 +21,15 @@
}
tbody {
tr:hover {
tr {
.assigned-column {
.repository-row-lock-icon {
display: none !important;
}
}
}
tr:hover {
.assigned-column {
.repository-row-edit-icon {
display: none !important;

View file

@ -116,6 +116,7 @@
padding-top: 123px;
.dataTables_scrollHead {
position: -webkit-sticky !important;
position: sticky !important;
top: 194px;
z-index: 90;
@ -418,13 +419,8 @@
display: flex;
padding: 5px 0;
.simple-checkbox.hidden {
.sci-checkbox.hidden {
display: inline-block !important;
+ .checkbox-label {
display: inline-block;
opacity: 0;
}
}
}
}
@ -441,7 +437,7 @@
display: flex;
flex-grow: 1;
.checkbox-label {
.sci-checkbox-container {
margin-right: 5px;
}
}
@ -470,4 +466,3 @@
color: $color-silver-chalice;
}
}

View file

@ -33,6 +33,10 @@
width: 30px;
}
.repository-row-lock-icon {
width: 30px;
}
.assign-counter-container {
border-radius: $border-radius-tag;
cursor: pointer;
@ -198,6 +202,12 @@
.editing {
border: 1px solid;
}
tr[data-editable=false] {
.assign-counter-container {
margin-left: 0;
}
}
}
&.editing {

View file

@ -1,108 +0,0 @@
// scss-lint:disable SelectorDepth SelectorFormat QualifyingElement
// scss-lint:disable NestingDepth ImportantRule
@import "constants";
@import "mixins";
:root {
--checkbox-size: 16px;
}
input[type="checkbox"].simple-checkbox {
cursor: pointer;
flex-shrink: 0;
height: var(--checkbox-size);
margin: 0;
opacity: 0;
position: relative;
width: var(--checkbox-size);
z-index: 2;
+ .checkbox-label {
display: inline-block;
flex-shrink: 0;
height: var(--checkbox-size);
margin-left: calc((var(--checkbox-size) * -1) - 1px);
position: relative;
width: var(--checkbox-size);
&::before {
content: "\f0c8";
font-family: "Font Awesome 5 Free";
font-size: var(--checkbox-size);
font-weight: 400;
left: 0;
line-height: var(--checkbox-size);
position: absolute;
text-align: center;
top: 1px;
width: var(--checkbox-size);
}
}
&.disabled {
pointer-events: none;
+ .checkbox-label {
color: $color-silver-chalice;
cursor: not-allowed;
}
}
&.hidden + .checkbox-label {
display: none;
}
&:checked + .checkbox-label {
&::before {
content: "\f14a";
}
}
}
input[type="checkbox"].trigger-checkbox {
cursor: pointer;
flex-shrink: 0;
height: 16px;
margin: 0;
opacity: 0;
position: relative;
width: 24px;
z-index: 2;
+ .checkbox-label {
background: $color-silver-chalice;
border-radius: 8px;
display: inline-block;
flex-shrink: 0;
height: 16px;
margin-left: -24px;
position: relative;
transition: .2s;
width: 24px;
&::before {
background: $color-white;
border-radius: 7px;
content: "";
height: 12px;
left: 0;
margin: 2px;
position: absolute;
transition: .2s;
width: 12px;
}
}
&.hidden + .checkbox-label {
display: none;
}
&:checked + .checkbox-label {
background: $brand-success;
&::before {
left: 8px;
}
}
}

View file

@ -4,6 +4,13 @@
--sci-checkbox-size: 16px;
}
.sci-checkbox-container {
display: inline-block;
height: var(--sci-checkbox-size);
position: relative;
width: var(--sci-checkbox-size);
}
input[type="checkbox"].sci-checkbox {
cursor: pointer;
flex-shrink: 0;
@ -36,7 +43,6 @@ input[type="checkbox"].sci-checkbox {
line-height: calc(var(--sci-checkbox-size) - 2px);
position: absolute;
text-align: center;
top: 1px;
transition: .2s;
width: var(--sci-checkbox-size);
}

View file

@ -1,5 +1,12 @@
// scss-lint:disable SelectorDepth QualifyingElement NestingDepth
.sci-toggle-checkbox-container {
display: inline-block;
height: 16px;
position: relative;
width: 24px;
}
input[type="checkbox"].sci-toggle-checkbox {
cursor: pointer;
flex-shrink: 0;
@ -17,8 +24,9 @@ input[type="checkbox"].sci-toggle-checkbox {
display: inline-block;
flex-shrink: 0;
height: 16px;
margin-left: -27px;
position: relative;
left: 0;
position: absolute;
top: 0;
transition: .2s;
width: 24px;

View file

@ -4,7 +4,7 @@ module RepositoryColumns
class ChecklistColumnsController < BaseColumnsController
before_action :load_column, only: %i(update destroy items)
before_action :check_create_permissions, only: :create
before_action :check_manage_permissions, only: %i(update destroy items)
before_action :check_manage_permissions, only: %i(update destroy)
helper_method :delimiters
def create

View file

@ -4,7 +4,7 @@ module RepositoryColumns
class ListColumnsController < BaseColumnsController
before_action :load_column, only: %i(update destroy items)
before_action :check_create_permissions, only: :create
before_action :check_manage_permissions, only: %i(update destroy items)
before_action :check_manage_permissions, only: %i(update destroy)
helper_method :delimiters
def create

View file

@ -5,7 +5,7 @@ module RepositoryColumns
include InputSanitizeHelper
before_action :load_column, only: %i(update destroy items)
before_action :check_create_permissions, only: :create
before_action :check_manage_permissions, only: %i(update destroy items)
before_action :check_manage_permissions, only: %i(update destroy)
def create
service = RepositoryColumns::CreateColumnService

View file

@ -28,7 +28,8 @@ module RepositoryDatatableHelper
record.id
),
'recordInfoUrl': Rails.application.routes.url_helpers
.repository_row_path(record.id)
.repository_row_path(record.id),
'recordEditable': record.editable?
}
# Add custom columns

View file

@ -11,5 +11,5 @@ class RepositoryChecklistItem < ApplicationRecord
belongs_to :last_modified_by, foreign_key: 'last_modified_by_id', class_name: 'User',
inverse_of: :modified_repository_checklist_types
has_many :repository_checklist_items_values, dependent: :destroy
has_many :repository_checklist_values, through: :repository_checklist_items_values
has_many :repository_checklist_values, through: :repository_checklist_items_values, dependent: :destroy
end

View file

@ -37,4 +37,8 @@ class RepositoryRow < ApplicationRecord
.where('repositories.team_id = ? and repository_rows.created_by_id = ?', team, user)
.update_all(created_by_id: new_owner.id)
end
def editable?
true
end
end

View file

@ -4,8 +4,8 @@ module RepositoryDatatable
class RepositoryListValueSerializer < RepositoryBaseValueSerializer
def value
{
id: object.repository_list_item.id,
text: object.data
id: (object.repository_list_item&.id || ''),
text: (object.data || '')
}
end
end

View file

@ -52,6 +52,7 @@ class RepositoryDatatableService
.select('COUNT(DISTINCT my_modules.experiment_id) AS "assigned_experiments_count"')
.select('COUNT(DISTINCT experiments.project_id) AS "assigned_projects_count"')
end
repository_rows = repository_rows.preload(Extends::REPOSITORY_ROWS_PRELOAD_RELATIONS)
@repository_rows = sort_rows(order_obj, repository_rows)
end

View file

@ -17,29 +17,37 @@
<div class="data-list">
<div class="all-teams">
<span class="team-selector" title="<%= t("repositories.index.modal_share.all_teams_tooltip") %>">
<%= check_box_tag 'select_all_teams', 0, @repository.shared_read? || @repository.shared_write?, { class: 'simple-checkbox' } %>
<span class="checkbox-label"></span>
<span class="sci-checkbox-container">
<%= check_box_tag 'select_all_teams', 0, @repository.shared_read? || @repository.shared_write?, { class: 'sci-checkbox' } %>
<span class="sci-checkbox-label"></span>
</span>
<%= t("repositories.index.modal_share.all_teams") %>
</span>
<span class="permission-selector">
<%= check_box_tag 'select_all_write_permission', 0, @repository.shared_write?, { class: 'hidden trigger-checkbox' }%>
<span class="checkbox-label"></span>
<span class="sci-toggle-checkbox-container">
<%= check_box_tag 'select_all_write_permission', 0, @repository.shared_write?, { class: 'hidden sci-toggle-checkbox' }%>
<span class="sci-toggle-checkbox-label"></span>
</span>
</span>
</div>
<div class="teams-list">
<% (current_user.teams - [@repository.team]).each do |t| %>
<div class="team-container">
<div class="team-selector">
<%= check_box_tag 'share_team_ids[]', t.id, @repository.private_shared_with?(t), {id: "shared_#{t.id}", class: "simple-checkbox"} %>
<span class="checkbox-label"></span>
<span class="sci-checkbox-container">
<%= check_box_tag 'share_team_ids[]', t.id, @repository.private_shared_with?(t), {id: "shared_#{t.id}", class: "sci-checkbox"} %>
<span class="sci-checkbox-label"></span>
</span>
<%= t.name %>
</div>
<div class="permission-selector">
<%= check_box_tag 'write_permissions[]', t.id, @repository.private_shared_with_write?(t), {
id: "editable_#{t.id}",
class: (@repository.private_shared_with?(t) ? 'trigger-checkbox' : 'trigger-checkbox hidden')
}.compact %>
<span class="checkbox-label"></span>
<span class="sci-toggle-checkbox-container">
<%= check_box_tag 'write_permissions[]', t.id, @repository.private_shared_with_write?(t), {
id: "editable_#{t.id}",
class: (@repository.private_shared_with?(t) ? 'sci-toggle-checkbox' : 'sci-toggle-checkbox hidden')
}.compact %>
<span class="sci-toggle-checkbox-label"></span>
</span>
</div>
</div>
<% end %>

View file

@ -2,8 +2,10 @@
<div class="col-sm-3"></div>
<div class="col-sm-9">
<div class="permission-selector">
<%= check_box_tag 'range', '', column&.repository_date_range_value?, { id: 'date-range', class: column.new_record? ? 'simple-checkbox' : 'simple-checkbox disabled' } %>
<span class="checkbox-label"></span>
<span class="sci-checkbox-container">
<%= check_box_tag 'range', '', column&.repository_date_range_value?, { id: 'date-range', class: column.new_record? ? 'sci-checkbox' : 'sci-checkbox disabled' } %>
<span class="sci-checkbox-label"></span>
</span>
<span class="range-label"><%= t('libraries.manange_modal_column.datetime_type.range_label') %></span>
</div>
</div>

View file

@ -2,8 +2,10 @@
<div class="col-sm-3"></div>
<div class="col-sm-9">
<div class="permission-selector">
<%= check_box_tag 'range', '', column&.repository_date_time_range_value?, { id: 'datetime-range', class: column.new_record? ? 'simple-checkbox' : 'simple-checkbox disabled' } %>
<span class="checkbox-label"></span>
<span class="sci-checkbox-container">
<%= check_box_tag 'range', '', column&.repository_date_time_range_value?, { id: 'datetime-range', class: column.new_record? ? 'sci-checkbox' : 'sci-checkbox disabled' } %>
<span class="sci-checkbox-label"></span>
</span>
<span class="range-label"><%= t('libraries.manange_modal_column.datetime_type.range_label') %></span>
</div>
</div>

View file

@ -2,8 +2,10 @@
<div class="col-sm-3"></div>
<div class="col-sm-9">
<div class="permission-selector">
<%= check_box_tag 'range', '', column&.repository_time_range_value?, { id: 'time-range', class: column.new_record? ? 'simple-checkbox' : 'simple-checkbox disabled' } %>
<span class="checkbox-label"></span>
<span class="sci-checkbox-container">
<%= check_box_tag 'range', '', column&.repository_time_range_value?, { id: 'time-range', class: column.new_record? ? 'sci-checkbox' : 'sci-checkbox disabled' } %>
<span class="sci-checkbox-label"></span>
</span>
<span class="range-label"><%= t('libraries.manange_modal_column.datetime_type.range_label') %></span>
</div>
</div>

View file

@ -79,6 +79,9 @@ class Extends
repository_status_value: :repository_status_item,
repository_asset_value: { asset: { file_attachment: :blob } }]
# Array of preload relations used in search query for repository rows
REPOSITORY_ROWS_PRELOAD_RELATIONS = []
# List of implemented core API versions
API_VERSIONS = ['v1']

View file

@ -1055,6 +1055,7 @@ en:
added_on: "Added on"
added_by: "Added by"
enter_row_name: "Enter name"
locked_item: "This is read-only item."
assets:
select_file_btn: "Select File (Max %{max_size} MB)..."
text:

View file

@ -262,18 +262,5 @@ RSpec.describe RepositoryColumns::StatusColumnsController, type: :controller do
expect(response).to(have_http_status(404))
end
end
context 'when user does not have permissions' do
before do
user_team.role = :guest
user_team.save
end
it 'respons with status 403' do
action
expect(response).to(have_http_status(403))
end
end
end
end