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(); initImportRecordsModal();
initTable(); initTable();
initRepositoryViewSwitcher(); initRepositoryViewSwitcher();
initArchivingActionsInDropdown(); initArchivingActionsInDropdown();
initFilterSaving();
}(window)); }(window));

View file

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

View file

@ -19,36 +19,51 @@ class RepositoryTableFiltersController < ApplicationController
def create def create
repository_table_filter = @repository.repository_table_filters.new( 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 created_by: current_user
) )
repository_table_filter.transaction do repository_table_filter.transaction do
repository_table_filter.save! 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) repository_table_filter.repository_table_filter_elements.create!(custom_column_params)
end end
end end
if repository_table_filter.persisted?
render json: repository_table_filter render json: repository_table_filter
else rescue ActiveRecord::RecordInvalid
render json: repository_table_filter.errors, status: :unprocessable_entity error_key =
end 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 end
def update def update
@repository_table_filter.transaction do @repository_table_filter.transaction do
@repository_table_filter.default_columns = repository_table_filter_params[:default_columns] @repository_table_filter.name = repository_table_filter_params[:name]
repository_table_filter_params[:custom_columns].each do |custom_column_params| @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 @repository_table_filter.repository_table_filter_elements
.find_by(repository_column_id: custom_column_params[:repository_column_id]) .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_or_initialize_by(repository_column_id: custom_column_params['repository_column_id'])
.update!(custom_column_params) .update!(custom_column_params)
end end
end end
if @repository_table_filter.persisted?
render json: @repository_table_filter render json: @repository_table_filter
else rescue ActiveRecord::RecordInvalid
render json: repository_table_filter.errors, status: :unprocessable_entity error_key =
end @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 end
def destroy def destroy
@ -79,7 +94,16 @@ class RepositoryTableFiltersController < ApplicationController
render_403 unless can_manage_repository?(@repository) render_403 unless can_manage_repository?(@repository)
end 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 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
end end

View file

@ -48,6 +48,9 @@ window.initRepositoryFilter = () => {
applyFilters() { applyFilters() {
this.dataTableElement this.dataTableElement
.attr('data-repository-filter-json', JSON.stringify({ filter_elements: this.filtersJSON })); .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'); $('#filterContainer .dropdown-selector-container').removeClass('open');
$('#filtersDropdownButton').removeClass('open'); $('#filtersDropdownButton').removeClass('open');
$('#filtersDropdownButton').addClass('active-filters'); $('#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> <span class="hidden-xs"><%= t("repositories.add_new_record") %></span>
</button> </button>
<% end %> <% 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"> <span id="editDeleteCopy" data-toggle="buttons" style="display:none">
<%if can_update_repository_rows?(@repository) %> <%if can_update_repository_rows?(@repository) %>
<button type="button" class="btn btn-light editAdd" id="editRepositoryRecord" disabled data-view-mode="active"> <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: 'repository_columns/manage_column_modal', locals: { my_module_page: false } %>
<%= render partial: 'save_bmt_filter_modal' %> <%= render partial: 'save_bmt_filter_modal' %>
<%= render partial: 'save_repository_filter_modal' %>
<%= render partial: 'repository_filters' %>
<% if @repository.is_a?(BmtRepository) %> <% if @repository.is_a?(BmtRepository) %>
<%= javascript_pack_tag 'vue/bmt_filter' %> <%= javascript_pack_tag 'vue/bmt_filter' %>

View file

@ -157,6 +157,13 @@ en:
attributes: attributes:
base: base:
per_column_limit: "Too many items in the column" 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: webhook:
attributes: attributes:
configuration: configuration:
@ -1372,6 +1379,7 @@ en:
all_teams_tooltip: "This will disable individual team settings" all_teams_tooltip: "This will disable individual team settings"
success_message: "Selected sharing options for the Inventory %{inventory_name} have been saved." success_message: "Selected sharing options for the Inventory %{inventory_name} have been saved."
show: show:
name: "Name"
archived_inventory_items: "%{repository_name} archived items" archived_inventory_items: "%{repository_name} archived items"
archived_inventory: "Archived %{repository_name}" archived_inventory: "Archived %{repository_name}"
inventory_archived_items: "%{repository_name} archived items" inventory_archived_items: "%{repository_name} archived items"
@ -1391,6 +1399,9 @@ en:
no_archived_items_matched: "No archived items matched your search request" no_archived_items_matched: "No archived items matched your search request"
error_searching: "Error searching, please try again" error_searching: "Error searching, please try again"
filters: filters:
save_filters: "Save filters"
new_filter: "New filter"
overwrite_filter: "Overwrite"
title: "Filters" title: "Filters"
clear: "Clear" clear: "Clear"
add_filter: "Add filter" add_filter: "Add filter"