mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-09-07 05:34:55 +08:00
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:
parent
ef0e45be04
commit
b269f3f612
12 changed files with 197 additions and 27 deletions
34
app/controllers/bmt_filters_controller.rb
Normal file
34
app/controllers/bmt_filters_controller.rb
Normal 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
|
|
@ -10,27 +10,39 @@ window.initBMTFilter = () => {
|
||||||
el: '#bmtFilterContainer',
|
el: '#bmtFilterContainer',
|
||||||
data: () => {
|
data: () => {
|
||||||
return {
|
return {
|
||||||
saved_filters: []
|
savedFilters: [],
|
||||||
|
filters: []
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
'filter-container': FilterContainer
|
'filter-container': FilterContainer
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
updateFilters(filters) {
|
||||||
|
this.filters = filters;
|
||||||
|
},
|
||||||
|
getFilters() {
|
||||||
|
return this.filters;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$('#bmtFilterContainer').on('click', (e) => e.stopPropagation());
|
$('#bmtFilterContainer').on('click', (e) => e.stopPropagation());
|
||||||
|
|
||||||
$( "#saveBmtFilterForm" ).off().submit(function(e) {
|
$("#saveBmtFilterForm" )
|
||||||
let filterName = $(this).find('input#filter_name').val();
|
.off()
|
||||||
bmtFilterContainer.saved_filters.push({
|
.on('ajax:before', function() {
|
||||||
id: bmtFilterContainer.saved_filters.length,
|
$('#bmt_filter_filters').val(JSON.stringify(bmtFilterContainer.getFilters()));
|
||||||
filter_name: filterName,
|
})
|
||||||
filters: []
|
.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', () => {
|
$('.repository-show').on('click', '.open-save-bmt-modal', () => {
|
||||||
$('#modalSaveBmtFilter').modal('show')
|
$('#modalSaveBmtFilter').modal('show');
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -8,10 +8,10 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="dropdown-menu saved-filters-container">
|
<div class="dropdown-menu saved-filters-container">
|
||||||
<SavedFilterElement
|
<SavedFilterElement
|
||||||
v-for="(saved_filter, index) in saved_filters"
|
v-for="(savedFilter, index) in savedFilters"
|
||||||
:key="saved_filter.id"
|
:key="savedFilter.id"
|
||||||
:saved_filter.sync="saved_filters[index]"
|
:savedFilter.sync="savedFilters[index]"
|
||||||
@saved_filter:delete="saved_filters.splice(index, 1)"
|
@savedFilter:delete="savedFilters.splice(index, 1)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -50,15 +50,15 @@
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FilterContainer',
|
name: 'FilterContainer',
|
||||||
|
props: {
|
||||||
|
container: Object,
|
||||||
|
savedFilters: Array
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
filters: []
|
filters: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
props: {
|
|
||||||
container: Object,
|
|
||||||
saved_filters: Array
|
|
||||||
},
|
|
||||||
components: { FilterElement, SavedFilterElement },
|
components: { FilterElement, SavedFilterElement },
|
||||||
computed: {
|
computed: {
|
||||||
searchJSON() {
|
searchJSON() {
|
||||||
|
@ -77,6 +77,7 @@
|
||||||
},
|
},
|
||||||
updateFilter(filter) {
|
updateFilter(filter) {
|
||||||
this.filters.find((f) => f.id === filter.id).data = filter.data;
|
this.filters.find((f) => f.id === filter.id).data = filter.data;
|
||||||
|
this.$emit('filters:update', this.searchJSON);
|
||||||
},
|
},
|
||||||
clearAllFilters() {
|
clearAllFilters() {
|
||||||
this.filters = [];
|
this.filters = [];
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="saved-filter-element">
|
<div class="saved-filter-element">
|
||||||
{{ saved_filter.filter_name }}
|
{{ savedFilter.attributes.name }}
|
||||||
<button class="btn btn-light icon-btn" @click="$emit('saved_filter:delete')">
|
<button class="btn btn-light icon-btn" @click="deleteFilter">
|
||||||
<i class="fas fa-trash"></i>
|
<i class="fas fa-trash"></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -11,7 +11,20 @@
|
||||||
export default {
|
export default {
|
||||||
name: 'SavedFilterElement',
|
name: 'SavedFilterElement',
|
||||||
props: {
|
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>
|
</script>
|
||||||
|
|
13
app/models/bmt_filter.rb
Normal file
13
app/models/bmt_filter.rb
Normal 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
|
|
@ -36,6 +36,10 @@ Canaid::Permissions.register_for(Team) do
|
||||||
user.is_normal_user_or_admin_of_team?(team)
|
user.is_normal_user_or_admin_of_team?(team)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
can :manage_bmt_filters do |user, team|
|
||||||
|
user.is_normal_user_or_admin_of_team?(team)
|
||||||
|
end
|
||||||
|
|
||||||
# repository: create, copy
|
# repository: create, copy
|
||||||
can :create_repositories do |user, team|
|
can :create_repositories do |user, team|
|
||||||
within_limits = Repository.within_global_limits?
|
within_limits = Repository.within_global_limits?
|
||||||
|
|
11
app/serializers/bmt_filter_serializer.rb
Normal file
11
app/serializers/bmt_filter_serializer.rb
Normal 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
|
|
@ -7,11 +7,12 @@
|
||||||
<%= t('repositories.show.bmt_search.save_filters') %>
|
<%= t('repositories.show.bmt_search.save_filters') %>
|
||||||
</h4>
|
</h4>
|
||||||
</div>
|
</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">
|
<div class="modal-body">
|
||||||
|
<%= f.hidden_field :filters, class: "sci-input-field" %>
|
||||||
<div class="sci-input-container">
|
<div class="sci-input-container">
|
||||||
<%= f.label :filter_name %>
|
<%= f.label :name %>
|
||||||
<%= f.text_field :filter_name, class: "sci-input-field" %>
|
<%= f.text_field :name, class: "sci-input-field" %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -96,8 +96,11 @@
|
||||||
<span class="fas fa-microscope"></span>
|
<span class="fas fa-microscope"></span>
|
||||||
<%= t('repositories.show.bmt_search.bmt_filter') %>
|
<%= t('repositories.show.bmt_search.bmt_filter') %>
|
||||||
</button>
|
</button>
|
||||||
<div class="dropdown-menu bmt-filters-container" id="bmtFilterContainer">
|
<div class="dropdown-menu bmt-filters-container" id="bmtFilterContainer" data-url-saved-filters="<%= bmt_filters_path %>">
|
||||||
<filter-container :saved_filters="saved_filters"></filter-container>
|
<filter-container
|
||||||
|
@filters:update="updateFilters"
|
||||||
|
:saved-filters.sync="savedFilters"
|
||||||
|
:filters.sync="filters" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
|
|
|
@ -779,6 +779,8 @@ Rails.application.routes.draw do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
resources :bmt_filters, only: %i(index create destroy)
|
||||||
|
|
||||||
match '/marvin4js-license.cxl', to: 'bio_eddie_assets#license', via: :get
|
match '/marvin4js-license.cxl', to: 'bio_eddie_assets#license', via: :get
|
||||||
|
|
||||||
match 'biomolecule_toolkit/*path', to: 'bio_eddie_assets#bmt_request',
|
match 'biomolecule_toolkit/*path', to: 'bio_eddie_assets#bmt_request',
|
||||||
|
|
12
db/migrate/20210825112050_create_bmt_filters.rb
Normal file
12
db/migrate/20210825112050_create_bmt_filters.rb
Normal 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
|
|
@ -313,6 +313,39 @@ CREATE SEQUENCE public.assets_id_seq
|
||||||
ALTER SEQUENCE public.assets_id_seq OWNED BY public.assets.id;
|
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: -
|
-- 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);
|
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: -
|
-- 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);
|
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: -
|
-- 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);
|
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: -
|
-- 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);
|
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: -
|
-- Name: my_modules fk_rails_e21638fa54; Type: FK CONSTRAINT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
|
@ -7504,6 +7567,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||||
('20210715125349'),
|
('20210715125349'),
|
||||||
('20210716124649'),
|
('20210716124649'),
|
||||||
('20210720112050'),
|
('20210720112050'),
|
||||||
('20210812095254');
|
('20210812095254'),
|
||||||
|
('20210825112050');
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue