Skip to content

Commit

Permalink
Merge upstream 0.11.0
Browse files Browse the repository at this point in the history
  • Loading branch information
davidmiller committed Jun 15, 2018
2 parents f79c44d + 4cec37e commit 5bd2038
Show file tree
Hide file tree
Showing 24 changed files with 371 additions and 55 deletions.
38 changes: 38 additions & 0 deletions CHANGELOG.md
Expand Up @@ -18,6 +18,9 @@ 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.

#### 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
Expand All @@ -26,6 +29,15 @@ 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
Expand All @@ -38,6 +50,32 @@ 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.

#### Updates to the Dependency Graph

* Django compressor: 1.5 -> 2.2


### 0.10.1 (Minor Release)

Expand Down
6 changes: 0 additions & 6 deletions doc/docs/guides/dump.md
Expand Up @@ -28,12 +28,6 @@ _is_singleton is a boolean property that ensures that there is only one of this

Effectively this defaults to False.

### _title

_title sets the column headings in list view.

Effectively this defaults to camel_case_to_underscore() on the class name.

### _sort

_sort names a field by which we would like to sort the display of subrecords.
Expand Down
75 changes: 75 additions & 0 deletions doc/docs/reference/core_subrecords.md
@@ -0,0 +1,75 @@
# opal.core.subrecords

The `opal.core.subrecords` module contains utility functions for working with
subrecords.

## `episode_subrecords()`

Generator function that iterates through all episode subrecords.

```python
for s in episode_subrecords():
print(s)

# -> Location, Diagosis et cetera
```

## `patient_subrecords()`

Generator function that iterates through all patient subrecords.

```python
for s in patient_subrecords():
print(s)

# -> Allergies, ContactDetails et cetera
```

## `subrecords()`

Generator function that iterates through all subrecords.

```python
for s in subrecords():
print(s)

# -> Allergies, ContactDetails, Location, Diagnosis et cetera
```

## `singletons()`

Generator function that iterates through all singleton subrecords.

```python
for s in singletons():
print(s)

# -> Location, Demographics
```

## Fetchers

### `get_subrecord_from_api_name(api_name)`

Return a subrecord given the relevant API name for it. Raise a ValueError
if no matching subrecord is found.


```python
get_subrecord_from_api_name('demographics')

# -> <class Demographics>
```


### `get_subrecord_from_model_name(model_name)`

Return a subrecord given the relevant model name for it. Raise a ValueError
if no matching subrecord is found.


```python
get_subrecord_from_api_name('Demographics')

# -> <class Demographics>
```
21 changes: 20 additions & 1 deletion doc/docs/reference/form_templatetags.md
Expand Up @@ -109,7 +109,26 @@ available by using the unit argument e.g.

### {% radio ... %}

Generates an inline radio input
Generates an inline radio input.
Options are rendered in rows with multiple options on each row.

Keywords:

* `field` a string of the models api name '.' field from this it calculates the label, model and will infer the lookuplist if required. For example {% radio field="DogOwner.dog" %}
* `label` The Label with which to describe this input
* `model` The model which we are editing (This is a string that references an in-scope Angular variable)
* `change` A javascript function that fires if the field has changed
* `show` A string that contains an Angular expression for the ng-show directive
* `hide` A string that contains an Angular expression for the ng-hide directive
* `lookuplist` an Angular expression that evaluates to an array containing the radio values
* `element_name` If this exists this is an Angular expression that is set to the 'name' attribute of the html element
* `style` The form style to render this widget with. Possible values are `['horizontal', 'vertical']`. Defaults to 'horizontal'


### {% radio_vertical ... %}

Generates a vertical radio input.
Options are rendered one option per row.

Keywords:

Expand Down
10 changes: 8 additions & 2 deletions doc/docs/reference/pathways.md
Expand Up @@ -64,10 +64,16 @@ Steps are a single section within a form, and can be instances of either `opal.m
`pathway.Step` subclasses. You can use both types of Step in a given Pathway.

More detail on Steps is given in the [Guides section on Pathways](../guides/pathways.md)

## HelpTextStep

A Step subclass with help text to the side of the form
A Step subclass with help text to the side of the form.

As arguments these takes either `help_text` or `help_text_template`.

`help_text` will be displayed in a side bar next to the step.

`help_text_template` will completely replace the normal side bar template with the template that you pass in.

## FindPatientStep

Expand Down
11 changes: 6 additions & 5 deletions doc/docs/reference/reference_guides.md
Expand Up @@ -16,16 +16,17 @@ The following reference guides are available:
-|-
[opal.core.application](opal_application.md) | Opal Application objects|
[opal.core.detail](detail_views.md)|Detail Views - Custom views over one or many episodes.|
[opal.core.discoverable](core_discoverable.md) | Reusable feature groups for plugins and applications |
[opal.core.episodes](episode_categories.md)|Episode Categories - Controlling the behaviour of different types of episode|
[opal.core.schemas](schemas.md)|Schemas - Dynamic columns for the table views|
[opal.core.fields](core_fields)| Field helpers - custom field types and utility functions|
[opal.core.patient_lists](patient_list.md)|Patient Lists - defining different types of list|
[opal.core.plugin](plugin.md)| Plugins - defining plugins to package reusable functionality
[opal.core.menus](core_menus.md)| Menus - declaring application menus
[opal.core.log](loggers.md)| Log Helpers - custom email error loggers
[opal.core.fields](core_fields)| Field helpers - custom field types and utility functions|
[opal.core.lookuplists](core_lookuplists.md) | Utilities for working with lookuplists |
[opal.core.discoverable](core_discoverable.md) | Reusable feature groups for plugins and applications |
[opal.core.menus](core_menus.md)| Menus - declaring application menus
[opal.core.plugin](plugin.md)| Plugins - defining plugins to package reusable functionality
[opal.core.schemas](schemas.md)|Schemas - Dynamic columns for the table views|
[opal.core.serialization](core_serialization.md) | Helpers for serializing and deserializing data
[opal.core.subrecords](core_subrecords.md) | Helpers for working with subrecords

### Angular Services
|
Expand Down
25 changes: 16 additions & 9 deletions doc/docs/reference/subrecords.md
Expand Up @@ -58,15 +58,6 @@ Name of the field by which we want to sort these records when displaying.
_sort = 'start_date'
```

