From 29eb4d057ab010beb9167044eedb08cc2783e22a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alejandro=20Avil=C3=A9s?= Date: Thu, 25 Jun 2020 16:47:51 +0200 Subject: [PATCH] Allow filtering event log by related entries --- CHANGES.rst | 2 ++ .../modules/events/logs/client/js/actions.js | 9 ++++-- .../logs/client/js/components/EventLog.jsx | 32 +++++++++++++++++++ .../modules/events/logs/client/js/index.jsx | 3 +- .../modules/events/logs/client/js/reducers.js | 3 ++ indico/modules/events/logs/controllers.py | 6 ++-- indico/modules/events/logs/renderers.py | 4 ++- .../events/logs/templates/entry_simple.html | 10 ++++++ .../modules/events/logs/templates/logs.html | 3 +- 9 files changed, 65 insertions(+), 7 deletions(-) diff --git a/CHANGES.rst b/CHANGES.rst index 9ad4c6749cb..5c64a99cf53 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -78,6 +78,8 @@ Improvements - Preserve non-ascii characters in file names (:issue:`4465`) - Allow resetting moderation state from registration management view (:issue:`4498`, thanks :user:`omegak`) +- Allow filtering event log by related entries (:issue:`4503`, thanks + :user:`omegak`) Bugfixes ^^^^^^^^ diff --git a/indico/modules/events/logs/client/js/actions.js b/indico/modules/events/logs/client/js/actions.js index d1e14d84cd7..8825645d325 100644 --- a/indico/modules/events/logs/client/js/actions.js +++ b/indico/modules/events/logs/client/js/actions.js @@ -16,6 +16,7 @@ export const FETCH_FAILED = 'FETCH_FAILED'; export const SET_DETAILED_VIEW = 'SET_DETAILED_VIEW'; export const VIEW_PREV_ENTRY = 'VIEW_PREV_ENTRY'; export const VIEW_NEXT_ENTRY = 'VIEW_NEXT_ENTRY'; +export const SET_METADATA_QUERY = 'SET_METADATA_QUERY'; export function setKeyword(keyword) { return {type: SET_KEYWORD, keyword}; @@ -33,6 +34,10 @@ export function setDetailedView(entryIndex) { return {type: SET_DETAILED_VIEW, currentViewIndex: entryIndex}; } +export function setMetadataQuery(metadataQuery) { + return {type: SET_METADATA_QUERY, metadataQuery}; +} + export function viewPrevEntry() { return async (dispatch, getStore) => { const { @@ -90,15 +95,15 @@ export function fetchFailed() { export function fetchLogEntries() { return async (dispatch, getStore) => { dispatch(fetchStarted()); - const { - logs: {filters, keyword, currentPage}, + logs: {filters, keyword, currentPage, metadataQuery}, staticData: {fetchLogsUrl}, } = getStore(); const params = { page: currentPage, filters: [], + data: JSON.stringify(metadataQuery), }; if (keyword) { params.q = keyword; diff --git a/indico/modules/events/logs/client/js/components/EventLog.jsx b/indico/modules/events/logs/client/js/components/EventLog.jsx index 2f19f9e29da..9cb6d39afd0 100644 --- a/indico/modules/events/logs/client/js/components/EventLog.jsx +++ b/indico/modules/events/logs/client/js/components/EventLog.jsx @@ -6,13 +6,45 @@ // LICENSE file for more details. import React from 'react'; +import {useDispatch, useSelector} from 'react-redux'; + +import {Param, Translate} from 'indico/react/i18n'; import LogEntryList from '../containers/LogEntryList'; import Toolbar from './Toolbar'; +import {fetchLogEntries, setMetadataQuery, setPage} from '../actions'; + +function MetadataQueryMessage() { + const dispatch = useDispatch(); + const resetURLFiltering = () => { + dispatch(setMetadataQuery({})); + dispatch(setPage(1)); + dispatch(fetchLogEntries()); + }; + + return ( +
+ +
+ + Log entries are currently filtered by URL.{' '} + }> + Click here + {' '} + to disable the filter. + +
+
+ ); +} + +MetadataQueryMessage.propTypes = {}; export default function EventLog() { + const metadataQuery = useSelector(state => state.logs.metadataQuery); return ( <> + {Object.keys(metadataQuery).length !== 0 && } diff --git a/indico/modules/events/logs/client/js/index.jsx b/indico/modules/events/logs/client/js/index.jsx index 03fbed052ee..af806049fda 100644 --- a/indico/modules/events/logs/client/js/index.jsx +++ b/indico/modules/events/logs/client/js/index.jsx @@ -12,7 +12,7 @@ import {Provider} from 'react-redux'; import createReduxStore from 'indico/utils/redux'; import EventLog from './components/EventLog'; -import {fetchLogEntries} from './actions'; +import {fetchLogEntries, setMetadataQuery} from './actions'; import reducer from './reducers'; import '../style/logs.scss'; @@ -33,6 +33,7 @@ window.addEventListener('load', () => { }, initialData ); + store.dispatch(setMetadataQuery(JSON.parse(rootElement.dataset.metadataQuery))); ReactDOM.render( diff --git a/indico/modules/events/logs/client/js/reducers.js b/indico/modules/events/logs/client/js/reducers.js index 6fd2300c75f..b77d2db9918 100644 --- a/indico/modules/events/logs/client/js/reducers.js +++ b/indico/modules/events/logs/client/js/reducers.js @@ -12,6 +12,7 @@ const initialState = { keyword: null, currentPage: 1, isFetching: false, + metadataQuery: {}, filters: { event: true, management: true, @@ -46,6 +47,8 @@ export default function logReducer(state = initialState, action) { return {...state, isFetching: false}; case actions.SET_DETAILED_VIEW: return {...state, currentViewIndex: action.currentViewIndex}; + case actions.SET_METADATA_QUERY: + return {...state, metadataQuery: action.metadataQuery}; default: return state; } diff --git a/indico/modules/events/logs/controllers.py b/indico/modules/events/logs/controllers.py index 3f7e1cceb0a..b00a791663f 100644 --- a/indico/modules/events/logs/controllers.py +++ b/indico/modules/events/logs/controllers.py @@ -31,15 +31,17 @@ class RHEventLogs(RHManageEventBase): """Shows the modification/action log for the event""" def _process(self): + metadata_query = {k.lstrip('meta.'): int(v) if v.isdigit() else v + for k, v in request.args.iteritems() if k.startswith('meta.')} realms = {realm.name: realm.title for realm in EventLogRealm} - return WPEventLogs.render_template('logs.html', self.event, realms=realms) + return WPEventLogs.render_template('logs.html', self.event, realms=realms, metadata_query=metadata_query) class RHEventLogsJSON(RHManageEventBase): def _process(self): page = int(request.args.get('page', 1)) filters = request.args.getlist('filters') - data = json.loads(request.args.get('data')) + data = json.loads(request.args.get('data', '{}')) text = request.args.get('q') if not filters and not data: diff --git a/indico/modules/events/logs/renderers.py b/indico/modules/events/logs/renderers.py index 5cb7972569c..dc1137415bf 100644 --- a/indico/modules/events/logs/renderers.py +++ b/indico/modules/events/logs/renderers.py @@ -31,7 +31,9 @@ def render_entry(cls, entry): :param entry: A :class:`.EventLogEntry` """ template = '{}:{}'.format(cls.plugin.name, cls.template_name) if cls.plugin is not None else cls.template_name - return render_template(template, entry=entry, data=cls.get_data(entry), **cls.template_kwargs) + metadata_query = {'meta.{}'.format(k): v for k, v in entry.meta.iteritems()} + return render_template(template, entry=entry, data=cls.get_data(entry), metadata_query=metadata_query, + **cls.template_kwargs) @classmethod def get_data(cls, entry): diff --git a/indico/modules/events/logs/templates/entry_simple.html b/indico/modules/events/logs/templates/entry_simple.html index 0add14cf00e..2a556171fb4 100644 --- a/indico/modules/events/logs/templates/entry_simple.html +++ b/indico/modules/events/logs/templates/entry_simple.html @@ -34,4 +34,14 @@ {% endfor %} + {% if metadata_query %} + + + + + {% trans %}Display related log entries only.{% endtrans %} + + + + {% endif %} {% endblock %} diff --git a/indico/modules/events/logs/templates/logs.html b/indico/modules/events/logs/templates/logs.html index 4304f57b721..55c19f9a7fe 100644 --- a/indico/modules/events/logs/templates/logs.html +++ b/indico/modules/events/logs/templates/logs.html @@ -7,6 +7,7 @@ {% block content %}
+ data-realms="{{ realms|tojson|forceescape }}" + data-metadata-query="{{ metadata_query|tojson|forceescape }}">
{% endblock %}