OSIS History
is a Django application to add objects history registration at a high level. It embeds a history listing API and goes along with a VueJS widget that permit the history visualization.
OSIS History
requiresDjango Framework
2.2.0
# From your osis install, with python environment activated
pip install git+https://github.com/uclouvain/osis-history.git@dev#egg=osis_history
# From your osis install, with python environment activated
git clone [email protected]:uclouvain/osis-history.git
pip install -e ./osis-history
Add osis_history
to INSTALLED_APPS
:
INSTALLED_APPS = (
...,
'osis_history',
...,
)
osis_history is a small utility package that allows third-party modules to store different actions/states of an object in order to track its history within a Django application.
This object's history is then exposed via a UX-friendly widget with multiple visualizations (table and timelines).
Before being able to create history entries, you will need to prepare your model classes.
To do so, just add the HistoryDeleteMixin
to the classes that will register histories from their objects instances ;
- Import and declare the mixin :
from django.db import models
from osis_history.models import HistoryDeleteMixin
class MyClass(HistoryDeleteMixin, models.Model):
...
To declare a history entry within a Django application:
# Import the function to add an entry :
from osis_history.utilities import add_history_entry
# Pass the object's uuid and both french and english messages to it :
add_history_entry(
my_object.uuid, # an uuid
"French message",
"English message",
"Author name",
tags=['tag1', 'tag2'], # facultative
extra_data={'debug': True}, # facultative
)
To visualize the complete history of a given object, you must implement a view that will be called to get results, you are free to put any permission on it:
# In your views
from osis_history.contrib.mixins import HistoryEntryListAPIMixin
from osis_role.contrib.views import PermissionRequiredMixin
class MyModuleHistoryView(PermissionRequiredMixin, HistoryEntryListAPIMixin):
pass
# In your urls
from django.urls import path
urlpatterns = [
path("<uuid:uuid>/", MyModuleHistoryView.as_view(), name="some-test"),
]
Then to render the widget for an object, include the CSS and JS file while adding a div.history-viewer
element to your DOM:
{% block style %}
<link href="{% static 'osis_history/osis-history.css' %}" rel="stylesheet"/>
{% endblock style %}
{% block content %}
<div class="history-viewer" data-url="{% url 'some-test' object.uuid %}"></div>
{% endblock %}
{% block script %}
<script type="text/javascript" src="https://unpkg.com/vue@2/dist/vue.min.js"></script>
<script type="text/javascript" src="https://unpkg.com/[email protected]/dist/vue-i18n.min.js"></script>
<script type="text/javascript" src="{% static 'osis_history/osis-history.umd.min.js' %}"></script>
{% endblock %}
- You can filter based on tags by providing the data attribute with comma-separated values:
data-tags="foo,bar"
- You can customize the rendering by passing the mode you want to display:
data-modes="table,horizontal" data-default-mode="horizontal"
- You can customize the rendering of each mode by passing a function name available in the global scope:
data-on-item-render-table
will receive an entry and must return a<tr>
element to be displayed as table rowdata-on-headers-render-table
will receive the array of entries and must return a<tr>
element to be displayed as table headerdata-on-item-render-horizontal-timeline
anddata-on-item-render-vertical-timeline
will receive an entry and must return a<li>
element to be displayed as list item
<div class="history-viewer" data-url="{% url 'admission:doctorate:history-api' uuid=view.kwargs.uuid %}" data-tags="{{ tag }}" data-on-item-render-vertical-timeline="customListRendering" ></div> <script> function customListRendering(entry) { return `<li>${entry.author} (${entry.created}): ${OsisHistory.filterXssAndFormat(entry.message)}${entry.extra_data.debug ? ' (debug)'}</li>` } </script>
data-on-history-empty-render
will receive the mode and must return a<tr>
element if mode is'table'
or any element otherwise to be displayed
NB: it is the responsibility of the rendering function to take care of XSS attacks, and adding the correct CSS classes. In order to do that, you may use theOsisHistory.filterXssAndFormat()
function
All the 'raw' history entries related to an object can be retrieved using the following :
from osis_history.utilities import get_history_entries
history_entries = get_history_entries(my_object.uuid)
A history entry will always return the following details :
- date and time of entry creation
- message in French
- message in English
- author
- tags
- extra_data
To contribute to the frontend part of this module, install npm
> 6 (included in https://nodejs.org/en/download/), and run:
cd osis_history
npm clean-install
npm run build
Commands available:
npm run build
builds the frontend component toosis_history/static/osis_history
npm run watch
builds the frontend component toosis_history/static/osis_history
and watch for file changes (warning: this not a hot-reload, you have to refresh your page)npm run storybook
serve user stories page for developmentnpm run lint
checks Javascript syntaxnpm run test
launch testsnpm run coverage
launch tests with coverage