Add saved filters backend [SCI-5977] (#3509)

* Add saved filters backend [SCI-5977]

* Rework filter saving [SCI-5977]

Co-authored-by: Martin Artnik <martin@scinote.net>
This commit is contained in:
aignatov-bio 2021-08-26 14:50:54 +02:00 committed by Martin Artnik
parent ef0e45be04
commit b269f3f612
12 changed files with 197 additions and 27 deletions

View file

@ -0,0 +1,34 @@
# frozen_string_literal: true
class BmtFiltersController < ApplicationController
before_action :check_manage_permission, except: :index
def index
render json: BmtFilter.all, each_serializer: BmtFilterSerializer
end
def create
filter = BmtFilter.new(filters_params)
filter.created_by = current_user
if filter.save
render json: filter, serializer: BmtFilterSerializer
else
render json: filter.errors.full_messages, status: :unprocessable_entity
end
end
def destroy
filter = BmtFilter.find(params[:id])
render json: { status: filter.destroy }
end
private
def filters_params
params.require(:bmt_filter).permit(:name, :filters)
end
def check_manage_permission
render_403 && return unless can_manage_bmt_filters?(@current_team)
end
end

View file

@ -10,27 +10,39 @@ window.initBMTFilter = () => {
el: '#bmtFilterContainer',
data: () => {
return {
saved_filters: []
savedFilters: [],
filters: []
};
},
components: {
'filter-container': FilterContainer
},
methods: {
updateFilters(filters) {
this.filters = filters;
},
getFilters() {
return this.filters;
}
}
});
$('#bmtFilterContainer').on('click', (e) => e.stopPropagation());
$( "#saveBmtFilterForm" ).off().submit(function(e) {
let filterName = $(this).find('input#filter_name').val();
bmtFilterContainer.saved_filters.push({
id: bmtFilterContainer.saved_filters.length,
filter_name: filterName,
filters: []
$("#saveBmtFilterForm" )
.off()
.on('ajax:before', function() {
$('#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) {
bmtFilterContainer.savedFilters = result.data;
})
};
$('.repository-show').on('click', '.open-save-bmt-modal', () => {
$('#modalSaveBmtFilter').modal('show')
$('#modalSaveBmtFilter').modal('show');
})

View file

@ -8,10 +8,10 @@
</div>
<div class="dropdown-menu saved-filters-container">
<SavedFilterElement
v-for="(saved_filter, index) in saved_filters"
:key="saved_filter.id"
:saved_filter.sync="saved_filters[index]"
@saved_filter:delete="saved_filters.splice(index, 1)"
v-for="(savedFilter, index) in savedFilters"
:key="savedFilter.id"
:savedFilter.sync="savedFilters[index]"
@savedFilter:delete="savedFilters.splice(index, 1)"
/>
</div>
</div>
@ -50,15 +50,15 @@
export default {
name: 'FilterContainer',
props: {
container: Object,
savedFilters: Array
},
data() {
return {
filters: []
}
},
props: {
container: Object,
saved_filters: Array
},
components: { FilterElement, SavedFilterElement },
computed: {
searchJSON() {
@ -77,6 +77,7 @@
},
updateFilter(filter) {
this.filters.find((f) => f.id === filter.id).data = filter.data;
this.$emit('filters:update', this.searchJSON);
},
clearAllFilters() {
this.filters = [];

View file

@ -1,7 +1,7 @@
<template>
<div class="saved-filter-element">
{{ saved_filter.filter_name }}
<button class="btn btn-light icon-btn" @click="$emit('saved_filter:delete')">
{{ savedFilter.attributes.name }}
<button class="btn btn-light icon-btn" @click="deleteFilter">
<i class="fas fa-trash"></i>
</button>
</div>
@ -11,7 +11,20 @@
export default {
name: 'SavedFilterElement',
props: {
saved_filter: Object
savedFilter: Object
},
methods: {
deleteFilter() {
let filter = this
$.ajax({
url: this.savedFilter.attributes.delete_url,
type: 'DELETE',
dataType: 'json',
success: function() {
filter.$emit('savedFilter:delete')
}
});
}
}
}
</script>

13
app/models/bmt_filter.rb Normal file
View file

@ -0,0 +1,13 @@
# frozen_string_literal: true
class BmtFilter < ApplicationRecord
attr_accessor :delete_url
belongs_to :created_by,
foreign_key: :created_by_id,
class_name: 'User',
optional: true
validates :name, :filters, presence: true
end

View file

@ -36,6 +36,10 @@ Canaid::Permissions.register_for(Team) do
user.is_normal_user_or_admin_of_team?(team)
end
can :manage_bmt_filters do |user, team|
user.is_normal_user_or_admin_of_team?(team)
end
# repository: create, copy
can :create_repositories do |user, team|
within_limits = Repository.within_global_limits?

View file

@ -0,0 +1,11 @@
# frozen_string_literal: true
class BmtFilterSerializer < ActiveModel::Serializer
include Rails.application.routes.url_helpers
attributes :name, :filters, :delete_url
def delete_url
bmt_filter_path(object.id)
end
end

View file

@ -7,11 +7,12 @@
<%= t('repositories.show.bmt_search.save_filters') %>
</h4>
</div>
<%= form_with url: '', method: :post, :html => { :id => "saveBmtFilterForm" } do |f| %>
<%= form_with model: BmtFilter.new, method: :post, :html => { :id => "saveBmtFilterForm" } do |f| %>
<div class="modal-body">
<%= f.hidden_field :filters, class: "sci-input-field" %>
<div class="sci-input-container">
<%= f.label :filter_name %>
<%= f.text_field :filter_name, class: "sci-input-field" %>
<%= f.label :name %>
<%= f.text_field :name, class: "sci-input-field" %>
</div>
</div>

View file

@ -96,8 +96,11 @@
<span class="fas fa-microscope"></span>
<%= t('repositories.show.bmt_search.bmt_filter') %>
</button>
<div class="dropdown-menu bmt-filters-container" id="bmtFilterContainer">
<filter-container :saved_filters="saved_filters"></filter-container>
<div class="dropdown-menu bmt-filters-container" id="bmtFilterContainer" data-url-saved-filters="<%= bmt_filters_path %>">
<filter-container
@filters:update="updateFilters"
:saved-filters.sync="savedFilters"
:filters.sync="filters" />
</div>
</div>
<button

View file

@ -779,6 +779,8 @@ Rails.application.routes.draw do
end
end
resources :bmt_filters, only: %i(index create destroy)
match '/marvin4js-license.cxl', to: 'bio_eddie_assets#license', via: :get
match 'biomolecule_toolkit/*path', to: 'bio_eddie_assets#bmt_request',

View file

@ -0,0 +1,12 @@
# frozen_string_literal: true
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.references :created_by, index: true, foreign_key: { to_table: :users }
t.timestamps
end
end
end

View file

@ -313,6 +313,39 @@ CREATE SEQUENCE public.assets_id_seq
ALTER SEQUENCE public.assets_id_seq OWNED BY public.assets.id;
--
-- Name: bmt_filters; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.bmt_filters (
id bigint NOT NULL,
name character varying NOT NULL,
filters character varying NOT NULL,
created_by_id bigint,
created_at timestamp(6) without time zone NOT NULL,
updated_at timestamp(6) without time zone NOT NULL
);
--
-- Name: bmt_filters_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public.bmt_filters_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: bmt_filters_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE public.bmt_filters_id_seq OWNED BY public.bmt_filters.id;
--
-- Name: checklist_items; Type: TABLE; Schema: public; Owner: -
--
@ -3083,6 +3116,13 @@ ALTER TABLE ONLY public.asset_text_data ALTER COLUMN id SET DEFAULT nextval('pub
ALTER TABLE ONLY public.assets ALTER COLUMN id SET DEFAULT nextval('public.assets_id_seq'::regclass);
--
-- Name: bmt_filters id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.bmt_filters ALTER COLUMN id SET DEFAULT nextval('public.bmt_filters_id_seq'::regclass);
--
-- Name: checklist_items id; Type: DEFAULT; Schema: public; Owner: -
--
@ -3672,6 +3712,14 @@ ALTER TABLE ONLY public.assets
ADD CONSTRAINT assets_pkey PRIMARY KEY (id);
--
-- Name: bmt_filters bmt_filters_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.bmt_filters
ADD CONSTRAINT bmt_filters_pkey PRIMARY KEY (id);
--
-- Name: checklist_items checklist_items_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
@ -4427,6 +4475,13 @@ CREATE INDEX index_assets_on_last_modified_by_id ON public.assets USING btree (l
CREATE INDEX index_assets_on_team_id ON public.assets USING btree (team_id);
--
-- Name: index_bmt_filters_on_created_by_id; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX index_bmt_filters_on_created_by_id ON public.bmt_filters USING btree (created_by_id);
--
-- Name: index_checklist_items_on_checklist_id; Type: INDEX; Schema: public; Owner: -
--
@ -7147,6 +7202,14 @@ ALTER TABLE ONLY public.protocols
ADD CONSTRAINT fk_rails_dcb4ab6aa9 FOREIGN KEY (parent_id) REFERENCES public.protocols(id);
--
-- Name: bmt_filters fk_rails_de5b654b84; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.bmt_filters
ADD CONSTRAINT fk_rails_de5b654b84 FOREIGN KEY (created_by_id) REFERENCES public.users(id);
--
-- Name: my_modules fk_rails_e21638fa54; Type: FK CONSTRAINT; Schema: public; Owner: -
--
@ -7504,6 +7567,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20210715125349'),
('20210716124649'),
('20210720112050'),
('20210812095254');
('20210812095254'),
('20210825112050');