#### Subrecord._title

String we would like to use for user-facing display of this record type.

```python
class Antimicrobial(EpisodeSubrecord):
_title = 'Abx'
```

#### Subrecord._clonable

A Boolean that is True by default used by `opal.views.EpisodeCopyToCategoryView`
Expand Down Expand Up @@ -106,6 +97,22 @@ representations of the data.
"demographics"
```

#### Subrecord.get_display_name()

Classmethod that returns the display name of the subrecord.

This is used as the user visible title of subrecord panels and modals amongst other places.

By default this uses the Django
[Meta verbose_name](https://docs.djangoproject.com/en/dev/ref/models/options/#verbose-name)
property

```python
>>> PastMedicalHistory.get_display_name()
"PMH"
```


#### Subrecord.get_display_template()

Classmethod to locate the display template for our record. By default this
Expand Down
10 changes: 4 additions & 6 deletions doc/docs/reference/upgrading.md
Expand Up @@ -5,13 +5,10 @@ application to a later version where there are extra steps required.

### 0.10.1 -> 0.11.0

#### Upgrading Opal

How you do this depends on how you have configured your application, but updating your
requirements.txt to update the version should work.
Please upgrade django-compressor version to 2.2, ie update your requirements to

# requirements.txt
opal==0.10.1
# requirements.txt
django-compressor==2.2

### 0.10.0 -> 0.10.1

Expand Down Expand Up @@ -47,6 +44,7 @@ you have specified them in for instance, a requirements.txt.
requests==2.18.4
django-celery==3.2.2
celery==3.1.25
django-compressor==2.2


After re-installing (via for instance `pip install -r requirements.txt`) you will
Expand Down
1 change: 1 addition & 0 deletions doc/mkdocs.yml
Expand Up @@ -76,6 +76,7 @@ pages:
- Lookuplists: reference/core_lookuplists.md
- Discoverable: reference/core_discoverable.md
- Serialization: reference/core_serialization.md
- Subrecords: reference/core_subrecords.md

# Angular Services
- reference/javascript/patient_service.md
Expand Down
3 changes: 3 additions & 0 deletions opal/core/pathway/steps.py
Expand Up @@ -182,3 +182,6 @@ class HelpTextStep(Step):

def get_help_text(self):
return self.other_args.get("help_text", "").strip()

def get_help_text_template(self):
return self.other_args.get("help_text_template", "").strip()
Expand Up @@ -19,11 +19,15 @@ <h3>
</div>
</div> <!-- Col -->
<div class="col-md-4">
<p markdown class="sidebar-help content-offset">
{% block side_bar %}
{{ step.get_help_text }}
{% endblock %}
</p>
{% block side_bar %}
{% if step.get_help_text_template %}
{% include step.get_help_text_template %}
{% else %}
<p markdown class="sidebar-help content-offset">
{{ step.get_help_text }}
</p>
{% endif %}
{% endblock %}
</div>
</div>
</div>
41 changes: 40 additions & 1 deletion opal/core/pathway/tests/test_steps.py
Expand Up @@ -128,7 +128,15 @@ def test_get_help_text(self):
s.get_help_text(), "interesting"
)

def test_step_render(self):
def test_get_help_test_with_no_argument(self):
s = HelpTextStep(
display_name="fake", template=""
)
self.assertEqual(
s.get_help_text(), ''
)

def test_step_help_text_render(self):
class SomePathway(PagePathway):
display_name = "some pathway"
slug = "some_pathway"
Expand All @@ -139,3 +147,34 @@ class SomePathway(PagePathway):
)
url = reverse("pathway_template", kwargs=dict(name="some_pathway"))
self.assertStatusCode(url, 200)

def test_step_help_text_render_with_no_arg(self):
class SomePathway(PagePathway):
display_name = "some pathway"
slug = "some_pathway"
steps = (
HelpTextStep(
display_name="fake", template=""
),
)
url = reverse("pathway_template", kwargs=dict(name="some_pathway"))
self.assertStatusCode(url, 200)

def test_get_help_text_template(self):
s = HelpTextStep(
display_name="fake",
template="",
help_text_template="/pathways/something.html"
)
self.assertEqual(
s.get_help_text_template(), "/pathways/something.html"
)

def test_get_help_text_template_with_no_arg(self):
s = HelpTextStep(
display_name="fake",
template="",
)
self.assertEqual(
s.get_help_text_template(), ''
)
9 changes: 9 additions & 0 deletions opal/core/subrecords.py
Expand Up @@ -36,6 +36,15 @@ def subrecords():
yield m


def singletons():
"""
Generator function for singleton subrecords
"""
for s in subrecords():
if s._is_singleton:
yield s


def get_subrecord_from_api_name(api_name):
for subrecord in subrecords():
if subrecord.get_api_name() == api_name:
Expand Down

0 comments on commit 5bd2038

Please sign in to comment.