mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-14 00:54:32 +08:00
Implemented applying BMT filters [SCI-5980]
This commit is contained in:
parent
b269f3f612
commit
896f0ce1e3
13 changed files with 133 additions and 29 deletions
|
@ -407,6 +407,10 @@ var RepositoryDatatable = (function(global) {
|
|||
url: $(TABLE_ID).data('source'),
|
||||
data: function(d) {
|
||||
d.archived = $('.repository-show').hasClass('archived');
|
||||
|
||||
if ($('[data-external-ids]').length) {
|
||||
d.external_ids = $('[data-external-ids]').attr('data-external-ids').split(',');
|
||||
}
|
||||
},
|
||||
global: false,
|
||||
type: 'POST'
|
||||
|
|
|
@ -1,3 +1,19 @@
|
|||
.bmt-filters-button.active-filters {
|
||||
position: relative;
|
||||
|
||||
&::after {
|
||||
background: $brand-accent;
|
||||
border-radius: 50%;
|
||||
content: "";
|
||||
display: block;
|
||||
height: 8px;
|
||||
position: absolute;
|
||||
right: .3em;
|
||||
top: .3em;
|
||||
width: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
#bmtFilterContainer {
|
||||
min-width: 422px;
|
||||
z-index: 100;
|
||||
|
@ -63,15 +79,37 @@
|
|||
align-items: center;
|
||||
border-top: $border-tertiary;
|
||||
display: flex;
|
||||
padding: 0 1em;
|
||||
|
||||
.add-filter {
|
||||
margin-right: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.savedFilterContainer {
|
||||
.saved-filter-element {
|
||||
display: flex;
|
||||
.saved-filters-container {
|
||||
.title {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.saved-filters-list {
|
||||
padding: 0 1em;
|
||||
}
|
||||
|
||||
.saved-filters-element {
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
min-width: 200px;
|
||||
|
||||
i {
|
||||
color: $color-silver-chalice;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
.saved-filters-element:hover i {
|
||||
color: $color-black;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -66,8 +66,10 @@ class BioEddieAssetsController < ApplicationController
|
|||
api_request['x-api-key'] = ENV['BIOMOLECULE_TOOLKIT_API_KEY'] if ENV['BIOMOLECULE_TOOLKIT_API_KEY']
|
||||
api_request['Content-Type'] = 'application/json'
|
||||
request_body = request.body.read
|
||||
|
||||
api_request.body = request_body if request_body.present?
|
||||
api_response = http.request(api_request)
|
||||
|
||||
render body: api_response.body, content_type: api_response.content_type, status: api_response.code
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,7 +8,10 @@ class BmtFiltersController < ApplicationController
|
|||
end
|
||||
|
||||
def create
|
||||
filter = BmtFilter.new(filters_params)
|
||||
filter = BmtFilter.new(
|
||||
name: filters_params[:name],
|
||||
filters: JSON.parse(filters_params[:filters])
|
||||
)
|
||||
filter.created_by = current_user
|
||||
if filter.save
|
||||
render json: filter, serializer: BmtFilterSerializer
|
||||
|
|
|
@ -10,10 +10,14 @@ window.initBMTFilter = () => {
|
|||
el: '#bmtFilterContainer',
|
||||
data: () => {
|
||||
return {
|
||||
bmtApiBaseUrl: $($('#bmtFilterContainer')).data('bmt-api-base-url'),
|
||||
savedFilters: [],
|
||||
filters: []
|
||||
};
|
||||
},
|
||||
created() {
|
||||
this.dataTableElement = $($('#bmtFilterContainer').data('datatable-id'));
|
||||
},
|
||||
components: {
|
||||
'filter-container': FilterContainer
|
||||
},
|
||||
|
@ -23,22 +27,39 @@ window.initBMTFilter = () => {
|
|||
},
|
||||
getFilters() {
|
||||
return this.filters;
|
||||
},
|
||||
updateExternalIds(ids) {
|
||||
this.dataTableElement.attr('data-external-ids', ids.join(','));
|
||||
this.closeFilters();
|
||||
this.reloadDataTable();
|
||||
},
|
||||
clearFilters() {
|
||||
this.dataTableElement.removeAttr('data-external-ids');
|
||||
this.reloadDataTable();
|
||||
},
|
||||
closeFilters() {
|
||||
$(this.$el).closest('.dropdown').removeClass('open');
|
||||
},
|
||||
reloadDataTable() {
|
||||
this.dataTableElement.DataTable().ajax.reload();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// prevent closing of dropdown
|
||||
$('#bmtFilterContainer').on('click', (e) => e.stopPropagation());
|
||||
|
||||
$("#saveBmtFilterForm" )
|
||||
.off()
|
||||
.on('ajax:before', function() {
|
||||
$('#bmt_filter_filters').val(JSON.stringify(bmtFilterContainer.getFilters()));
|
||||
$('#bmt_filter_filters').val(JSON.stringify(bmtFilterContainer.getFilters()));
|
||||
})
|
||||
.on('ajax:success', function(e, result) {
|
||||
bmtFilterContainer.savedFilters.push(result.data);
|
||||
$('#modalSaveBmtFilter').modal('hide');
|
||||
});
|
||||
|
||||
$.get($('#bmtFilterContainer').data('url-saved-filters'), function(result) {
|
||||
$.get($('#bmtFilterContainer').data('saved-filters-url'), function(result) {
|
||||
bmtFilterContainer.savedFilters = result.data;
|
||||
})
|
||||
};
|
||||
|
|
|
@ -1,21 +1,22 @@
|
|||
<template>
|
||||
<div class="filter-container">
|
||||
<div class="header">
|
||||
<div class="dropdown savedFilterContainer">
|
||||
<div class="title" @click="openSavedFilters()">
|
||||
<div class="dropdown saved-filters-container">
|
||||
<div class="title" @click="toggleSavedFilters">
|
||||
{{ i18n.t('repositories.show.bmt_search.title') }}
|
||||
<i class="fas fa-caret-down"></i>
|
||||
<i v-if="savedFilters.length" class="fas fa-caret-down"></i>
|
||||
</div>
|
||||
<div class="dropdown-menu saved-filters-container">
|
||||
<div v-if="savedFilters.length" class="dropdown-menu saved-filters-list">
|
||||
<SavedFilterElement
|
||||
v-for="(savedFilter, index) in savedFilters"
|
||||
:key="savedFilter.id"
|
||||
:savedFilter.sync="savedFilters[index]"
|
||||
@savedFilter:load="loadFilters"
|
||||
@savedFilter:delete="savedFilters.splice(index, 1)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<button class="btn btn-light" @click="clearAllFilters">
|
||||
<button class="btn btn-light" @click="clearFilters">
|
||||
<i class="fas fa-times-circle"></i>
|
||||
{{ i18n.t('repositories.show.bmt_search.clear_all') }}
|
||||
</button>
|
||||
|
@ -37,7 +38,7 @@
|
|||
<i class="fas fa-plus"></i>
|
||||
{{ i18n.t('repositories.show.bmt_search.add_filter') }}
|
||||
</button>
|
||||
<button class="btn btn-primary">
|
||||
<button @click="fetchCIDs" class="btn btn-primary">
|
||||
{{ i18n.t('repositories.show.bmt_search.apply') }}
|
||||
</button>
|
||||
</div>
|
||||
|
@ -52,7 +53,8 @@
|
|||
name: 'FilterContainer',
|
||||
props: {
|
||||
container: Object,
|
||||
savedFilters: Array
|
||||
savedFilters: Array,
|
||||
bmtApiBaseUrl: String
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
|
@ -62,31 +64,50 @@
|
|||
components: { FilterElement, SavedFilterElement },
|
||||
computed: {
|
||||
searchJSON() {
|
||||
return this.filters.map((f) => f.data);
|
||||
const filterData = this.filters.map(f => f.data)
|
||||
return {
|
||||
'filters': filterData,
|
||||
'resultAttributeNames': ['Cid']
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
filters() {
|
||||
$('.open-save-bmt-modal').toggleClass('hidden', !this.filters.length)
|
||||
$('.bmt-filters-button').toggleClass('active-filters', !!this.filters.length)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
addFilter() {
|
||||
let id = this.filters.length ? this.filters[this.filters.length - 1].id + 1 : 1
|
||||
const id = this.filters.length ? this.filters[this.filters.length - 1].id + 1 : 1
|
||||
this.filters.push({ id: id, data: { type: "fullSequenceFilter" } });
|
||||
},
|
||||
updateFilter(filter) {
|
||||
this.filters.find((f) => f.id === filter.id).data = filter.data;
|
||||
this.$emit('filters:update', this.searchJSON);
|
||||
this.$emit('filters:update', this.searchJSON.filters);
|
||||
},
|
||||
clearAllFilters() {
|
||||
clearFilters() {
|
||||
this.filters = [];
|
||||
this.$emit('filters:clear');
|
||||
},
|
||||
openSavedFilters() {
|
||||
$('.savedFilterContainer').toggleClass('open')
|
||||
fetchCIDs() {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: this.bmtApiBaseUrl + '/macromolecule/search',
|
||||
data: JSON.stringify(this.searchJSON),
|
||||
contentType: 'application/json; charset=utf-8',
|
||||
dataType: 'json',
|
||||
success: (data) => {
|
||||
this.$emit('cids:update', data.map(i => i.Cid))
|
||||
}
|
||||
});
|
||||
},
|
||||
toggleSavedFilters() {
|
||||
$('.saved-filters-container').toggleClass('open');
|
||||
},
|
||||
loadFilters(filters) {
|
||||
this.clearAllFilters();
|
||||
this.toggleSavedFilters();
|
||||
this.clearFilters();
|
||||
filters.forEach((filter, index) => {
|
||||
this.filters.push(
|
||||
{
|
||||
|
@ -95,6 +116,7 @@
|
|||
}
|
||||
);
|
||||
});
|
||||
this.fetchCIDs();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<script>
|
||||
import FilterMixin from 'vue/bmt_filter/mixins/filter.js'
|
||||
export default {
|
||||
name: 'fullSequenceFilter',
|
||||
name: 'fullsequenceFilter',
|
||||
mixins: [FilterMixin],
|
||||
data() {
|
||||
return {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
<template>
|
||||
<div class="saved-filter-element">
|
||||
{{ savedFilter.attributes.name }}
|
||||
<div class="saved-filters-element">
|
||||
<span @click="loadFilters">{{ savedFilter.attributes.name }}</span>
|
||||
<button class="btn btn-light icon-btn" @click="deleteFilter">
|
||||
<i class="fas fa-trash"></i>
|
||||
</button>
|
||||
|
@ -14,6 +14,9 @@
|
|||
savedFilter: Object
|
||||
},
|
||||
methods: {
|
||||
loadFilters() {
|
||||
this.$emit('savedFilter:load', this.savedFilter.attributes.filters)
|
||||
},
|
||||
deleteFilter() {
|
||||
let filter = this
|
||||
$.ajax({
|
||||
|
@ -28,4 +31,3 @@
|
|||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
|
|
@ -75,6 +75,8 @@ class RepositoryDatatableService
|
|||
repository_rows.count
|
||||
end
|
||||
|
||||
repository_rows = repository_rows.where(external_id: @params[:external_ids]) if @params[:external_ids]
|
||||
|
||||
if search_value.present?
|
||||
if @repository.default_search_fileds.include?('users.full_name')
|
||||
repository_rows = repository_rows.joins(:created_by)
|
||||
|
|
|
@ -88,7 +88,7 @@
|
|||
<% if @repository.is_a?(BmtRepository) %>
|
||||
<div class="dropdown">
|
||||
<button id="bmtFiltersDropdown"
|
||||
class="btn btn-secondary"
|
||||
class="btn btn-secondary bmt-filters-button"
|
||||
type="button"
|
||||
data-toggle="dropdown"
|
||||
aria-haspopup="true"
|
||||
|
@ -96,9 +96,18 @@
|
|||
<span class="fas fa-microscope"></span>
|
||||
<%= t('repositories.show.bmt_search.bmt_filter') %>
|
||||
</button>
|
||||
<div class="dropdown-menu bmt-filters-container" id="bmtFilterContainer" data-url-saved-filters="<%= bmt_filters_path %>">
|
||||
<div
|
||||
class="dropdown-menu bmt-filters-container"
|
||||
id="bmtFilterContainer"
|
||||
data-datatable-id="#repository-table-<%= @repository.id %>"
|
||||
data-saved-filters-url="<%= bmt_filters_url %>"
|
||||
data-bmt-api-base-url="<%= bmt_request_url(path: 'api') %>"
|
||||
>
|
||||
<filter-container
|
||||
@filters:update="updateFilters"
|
||||
@filters:clear="clearFilters"
|
||||
@cids:update="updateExternalIds"
|
||||
:bmt-api-base-url="bmtApiBaseUrl"
|
||||
:saved-filters.sync="savedFilters"
|
||||
:filters.sync="filters" />
|
||||
</div>
|
||||
|
|
|
@ -785,7 +785,8 @@ Rails.application.routes.draw do
|
|||
|
||||
match 'biomolecule_toolkit/*path', to: 'bio_eddie_assets#bmt_request',
|
||||
via: %i(get post put delete),
|
||||
defaults: { format: 'json' }
|
||||
defaults: { format: 'json' },
|
||||
as: 'bmt_request'
|
||||
|
||||
post 'global_activities', to: 'global_activities#index'
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@ class CreateBmtFilters < ActiveRecord::Migration[6.1]
|
|||
def change
|
||||
create_table :bmt_filters do |t|
|
||||
t.string :name, null: false
|
||||
t.string :filters, null: false
|
||||
t.json :filters, null: false
|
||||
t.references :created_by, index: true, foreign_key: { to_table: :users }
|
||||
t.timestamps
|
||||
end
|
||||
|
|
|
@ -320,7 +320,7 @@ ALTER SEQUENCE public.assets_id_seq OWNED BY public.assets.id;
|
|||
CREATE TABLE public.bmt_filters (
|
||||
id bigint NOT NULL,
|
||||
name character varying NOT NULL,
|
||||
filters character varying NOT NULL,
|
||||
filters json NOT NULL,
|
||||
created_by_id bigint,
|
||||
created_at timestamp(6) without time zone NOT NULL,
|
||||
updated_at timestamp(6) without time zone NOT NULL
|
||||
|
|
Loading…
Add table
Reference in a new issue