0.8.0 Major Release
0.8.0 (Major Release)
Plugins
Plugins have been refactored and are now DiscoverableFeatures
. This should have no impact on existing plugins, however the functions opal.core.plugins.register
and opal.core.plugins.plugins
are slated for
removal in 0.9.0
When creating new plugins we will place the plugin definition class in plugin.py
rather than __init__.py
opal.core.api.patient_from_pk
A decorator that changes a method that is passed a pk, to a method that is passed a patient.
ToDictMixin._bulk_serialise
Adds a flag to the to dict mixin to determine whether the item is serialised as part of Episode/Patient.to_dict
.
Fixes bugs in add many subrecord radio buttons
Previously multiple radio buttons for the same subrecord field on the same page would
not appear to the user to update correctly. This has now been fixed.
Angular UI Libraries
0.8.0 consolidates Angular UI libraries bundled with Opal. We have removed Angular Strap, and
switched all components using it to their Angular UI Bootstrap equivalents.
This is a breaking change.
Applications taking advantage of the Forms
templatetag library should require no updates, but will see some minor differences in visual style of widgets.
Detailed upgrade guides for the components affected (Typeahead, Popover, Tooltip, Datepicker, Timepicker) are available in the upgrade reference documentation.
Defaults for Client Side subrecords
We pull through default values from subrecord fields into the Opal Schema
and use those values when initializing the relevant Item instance for a new subrecord. This should greatly reduce the need to use custom Angular subrecord services to set defaults.
Choices in form templatetags
Template tags that use the 'field' attribute to point to a subrecord field will now infer a lookup list from the Choices of the field if it exists.
Note unlike the traditional choices implementation only the last value of the choices is used and saved to the database
Colours = (
('P', 'Purple'),
('R', 'Red'),
)
What is displayed to the user and saved to the database is 'Purple' or 'Red' respectively.
element name in template tags
The html attribute 'name' for form elements generated with the Opal {% forms %}
templatetag library used to be inferred from the model name. Although this remains the default you can also set it with an angular expression:
{% select field="Demographics.first_name" element_name="...Your Angular expression..." %}
Model removals
The models Team
, GP
, CommunityNurse
and LocatedModel
- marked for removal since 0.6.0 have now been removed.
As part of this change, the add episode modal previously available at /templates/modals/add_episode.html/
is now not available at the url with a trailing slash. Any controllers attempting to open the modal e.g. custom list flows should update their $modal.open
call to remove the trailing slash.
Python 3
Opal 0.8.0 is the first version of Opal to support Python 3. This has meant changing the default ordering of PatientList
instances to 0 rather than None.
Moving forwards we expect all new code in Opal to be compatible both Python 2.7 / 3.4 / 3.5 / 3.6.
This introduces an explicit Opal dependency on the Six module for maintaining codebases that span Python 2.x and 3.x.
Tabbed Patient List Groups
Adds the class opal.core.patient_lists.TabbedPatientListGroup
which displays groups of related lists as tabs at the top of each member list.
PatientList sort order
To enable custom sort orders for individual PatientList
s we introduce the comparator_service
attribute.
This names an Angular service which will return a list of comparator functions.
PatientList Arbitrary columns
We now explicitly enable columns in spreadhseet lists that are not tied to subrecords. These can be
included in PatientList schema instances as explicit Column() entries.
Template re-naming
Modal_base has now been moved into a folder called base_templates. Its also now got a form_modal_base and a two_column_form_modal_base.
The latter two templates add validation around saving.
The standard edit item models and others now inherit from the form_modal_base.
Authorization and permissions
All APIs should be permissioned with Django REST framework permission classes. The default implementation uses
opal.core.api.LoginRequiredViewset, a standard DRF viewset that requires the user to be logged in.
We now require the user to be logged in for any use of the search functionality.
Added a custom interceptor that logs the user out if the we receive a 403 or 401 from the server
Form Validation
Adds the checkForm directive
e.g.
<button check-form="form" ng-click="sendDataToTheServer">click me</button>
This adds default form submission behaviour to the a button. It will check if the form is valid, and if its not it will mark the button as disabled until it becomes valid.
It will also set the form as submitted.
We also now show the required error if the form has been submitted or if the field is dirty, so that the user doesn't get an ugly "fill this field in now" message when opening the modal/pathway but will get the error after they click submit.
Removals
Opal 0.8.0 removes a number of un-used features that have been slated for removal for some time:
Options
- both from the JSON API, and the Angular service.- The legacy APIs
/api/v0.1/episode/admit
and/api/v0.1/episode/refer
. - The models
GP
,CommunityNurse
andLocatedModel
. opal.models.Tagging.import_from_reversion
. This one-off classmethod on tagging was introduced to aid with the upgrade from Opal 4.x to 5.0 and has no further utility.- The
static
argument from the formsinput
tag. Developers should move to thestatic
tag. - The _modal option to set on subrecords. This is because we now use large modals across the board.
Misc changes
The opal.core.api.EpisodeViewSet.create now expects tagging to be an object rather than a list, similar to how it details with demographics and location.
The API will no longer serialise the _ft or _fk_id fields of FreeTextOrForeignKey fields - these
are internal implementation details of the server that are not useful on the client side.
Adds a Unique Together constraint for (Tagging.user, Tagging.episode, Tagging.value)
Look up lists now load in from individual apps. The look for a file at {{ app }}/data/lookuplists.json
The default admin url is now /admin/
- rather than /admin/?
this results in more readable
admin urls and is closer to what most applications do with the Django admin.
The roles field opal.models.UserProfile.roles
has been updated to be blank=True
. This allows the editing
of users without specific roles assigned in the Django admin. Although this introduces no changes at the
database level, this does introduce a migration.
Updates to the Dependency Graph
Upgrades angular to v1.5.8 (from 1.3.11) you can see their change log here
Updates angular-cookies and angular-mocks to v1.5.8 (both from 1.3.11)
Updates angular-ui-select to 0.19.4 from 0.13.2