Skip to content

Releases: openhealthcare/opal

0.13.1 (Minor Release)

22 Feb 16:26
Compare
Choose a tag to compare

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)

13 Feb 17:59
Compare
Choose a tag to compare

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 the reopen_episode_modal.html template and the url/view at templates/modals/reopen_episode.html/.

  • Removes the method .deleteItem from the RecordEditor service.

  • Adds in a footer updated/created by to the form base template

  • Changes the default value of _ft fields on ForeignKeyOrFreeTextField from b'' to ''. This requires a migration

  • __unicode__ model methods have been renamed __str__

  • Adds an index argument to PatientList.as_menuitem() and Pathway.as_menuitem()

  • Adds a get_absolute_url() method to Patient and `Episode

  • Adds btn-cancel, btn-save and btn-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 to FieldTranslator

  • 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)

05 Feb 20:41
Compare
Choose a tag to compare

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)

15 Oct 18:05
8dfb4fb
Compare
Choose a tag to compare

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() to opal.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)

03 Jul 10:09
af10e3b
Compare
Choose a tag to compare

Minor bug fix that includes makes sure reference data are included when installed.

0.11.1 (Minor Release)

29 Jun 17:09
Compare
Choose a tag to compare

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)

25 Jun 17:29
Compare
Choose a tag to compare

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.htmlin 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() and get_display_name()
    to opal.core.pathways.Pathway and opal.core.patient_lists.PatientList.

Updates to the Dependency Graph

  • Django compressor: 1.5 -> 2.2

0.10.1 (Minor Release)

18 Apr 17:29
Compare
Choose a tag to compare

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)

04 Apr 14:58
Compare
Choose a tag to compare

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)

03 Dec 11:41
Compare
Choose a tag to compare

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.