Releases: openhealthcare/opal
0.13.1 (Minor Release)
0.13.1 (Minor Release)
Upgrades the setup.py Django version from 2.0.9 to 2.0.13. Removes the six library dependency from setup.py
0.13.0 (Major Release)
v0.13.0 A major release fundamental changes.
Removes support for Python 2.x
Due to the upgrade to Django 2.x, Opal no longer supports Python 2.x.
Opal is now tested against Python 3.5, 3.6
Episode.active
The field Episode.active
was previously implicitly set when calling .set_tag_names()
to
something equivalent to the value of bool(len(tag_names) > 0)
.
As of 0.13.0 the value of Episode.active
is checked whenever .save()
is called, prior
to the database call. The correct value is looked up via Episode.category.is_active()
.
The default calculation of .active
has also changed to be roughly equivalent to
bool(self.episode.end is None)
.
Applications are now able to easily change this behaviour by overriding the .is_active
method of the relevant EpisodeCategory
.
Coding systems for lookuplists
Lookuplist entries may now have an associated coding system and code value stored against them.
This enables applications to explicitly code entries against e.g. SNOMED value sets.
Note: This will requires a migration to be created for all applications.
New date display format helpers
Introduces two new Angular filters: displayDate
and displayDateTime
. These format a date
for display according to the setting DATE_DISPLAY_FORMAT
. This defaults to D MMM YYYY
.
New applications will have this setting in their scaffold, existing applications may wish to add
it.
All core Opal templates that previously used shortDate
or shortDateTime
have been updated to
use either displayDate
or displayDateTime
.
Removes scope.jumpToEpisode and scope.getEpisodeId from Search and Extract
We no longer use these functions, instead we use an HTML link to the patient detail view.
Removes Patient.to_dict().active_episode_id
We no longer include a value for "active_episode_id" as part of the Patient to_dict serialisation.
This is effectively meaningless since we moved to an episode model that allows for multiple
concurrent episodes.
Removes CopyToCategory
Removes the entire CopyToCategory flow from Opal Core. If applications continue to rely on it,
they are advised to implement at application level.
In general application developers are advised to find alternative ways to display subrecords
from multiple episodes rather than copying them however, as this is known to cause duplication
of data that is hard to trace back later on.
This includes the API endpoint at episode/$id/actions/copyto/$category/
, the template
copy_to_category.html
, the Angular controller CopyToCategoryCtrl
and service
CopyToCategory
and Subrecord property _clonable
.
Lookuplist data format
Lookuplist entries in data files are no longer required to have an empty synonyms list
if the entry doesn't have a synonym. This reduces the file size and makes it easier to
hand craft data files for new applications.
TaggedPatientList Episode serialisation
Alters the default serialisation of TaggedPatientList serialisation to no longer filter out
'inactive' episodes. Given that 'active' was always true when an episode had a tag, this
was effectivly a no-op anyway unless applications were altering the get_queryset
for
these patient lists somehow.
Removes the deprecated Model._title property
Use of Model._title
to set a display name of a subrecord has issued a warning for several
releases - this has now been removed and will no longer work.
Free text or foreign key fields are now, by default case insensitive
This can be adjusted with a flag on the field.
Existing fk_or_ft fields could therefore still have the field set as free text.
This change is not accompanied by a retrospective migration so your existing fk_or_ft may be
stored in a case sensitive manner. It is recommended you migrate all of your fk_or_ft fields
as this will give you consistent behaviour.
For example
Prior to this change if I had an allergy for "paracetomol" but an entry in the models.Drug
table of "Paracetomol", it would be stored as free text in the Allergies.drug
field, because
it was case sensitive. Going forward after this change it will be saved as a foreign key. This
change will not be made retrospecively however so you would need to add a migration that resaved
the Allergies.drug.
Misc Changes
-
The undocumented Reopen Episode flow included in Opal < 0.8.0 has now been completely removed,
including thereopen_episode_modal.html
template and the url/view attemplates/modals/reopen_episode.html/
. -
Removes the method
.deleteItem
from theRecordEditor
service. -
Adds in a footer updated/created by to the form base template
-
Changes the default value of
_ft
fields onForeignKeyOrFreeTextField
from b'' to ''. This requires a migration -
__unicode__
model methods have been renamed__str__
-
Adds an index argument to
PatientList.as_menuitem()
andPathway.as_menuitem()
-
Adds a
get_absolute_url()
method toPatient
and `Episode -
Adds
btn-cancel
,btn-save
andbtn-delete
classes to the respective form buttons. -
Moves the cancel button by default to be left of the save button.
-
Renames the (undocumented, internal) Angular service
FieldTranslater
toFieldTranslator
-
If an item is deleted from the edit item modal, RecordEditor.openEditItemModal will now resolve after
the delete item modal is closed with 'deleted'
Updates to the Dependency Graph
- Django: 1.10.8 -> 2.0.9
- Django Rest Framework: 3.4.7 -> 3.7.4
- Django Reversion: 1.10.2 -> 3.0.1
- Letter: 0.4.1 -> 0.5
- Requests: 2.18.4 -> 2.20.1
- Psycopg2: 2.7 -> 2.7.6.1
- Python Dateutil: 2.4.2 -> 2.7.5
0.12.1 (Minor Release)
A minor release with a few fixes and improvements.
-
If an item is deleted from the edit item modal, RecordEditor.openEditItemModal will now resolve after the delete item modal is closed with 'deleted'
-
Fixes the default investigation modal
0.12.0 (Major Release)
A major release with a few notable changes.
-
Adds the {% block analytics %} in the base template (opal/templates/base.html) that by default contains the google analytics code.
-
Adds the block {% block javascripts %} in the base template (opal/templates/base.html) that will compress all javascripts.
-
Adds a method
.demographics()
toopal.models.Patient
which returns the relevant demographics instance. -
Adds a
for_user
method on to the menu item. This method
takes a user and by default returns True. Override this
to decide if a menu item should be shown in the nav bar.
0.11.2 (Minor Release)
Minor bug fix that includes makes sure reference data are included when installed.
0.11.1 (Minor Release)
Minor bug fix in user_options
Fixes the user_options in the date picker tag to display the options as part of the text input.
0.11.0 (Major Release)
0.11.0 (Major Release)
Adds options of today
and yesterday
in the date picker
If you pass in user_options=True
to the date picker. You will be provided with options to select today or yesterday in the form tag.
Adds dateHelper
to the rootScope
The dateHelper has the functions now
and yesterday
that return javascript Dates for
the current time and the current time - 1 day.
Deprecates the _title property
In future we will use the standard verbose_name
property as the display name.
The abstract models have been changed to account for this.
Core API registration
A refactor in the way that the core APIs are registered by Opal means that
importing opal.core.api
in a plugin API no longer results in circular imports.
Fixes a bug whereby episodes were serialising differently depending on whether
the code path went via .to_dict()
or .objects.serialised()
.
HelpTextStep can now use a custom template
The opal.core.pathway.steps.HelpTextStep
can now have a help_text_template
passed in.
This is the template for what will be placed in the side bar.
Adds in a radio_vertical template tag
This displays the label and then the radio
buttons as a vertical list.
opal.core.serialization
A number of helpers related to serialization and deserialization have been brought
together in the new module opal.core.serialization
.
Removes "episode_history" from episode serialization
Serialised episodes previously contained a "shallow" copy of all other episodes in
a property named episode_history
. This was primarially useful before we switched
from episode-oriented to patient-oriented detail views by default.
This also includes a change to the signature of the .serialised()
method of the
Episode manager, which no longer accepts a episode_history
kwarg.
as_menuitem helpers
Applications using Opal Menuitems often wish to add menu items for Patient Lists and
Pathways.
To aid this, the .as_menuitem()
method now creates one from the target class with
sensible but overridable defaults.
opal serve
command
We add opal serve
to the Opal commandline tool. Currently this simply wraps the
Django runserver management command. It is envisaged that in the future this will
also initialize e.g. sass precompilers with a single command.
Misc Changes
Adds the utility function opal.utils.get
. Similar to the getattr
builtin, get
looks
for a method named get_$attr
and will call that if it exists.
Adds the method .get_absolute_url()
to opal.core.pathways.Pathway
and
opal.core.patient_lists.PatientList
.
Template removals
We removed a number of superfluous templates:
- opal/templates/patient_lists/spreadsheet_list.html
- opal/templates/layouts/left-panel.html
Static asset minification
The Django upgrade in Opal 0.10 stopped compressor minifying files
when DEBUG is set to False. This fixes that issue by upgrading Django compressor to
a version that supports Django 1.10.
The return of an old friend: IE Document modes
Users report that their system administrators sometimes configure Internet Explorer
in such a way that it uses e.g. IE7 Document mode by default.
This is problematical for Opal applications which do in fact make use of internet
technologies that were in widespread use after say, 2006.
We have altered base.html
to specify "X-UA-Compatible" content="IE=Edge"
. If you
override base.html
in your application we advise that you add this <meta>
tag.
Misc Changes
-
Adds the utility function
opal.core.subrecords.singletons()
which returns
a generator function which will yield all subrecord singletons. -
Fixes a URI encoding bug in the
Episode.findByHospitalNumber()
method that
made hospital numbers including#
or/
raise an error. -
Adds the methods
.get_absolute_url()
,.get_icon()
andget_display_name()
toopal.core.pathways.Pathway
andopal.core.patient_lists.PatientList
.
Updates to the Dependency Graph
- Django compressor: 1.5 -> 2.2
0.10.1 (Minor Release)
Plugin API end points can now override application end points
A change to the order that APIs are registered with Django Rest Framework allows
plugins to now override the core Opal application APIs.
Fonts are now locally sourced
Fonts are now served from Opal's static assets rather than from the Google CDN.
print/screen stylesheets have been collapsed into opal.css
Print/screen differences are now in opal.css with media tags.
Google Analytics is now deferred
The loading in of Google Analytics is now deferred to the bottom of the body
tag to allow the page to load without waiting on analytics scripts to load.
Scaffold version control failures
The startplugin
and startproject
commands initialize a git repository by
default. If we (The subprocess
module) cannot find the git
command, we now
continue with a message printed to screen rather than raising an exception.
Episode.objects.serialised now uses select_related
ForeignKeyOrFreeText
fields now have their ForeignKey items preselected when
we use Episode.objects.serialised
. This provides a speed boost for applications
with moderately heavy ForeignKeyOrFreeText
usage.
(Approx 30-40% in our tests.)
0.10.0 (Major Release)
Referencedata in new applications
Opal now includes core lookuplist data in an opal.core.referencedata
plugin
which is installed and loaded by default by the startproject
scaffolding.
Deletion cascade behaviour
Opal 0.10 changes several behaviours related to cascading deletions which, despite
being Django defaults, were confusing to users and developers in our use case.
When we delete and look up list instance, we no longer delete all subrecords that use
that instance. Instead we set the look up list instances name in the free text field on
the subrecord.
When you delete a user, it will no longer delete all related episodes and subrecords
Episode Category stages
Episode categories now enforce a set of valid Episode.stage
values.
EpisodeCategory
now includes the .get_stages()
and .has_stage(stage)
methods,
while Episode
has a set_stage
setter which is used by the UpdateFromDictMixin JSON API.
lookuplists.lookuplists
Adds the utility generator lookuplists.lookuplists()
which wil yield every lookuplist
currently available.
Discoverable.filter()
Disoverable features now have a filter
method which allows you to filter features
with matching attributes.
Pathways ContextProcessor
The 'opal.core.pathways.context_processors.pathways' Context Processor will allow you to
access your pathways from templates without having to explicitly load them in a view. In
turn, this allows patterns like:
{% include pathways.YourPathway.get_display_name %}
Missing consistency token errors
.update_from_dict()
will now raise the new error
opal.core.errors.MissingConsistencyTokenError
if it is called without a consistency
token when one is set on the model. Previously it would raise APIError
.
The JSON API will now return a more specific message in the response boday, explaining
that the problem is a missing consistency token.
dump_lookup_lists --many-files
Adds the --many-files
option to the dump_lookup_lists
command which will write
each installed lookup list to a separate file in the ./data/lookuplists
directory
of the application.
Template removals
We remove a number of stale unused templates:
- changelog.html
- contact.html
- extract_footer.html
- tagging_detail.html
- _helpers/inline_form.html
- responsive/_phone_episode_list.html'
- responsive/_tablet_episode_list.html
Removing LoginRequiredMixin
As Django ships with a LoginRequiredMixin
of its own we no longer roll our own
in `opal.core.views.
Testing options
Adds a --failfast
option to the test harness to stop test runs on the first
failure.
If you are a plugin developer upgrading an existing plugin you will have to
manually add support for --failfast
passthrough to your runtests.py
.
If you are a plugin developer upgrading an existing plugin you will have to
manually add support for --failfast
passthrough to your runtests.py
.
Moves scaffold to be a django management command
The rest of the api is still the same but now
we run python manage.py scaffold {my_app_name}
Deprecations completed
As previously noted in console warnings, the Angular Episode service no longer
supports the discharge_date
, date_of_admission
, date_of_episode
properties.
These were replaced by .start
and .end
.
Updates to the Dependency Graph
- Django: 1.8.13 -> 1.10.8
- Django Reversion: 1.8.7 -> 1.10.2
- Django Rest Framework: 3.2.2 -> 3.4.7
- Psycopg2: 2.5 -> 2.7
- Jinja2: 2.9.6 -> 2.10
- Ffs: 0.0.8.1 -> 0.0.8.2
- Requests: 2.7.0 -> 2.18.4
- django-celery: 3.1.17 -> 3.2.2
- celery: 3.1.19 -> 3.1.25
Misc Changes
Removes the undocumented collapsed_multisave
tag from the pathways
templatetag
library.
Adds a setting OPAL_FAVICON_PATH
to specify the application Favicon to use.
Adds the rows
option to the textarea template tag which just fills in the html textarea
rows
attribute. Text areas are defaulted to 5 rows (the same as before).
Configures the setting CSRF_FAILURE_VIEW
to use the bundled opal.views.csrf_failure
view.
Adds the utility function opal.utils.get
. Similar to the getattr
builtin, get
looks
for a method named get_$attr
and will call that if it exists.
Adds the method .get_absolute_url()
to opal.core.pathways.Pathway
and
opal.core.patient_lists.PatientList
.
Adds the Opal error SignatureError
.
Pathway slugs may now include hyphens as well as numbers, lower case letters and underscores.
Bugfix: in edit_item.js $scope.episode_category is now set from episode.category_name
as opposed to episode.category (which was always null)
Fixes some instances of progressbars not being reset if unexpected error states
occur.
Improves the rendering of patient detail pages where no patient with the ID from
route params exits. (Displays a polite message instead of erroring.)
Incorrect pluralisation of subrecord names in the Admin view has been fixed. (Migrations
will have to be run in all models which extend the changed core Opal models (this is due
to a minor upstream Django bug)
Minor change to the diagnosis form.
0.9.0 (Major Release)
Good bye date_of_episode, discharge_date, date_of_admission
And hello episode.start
and episode.end
. These fields on the Episode
model
replace the multiple ways of recording Episode duration in Opal.
There is a migration that sets start
to date_of_episode if it exists, otherwise
it uses date of admission.
end
will be date_of_episode if it exists, otherwise it will use discharge_date.
Note that this means we no longer refer to start and end properties on the
Episode category. If you override start
and end
in a custom episode category
you should update to use the Episode model fields. This logic should be moved into
your flows and you'll need to put in a migration to populate existing
episodes.
We also remove the episode fields date_of_episode
discharge_date
, and
date_of_admission
.
Warning: Backwards migrations will not migrate back to date_of_episode
but to
a admission and discharge. Take backups before running these migrations!
The fields start
and end
are both cast to moments (rather than raw js Dates) on
episode.initialisation
Pathway
Moves the opal-pathway module into the opal core. Pathways is an extensible way
of creating forms that involve multiple subrecords.
We've got time on our side
Adds in the {% timepicker %} template tag, that follows the same convention as
the other template tags, ie {% timepicker field="Dinner.time" %}
Removes a js global declaration of categories
Previously we declared CATEGORIES globally. This has now been removed
Order Order
Episodes in the patient list are now ordered by start, first_name and surname
Theming support
Improvements and better documentation and guides for theming applications. Particularly
of note are changes to opal.html
and base.html
, as well as the addition of the
static_page.html
template.
This version also includes extensive improved support for customising the templates that
display patient lists, detail views, menus and forms amongst other things.
For full documentation, consult the theming guide in the documentation.
Makes search fully pluggable
Search is now completely pluggable, you need to have some angular controller
called SearchCtrl, but apart from that you can plugin your own implementation.
Exclude prefixes now work on actual paths
Previously they only worked with angular paths, now they work
with a combination of actual paths and angular url paths (e.g. /search/#/extract)
Misc Changes
Add the allow_add_patient and allow_edit_teams options to the patient lists.
We added support for a --file
or -f
option for the load_lookup_lists
command which
allows the user to specify a particular file outside of the default locations.
The default Location
record display template will no longer include references
to Episode.start
. and Episode.stop
labelled as admisssion and discharge to support
the majority case where an episode relates to something other than an inpatient episode!
Applications wishing to retaint this functionality should update their own temaplates
to display start/stop details.
Removes Deprecated functionality in ReferenceData, Metadata, UserProfile and recordLoader
Previously these would make their http request when imported into a file. They now require you to call .load()
for them to return the promise that loads in their respective data.