Add activity filters [SCI-5765]

This commit is contained in:
aignatov-bio 2021-05-31 13:32:31 +02:00
parent 27cefe7cbd
commit 3c7592657c
12 changed files with 163 additions and 2 deletions

View file

@ -1,4 +1,4 @@
/* global animateSpinner globalActivities */
/* global animateSpinner globalActivities HelperModule */
'use strict';
@ -59,6 +59,37 @@
});
}
function validateActivityFilterName() {
let filterName = $('#saveFilterModal .activity-filter-name-input').val();
$('#saveFilterModal .btn-confirm').prop('disabled', filterName.length === 0);
}
$('#saveFilterModal')
.on('keyup', '.activity-filter-name-input', function() {
validateActivityFilterName();
})
.on('click', '.btn-confirm', function() {
$.ajax({
url: this.dataset.saveFilterUrl,
type: 'POST',
global: false,
dataType: 'json',
data: {
name: $('#saveFilterModal .activity-filter-name-input').val(),
filter: globalActivities.getFilters()
},
success: function(data) {
HelperModule.flashAlertMsg(data.message, 'success');
$('#saveFilterModal .activity-filter-name-input').val('');
validateActivityFilterName();
$('#saveFilterModal').modal('hide');
},
error: function(response) {
HelperModule.flashAlertMsg(response.responseJSON.errors.join(','), 'danger');
}
});
});
initExpandCollapseAllButtons();
initShowMoreButton();
}());

View file

@ -3,6 +3,8 @@
class GlobalActivitiesController < ApplicationController
include InputSanitizeHelper
before_action :check_create_activity_filter_permissions, only: :save_activity_filter
def index
# Preload filter format
# {
@ -106,8 +108,21 @@ class GlobalActivitiesController < ApplicationController
render json: get_objects(Report)
end
def save_activity_filter
activity_filter = ActivityFilter.new(activity_filter_params)
if activity_filter.save
render json: { message: t('global_activities.index.activity_filter_saved') }
else
render json: { errors: activity_filter.errors.full_messages }, status: :unprocessable_entity
end
end
private
def check_create_activity_filter_permissions
render_403 && return unless can_create_acitivity_filters?
end
def get_objects(subject)
query = subject_search_params[:query]
teams =
@ -138,6 +153,10 @@ class GlobalActivitiesController < ApplicationController
matched.map { |pr| { value: pr[0], label: escape_input(pr[1]) } }
end
def activity_filter_params
params.permit(:name, filter: {})
end
def activity_filters
params.permit(
:page, :starting_timestamp, :from_date, :to_date, types: [], subjects: {}, users: [], teams: []

View file

@ -0,0 +1,6 @@
# frozen_string_literal: true
class ActivityFilter < ApplicationRecord
validates :name, presence: true
validates :filter, presence: true
end

View file

@ -8,5 +8,9 @@ module Organization
can :create_teams do |_|
true
end
can :create_acitivity_filters do
ENV['WEBHOOKS_ENABLED'] == 'true'
end
end
end

View file

@ -0,0 +1,25 @@
<div class="modal" id="saveFilterModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="<%= t('general.close') %>"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title" id="regenerate-report-modal-label">
<%= t('global_activities.index.save_filter_modal.title') %>
</h4>
</div>
<div class="modal-body">
<p>
<%= t('global_activities.index.save_filter_modal.description') %>
</p>
<div class="sci-input-container">
<label><%= t('global_activities.index.save_filter_modal.filter_name_label') %></label>
<input type="text" class="sci-input-field activity-filter-name-input" placeholder="<%= t('global_activities.index.save_filter_modal.filter_name_placeholder') %>"></input>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-dismiss="modal"><%= t('general.cancel') %></button>
<button type="button" class="btn btn-primary btn-confirm" data-save-filter-url="<%= save_activity_filter_global_activities_path %>" disabled><%= t('general.save') %></button>
</div>
</div>
</div>
</div>

View file

@ -17,6 +17,11 @@
</div>
<div class="ga-tags-container">
<div class="ga-tags perfect-scrollbar"></div>
<% if can_create_acitivity_filters? %>
<div class="btn btn-light save-filter" data-toggle="modal" data-target="#saveFilterModal">
<i class="fas fa-save"></i><%= t('global_activities.index.save_filter') %>
</div>
<% end %>
<div class="btn btn-light clear-container">
<i class="fas fa-times-circle"></i><%= t('global_activities.index.clear_filters') %>
</div>

View file

@ -32,6 +32,8 @@
</div>
</div>
<%= render partial: 'save_filter_modal' %>
<script>
var gaUrlQueryParams= <%= raw @filters.to_json %>
</script>

View file

@ -1682,6 +1682,7 @@ en:
activities_counter_label: " activities"
expand_all: "Expand all"
collapse_all: "Collapse all"
modal:
modal_title: "Activities"
result_type:

View file

@ -36,6 +36,13 @@ en:
select_reports: Select Reports
no_name: "(unnamed)"
content_generation_error: "Failed to render activity content with id: %{activity_id}"
activity_filter_saved: "Filter successfully saved to the Webhooks page!"
save_filter: "Save filter"
save_filter_modal:
title: "Save filter"
description: "Saved filter will be located in the Webhooks section of the Settings. It can be used to trigger webhooks."
filter_name_label: "Filter name"
filter_name_placeholder: "Name your filter"
content:
create_project_html: "%{user} created project %{project}."
rename_project_html: "%{user} renamed project %{project}."

View file

@ -761,6 +761,7 @@ Rails.application.routes.draw do
get :protocol_filter
get :team_filter
get :user_filter
post :save_activity_filter
end
end

View file

@ -0,0 +1,10 @@
class CreateActivityFilters < ActiveRecord::Migration[4.2]
def change
create_table :activity_filters do |t|
t.string :name, null: false
t.jsonb :filter, null: false
t.timestamps null: false
end
end
end

View file

@ -193,6 +193,39 @@ CREATE SEQUENCE public.activities_id_seq
ALTER SEQUENCE public.activities_id_seq OWNED BY public.activities.id;
--
-- Name: activity_filters; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.activity_filters (
id integer NOT NULL,
name character varying NOT NULL,
filter jsonb NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
);
--
-- Name: activity_filters_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public.activity_filters_id_seq
AS integer
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: activity_filters_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE public.activity_filters_id_seq OWNED BY public.activity_filters.id;
--
-- Name: ar_internal_metadata; Type: TABLE; Schema: public; Owner: -
--
@ -2918,6 +2951,13 @@ ALTER TABLE ONLY public.active_storage_variant_records ALTER COLUMN id SET DEFAU
ALTER TABLE ONLY public.activities ALTER COLUMN id SET DEFAULT nextval('public.activities_id_seq'::regclass);
--
-- Name: activity_filters id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.activity_filters ALTER COLUMN id SET DEFAULT nextval('public.activity_filters_id_seq'::regclass);
--
-- Name: asset_text_data id; Type: DEFAULT; Schema: public; Owner: -
--
@ -3468,6 +3508,14 @@ ALTER TABLE ONLY public.activities
ADD CONSTRAINT activities_pkey PRIMARY KEY (id);
--
-- Name: activity_filters activity_filters_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.activity_filters
ADD CONSTRAINT activity_filters_pkey PRIMARY KEY (id);
--
-- Name: ar_internal_metadata ar_internal_metadata_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
@ -7234,6 +7282,8 @@ INSERT INTO "schema_migrations" (version) VALUES
('20210312185911'),
('20210325152257'),
('20210407143303'),
('20210506125657');
('20210410100006'),
('20210506125657'),
('20210531114633');