Implement saving repository filters [SCI-6230] (#3748)

* Implement saving repository filters [SCI-6230]

* Remove unnecessary logging [SCI-6230]

* Refactor filter saving [SCI-6230]

* Remove unnecessary files, linter fixes [SCI_6230]
This commit is contained in:
artoscinote 2022-01-05 15:02:09 +01:00 committed by GitHub
parent 4af7a2eb7f
commit 3f87d250ce
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 163 additions and 18 deletions

View file

@ -197,8 +197,58 @@
});
}
function initFilterSaving() {
$(document).on('click', '#overwriteFilterLink', function() {
var $modal = $('#modalSaveRepositoryTableFilter');
// set overwrite flag
$modal.data('overwrite', true);
// revert to 'create' form
$modal.on('hidden.bs.modal', function() {
$modal.removeData('overwrite');
});
});
$(document).on('click', '#saveRepositoryTableFilterButton', function() {
var $modal = $('#modalSaveRepositoryTableFilter');
var url = $modal.data().saveUrl;
var method;
if ($modal.data().overwrite) {
method = 'PUT';
url = url + '/' + $modal.data().repositoryTableFilterId;
} else {
method = 'POST';
}
$.ajax({
type: method,
url: url,
contentType: 'application/json; charset=utf-8',
data: JSON.stringify({
repository_table_filter: {
name: $('#repository_table_filter_name').val(),
repository_table_filter_elements_json: $('#repository_table_filter_elements_json').val()
}
}),
success: function(response) {
var $overwriteLink = $('#overwriteFilterLink');
$modal.modal('hide');
$overwriteLink.removeClass('hidden');
$modal.data('repositoryTableFilterId', response.data.id);
$('#currentFilterName').html(response.data.name);
},
error: function(response) {
HelperModule.flashAlertMsg(response.responseJSON.message, 'danger');
}
});
});
}
initImportRecordsModal();
initTable();
initRepositoryViewSwitcher();
initArchivingActionsInDropdown();
initFilterSaving();
}(window));

View file

@ -41,3 +41,9 @@
text-align: center;
}
}
.main-actions {
.dropdown-menu {
font-size: 14px;
}
}

View file

@ -19,36 +19,51 @@ class RepositoryTableFiltersController < ApplicationController
def create
repository_table_filter = @repository.repository_table_filters.new(
default_columns: repository_table_filter_params[:default_columns],
name: repository_table_filter_params[:name],
default_columns: repository_table_filter_elements_params[:default_columns],
created_by: current_user
)
repository_table_filter.transaction do
repository_table_filter.save!
repository_table_filter_params[:custom_columns].each do |custom_column_params|
repository_table_filter_elements_params[:custom_columns].each do |custom_column_params|
repository_table_filter.repository_table_filter_elements.create!(custom_column_params)
end
end
if repository_table_filter.persisted?
render json: repository_table_filter
else
render json: repository_table_filter.errors, status: :unprocessable_entity
end
render json: repository_table_filter
rescue ActiveRecord::RecordInvalid
error_key =
repository_table_filter.errors[:repository_table_filter_elements] ? 'repository_column.must_exist' : 'general'
message = I18n.t("activerecord.errors.models.repository_table_filter_element.attributes.#{error_key}")
render json: { message: message }, status: :unprocessable_entity
end
def update
@repository_table_filter.transaction do
@repository_table_filter.default_columns = repository_table_filter_params[:default_columns]
repository_table_filter_params[:custom_columns].each do |custom_column_params|
@repository_table_filter.name = repository_table_filter_params[:name]
@repository_table_filter.default_columns = repository_table_filter_elements_params[:default_columns]
@repository_table_filter.save!
repository_column_ids =
repository_table_filter_elements_params[:custom_columns].map { |r| r['repository_column_id'] }
@repository_table_filter.repository_table_filter_elements
.where.not(
repository_column_id: repository_column_ids
).find_each(&:destroy!)
repository_table_filter_elements_params[:custom_columns].each do |custom_column_params|
@repository_table_filter.repository_table_filter_elements
.find_by(repository_column_id: custom_column_params[:repository_column_id])
.find_or_initialize_by(repository_column_id: custom_column_params['repository_column_id'])
.update!(custom_column_params)
end
end
if @repository_table_filter.persisted?
render json: @repository_table_filter
else
render json: repository_table_filter.errors, status: :unprocessable_entity
end
render json: @repository_table_filter
rescue ActiveRecord::RecordInvalid
error_key =
@repository_table_filter.errors[:repository_table_filter_elements] ? 'repository_column.must_exist' : 'general'
message = I18n.t("activerecord.errors.models.repository_table_filter_element.attributes.#{error_key}")
render json: { message: message }, status: :unprocessable_entity
end
def destroy
@ -79,7 +94,16 @@ class RepositoryTableFiltersController < ApplicationController
render_403 unless can_manage_repository?(@repository)
end
def repository_table_filter_elements_params
columns = JSON.parse(repository_table_filter_params[:repository_table_filter_elements_json])
@repository_table_filter_elements_params ||= {
default_columns: columns.select { |column_params| column_params['repository_column_id'].is_a?(String) },
custom_columns: columns.select { |column_params| column_params['repository_column_id'].is_a?(Integer) }
}
end
def repository_table_filter_params
require(:repository_table_filter).permit(:name, default_columns: [], custom_columns: [])
params.require(:repository_table_filter).permit(:name, :repository_table_filter_elements_json)
end
end

View file

@ -48,6 +48,9 @@ window.initRepositoryFilter = () => {
applyFilters() {
this.dataTableElement
.attr('data-repository-filter-json', JSON.stringify({ filter_elements: this.filtersJSON }));
$('#repository_table_filter_elements_json').val(JSON.stringify(this.filtersJSON));
$('#saveRepositoryFilters').removeClass('hidden');
$('#filterContainer .dropdown-selector-container').removeClass('open');
$('#filtersDropdownButton').removeClass('open');
$('#filtersDropdownButton').addClass('active-filters');

View file

@ -0,0 +1,24 @@
<div class="modal fade" data-save-url="<%= repository_repository_table_filters_path(@repository) %>" id="modalSaveRepositoryTableFilter" tabindex="-1" role="dialog" aria-labelledby="modal-import-records-label">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">
<%= t('repositories.show.filters.save_filters') %>
</h4>
</div>
<div class="modal-body">
<input type="hidden" id="repository_table_filter_elements_json">
<div class="sci-input-container">
<label for="repository_table_filter_name"><%= t('repositories.show.name') %></label>
<input type="text" id="repository_table_filter_name" class="sci-input-field" >
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal"><%= t('general.cancel')%></button>
<button class="btn btn-success" id="saveRepositoryTableFilterButton"><%= t('general.save') %></button>
</div>
</div>
</div>
</div>

View file

@ -13,8 +13,34 @@
<span class="hidden-xs"><%= t("repositories.add_new_record") %></span>
</button>
<% end %>
<% if can_manage_repository?(@repository) %>
<div class="repository-cog dropdown hidden" id="saveRepositoryFilters">
<button type="button"
class="btn btn-default"
data-toggle="dropdown"
aria-haspopup="true"
aria-expanded="true">
<span class="fas fa-save"></span>
<span class="hidden-xs"><%= t("repositories.show.filters.save_filters") %></span>
<span class="caret"></span>
</button>
<ul class="dropdown-menu pull-right">
<li id="newFilterLink" data-view-mode="active">
<a href="#" data-toggle="modal" data-target="#modalSaveRepositoryTableFilter">
<span class="fas fa-plus"></span>
<%= t('repositories.show.filters.new_filter') %>
</a>
</li>
<li id="overwriteFilterLink" class="hidden" data-view-mode="active">
<a href="#" data-toggle="modal" data-target="#modalSaveRepositoryTableFilter">
<span class="fas fa-save"></span>
<%= t('repositories.show.filters.overwrite_filter') %>
<span id="currentFilterName"></span>
</a>
</li>
</ul>
</div>
<% if can_manage_repository_rows?(@repository) %>
<span id="editDeleteCopy" data-toggle="buttons" style="display:none">
<%if can_update_repository_rows?(@repository) %>
<button type="button" class="btn btn-light editAdd" id="editRepositoryRecord" disabled data-view-mode="active">

View file

@ -168,7 +168,8 @@
<%= render partial: 'repository_columns/manage_column_modal', locals: { my_module_page: false } %>
<%= render partial: 'save_bmt_filter_modal' %>
<%= render partial: 'save_repository_filter_modal' %>
<%= render partial: 'repository_filters' %>
<% if @repository.is_a?(BmtRepository) %>
<%= javascript_pack_tag 'vue/bmt_filter' %>

View file

@ -157,6 +157,13 @@ en:
attributes:
base:
per_column_limit: "Too many items in the column"
repository_table_filter_element:
general: "There was a problem saving the filter."
attributes:
repository_column:
must_exist: Filter cannot be saved because one or more columns no longer exist. Please update your filter before saving.
parameters:
must_be_valid: Filter cannot be saved because some filter values no longer exist. Please update your filter before saving.
webhook:
attributes:
configuration:
@ -1372,6 +1379,7 @@ en:
all_teams_tooltip: "This will disable individual team settings"
success_message: "Selected sharing options for the Inventory %{inventory_name} have been saved."
show:
name: "Name"
archived_inventory_items: "%{repository_name} archived items"
archived_inventory: "Archived %{repository_name}"
inventory_archived_items: "%{repository_name} archived items"
@ -1391,6 +1399,9 @@ en:
no_archived_items_matched: "No archived items matched your search request"
error_searching: "Error searching, please try again"
filters:
save_filters: "Save filters"
new_filter: "New filter"
overwrite_filter: "Overwrite"
title: "Filters"
clear: "Clear"
add_filter: "Add filter"