Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

migrate data pivot to visual #1114

Open
wants to merge 40 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
e525240
migrate data pivot
shapiromatron Sep 24, 2024
3795a92
Merge branch 'main' into dp-to-visual
shapiromatron Jan 12, 2025
e655ecf
migrate data
shapiromatron Jan 12, 2025
fe8dd44
fix some tests
shapiromatron Jan 12, 2025
b09b5a5
fix visual type forms; switch exclude to fields
shapiromatron Jan 12, 2025
f480a93
fix reverse
shapiromatron Jan 12, 2025
3ac4b99
remove data pivot query api
shapiromatron Jan 14, 2025
964f792
data pivot upload
shapiromatron Jan 14, 2025
17b8afc
fix delete
shapiromatron Jan 14, 2025
e41f06d
fix display
shapiromatron Jan 14, 2025
e6d19fc
add updates
shapiromatron Jan 14, 2025
6ce1056
remove duplicates
shapiromatron Jan 14, 2025
03e2d27
update visual settings
shapiromatron Jan 14, 2025
3887ed0
return list
shapiromatron Jan 14, 2025
553d5ad
update how form context can be passed
shapiromatron Jan 14, 2025
efa413c
updates
shapiromatron Jan 14, 2025
5663274
fix data pivot query
shapiromatron Jan 14, 2025
2120177
update data pivot upload
shapiromatron Jan 14, 2025
a563501
add legacy url redirect
shapiromatron Jan 14, 2025
670df5e
add copy selector
shapiromatron Jan 14, 2025
e35f5a4
add create selector
shapiromatron Jan 14, 2025
cbbe4e6
fix spelling
shapiromatron Jan 14, 2025
58a3b37
create data pivot file
shapiromatron Jan 14, 2025
7797c3b
enable data pivot query
shapiromatron Jan 14, 2025
f131633
remove data pivots
shapiromatron Jan 15, 2025
8767cde
fix fixtures
shapiromatron Jan 15, 2025
8444457
add some tests
shapiromatron Jan 15, 2025
187c822
update timestamps for new objects
shapiromatron Jan 16, 2025
e1a23da
updates
shapiromatron Jan 16, 2025
a402f42
add form tests
shapiromatron Jan 16, 2025
ee47eb6
fix test failure
shapiromatron Jan 16, 2025
2d5ff85
test labels in filterset
shapiromatron Jan 16, 2025
6ce8ed3
updates
shapiromatron Jan 16, 2025
b05357d
two more tests
shapiromatron Jan 16, 2025
67a064c
restore client behavior
shapiromatron Jan 16, 2025
cae8cbf
bonus test
shapiromatron Jan 16, 2025
2382945
use correct label related queries
shapiromatron Jan 23, 2025
8f4abef
enable admin facets
shapiromatron Jan 23, 2025
5e3fd8d
Merge branch 'main' into dp-to-visual
shapiromatron Jan 23, 2025
854c662
add hidden prefilters forms
shapiromatron Jan 28, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
99 changes: 0 additions & 99 deletions client/hawc_client/summary.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,105 +90,6 @@ def visual_list(self, assessment_id: int) -> pd.DataFrame:
response_json = self.session.get(url).json()
return pd.DataFrame(response_json)

def create_datapivot(self, data: dict) -> dict:
"""Create a new data pivot (query)

Args:
data (dict): Required metadata for object creation.
- title (str): Visual title
- slug (str): Visual identifier/URL base
- evidence_type (int): Constant representing type of evidence used in data pivot
(see hawc.apps.study.constants.StudyType)
- export_style (int): Constant representing how the level at which data are aggregated,
and therefore which columns and types of data are presented in the export, for use
in the visual (see hawc.apps.summary.constants.ExportStyle)
- preferred_units: List of preferred dose-values IDs, in order of preference.
If empty, dose-units will be random for each endpoint
presented. This setting may used for comparing
percent-response, where dose-units are not needed, or for
creating one plot similar, but not identical, dose-units.
- published (bool): datapivot is published for public view
- settings (str): JSON of object settings
- assessment (int): assessment ID
- prefilters (str): JSON of object prefilters
- caption (str): Data pivot caption

Returns:
dict: The resulting object, if create was successful
"""
url = f"{self.session.root_url}/summary/api/data_pivot_query/"
return self.session.post(url, data=data).json()

def update_datapivot(self, datapivot_id: int, data: dict) -> dict:
"""Update an existing data pivot (query)

Args:
id (int): Data pivot identifier
data (dict): Required metadata for object creation.
- title (str): Visual title
- slug (str): Visual identifier/URL base
- evidence_type (int): Constant representing type of evidence used in data pivot
(see hawc.apps.study.constants.StudyType)
- export_style (int): Constant representing how the level at which data are aggregated,
and therefore which columns and types of data are presented in the export, for use
in the visual (see hawc.apps.summary.constants.ExportStyle)
- preferred_units: List of preferred dose-values IDs, in order of preference.
If empty, dose-units will be random for each endpoint
presented. This setting may used for comparing
percent-response, where dose-units are not needed, or for
creating one plot similar, but not identical, dose-units.
- published (bool): datapivot is published for public view
- settings (str): JSON of object settings
- assessment (int): assessment ID
- prefilters (str): JSON of object prefilters
- caption (str): Data pivot caption

Returns:
dict: The resulting object, if update was successful
"""
url = f"{self.session.root_url}/summary/api/data_pivot_query/{datapivot_id}/"
return self.session.patch(url, data=data).json()

def get_datapivot(self, datapivot_id: int):
"""Get a data pivot (query).

Args:
visual_id (int): ID of the visual to read

Returns:
Response: A response object, which contains the visual if successful.

"""
url = f"{self.session.root_url}/summary/api/data_pivot_query/{datapivot_id}/"
return self.session.get(url).json()

def delete_datapivot(self, datapivot_id: int):
"""Delete a data pivot (query).

Args:
visual_id (int): ID of the visual to delete

Returns:
None: If the operation is successful there is no return value.
If the operation is unsuccessful, an error will be raised.
"""
url = f"{self.session.root_url}/summary/api/data_pivot_query/{datapivot_id}/"
self.session.delete(url)

def datapivot_list(self, assessment_id: int) -> pd.DataFrame:
"""
Retrieves a data pivot list for the given assessment.

Args:
assessment_id (int): Assessment ID

Returns:
pd.DataFrame: Data Pivot list
"""
url = f"{self.session.root_url}/summary/api/data_pivot/?assessment_id={assessment_id}"
response_json = self.session.get(url).json()
return pd.DataFrame(response_json)

def table_list(self, assessment_id: int) -> pd.DataFrame:
"""
Retrieves a table list for the given assessment.
Expand Down
4 changes: 4 additions & 0 deletions docs/docs/client.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ Client tutorials for common operations are below:

#### NEXT (TBD)

* Remove data pivot API endpoints; all behaviors can be accomplished using the visual API

#### [2024-4](https://pypi.org/project/hawc-client/2024.4/) (January 2024)

* Added literature tag API {create, update, delete, move}

#### [2024-3](https://pypi.org/project/hawc-client/2024.3/) (October 2024)
Expand Down
4 changes: 2 additions & 2 deletions frontend/summary/dataPivot/DataPivot.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class DataPivot {
}

static get_object(pk, callback) {
const url = `/summary/api/data_pivot/${pk}/`,
const url = `/summary/api/visual/${pk}/`,
handleError = err => {
$("#loading_div").hide();
handleVisualError(err, $("#dp_display"));
Expand All @@ -53,7 +53,7 @@ class DataPivot {
fetch(url, h.fetchGet)
.then(d => d.json())
.then(d => {
fetch(d.data_url, h.fetchGet)
fetch(d.data_url + "?format=tsv", h.fetchGet)
.then(resp => {
if (!resp.ok) {
throw Error(`Invalid server response: ${resp.status}`);
Expand Down
6 changes: 3 additions & 3 deletions frontend/summary/summaryForms/BaseVisualForm.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,9 @@ class BaseVisualForm {
var self = this,
form = $("form").serialize();

if (this.isSynching) return;
if (this.isSyncing) return;
this.dataSynced = false;
this.isSynching = true;
this.isSyncing = true;
$.post(this.config.preview_url, form, function(d) {
self.data = d;
if (self.afterGetDataHook) self.afterGetDataHook(d);
Expand All @@ -89,7 +89,7 @@ class BaseVisualForm {
);
})
.always(function() {
self.isSynching = false;
self.isSyncing = false;
self.dataSynced = true;
$("#preview, #settings").trigger("dataSynced");
});
Expand Down
23 changes: 1 addition & 22 deletions hawc/apps/assessment/actions/audit.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,30 +73,9 @@ def get_assessment_queryset(self):
# get assessment visuals
visual_qs = versions_by_content_type("summary", "visual")
visual_qs = versions_by_related_field("assessment", [self.assessment.pk], visual_qs)
# get assessment data pivots
data_pivot_qs = versions_by_content_type("summary", "datapivot")
data_pivot_qs = versions_by_related_field("assessment", [self.assessment.pk], data_pivot_qs)
# get data pivot uploads
data_pivot_upload_qs = versions_by_content_type("summary", "datapivotupload")
data_pivot_upload_qs = data_pivot_upload_qs.filter(
object_id__in=set(data_pivot_qs.values_list("object_id", flat=True))
)
# get data pivot queries
data_pivot_query_qs = versions_by_content_type("summary", "datapivotquery")
data_pivot_query_qs = data_pivot_query_qs.filter(
object_id__in=set(data_pivot_qs.values_list("object_id", flat=True))
)

return (
assess_qs
| attach_qs
| dataset_qs
| dataset_revision_qs
| summary_table_qs
| visual_qs
| data_pivot_qs
| data_pivot_upload_qs
| data_pivot_query_qs
assess_qs | attach_qs | dataset_qs | dataset_revision_qs | summary_table_qs | visual_qs
)

def get_animal_queryset(self):
Expand Down
11 changes: 5 additions & 6 deletions hawc/apps/assessment/actions/search.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
from django.contrib.contenttypes.models import ContentType
from django.db.models import Q, QuerySet
from django.db.models.base import ModelBase

from ...myuser.models import HAWCUser
from ...study.models import Study
from ...summary.models import Visual
from ..models import Assessment, Label, LabeledItem


Expand Down Expand Up @@ -45,17 +45,16 @@ def search_studies(


def search_visuals(
model_cls: ModelBase,
query: str,
all_public: bool = False,
public: QuerySet[Assessment] | None = None,
all_internal: bool = False,
internal: QuerySet[Assessment] | None = None,
user: HAWCUser | None = None,
) -> QuerySet:
) -> QuerySet[Visual]:
filters = Q()

ct = ContentType.objects.get_for_model(model_cls)
ct = ContentType.objects.get_for_model(Visual)

if all_public or public:
filters1 = dict(
Expand Down Expand Up @@ -83,6 +82,6 @@ def search_visuals(
filters |= (Q(title__icontains=query) | Q(id__in=labeled_items)) & Q(**filters2)

if not bool(filters):
return model_cls.objects.none()
return Visual.objects.none()

return model_cls.objects.filter(filters)
return Visual.objects.filter(filters)
13 changes: 1 addition & 12 deletions hawc/apps/assessment/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from django.core.mail import mail_admins
from django.db import transaction
from django.db.models import QuerySet
from django.db.models.base import ModelBase
from django.urls import reverse, reverse_lazy
from django.utils import timezone

Expand All @@ -31,7 +30,6 @@
from ..common.widgets import DateCheckboxInput
from ..myuser.autocomplete import UserAutocomplete
from ..study.autocomplete import StudyAutocomplete
from ..summary import models as summary_models
from ..vocab.constants import VocabularyNamespace
from . import autocomplete, constants, models
from .actions import search
Expand Down Expand Up @@ -128,7 +126,6 @@ def helper(self):
helper.add_row("editable", 3, "col-md-4")
helper.add_row("conflicts_of_interest", 2, "col-md-6")
helper.add_create_btn("dtxsids", reverse("assessment:dtxsid_create"), "Add new DTXSID")
helper.attrs["novalidate"] = ""
return helper


Expand Down Expand Up @@ -582,7 +579,6 @@ class SearchForm(forms.Form):
choices=(
("study", "Studies"),
("visual", "Visuals"),
("data-pivot", "Data Pivots"),
),
)
order_by = forms.ChoiceField(
Expand All @@ -600,15 +596,9 @@ class SearchForm(forms.Form):
order_by_override = {
("visual", "name"): "title",
("visual", "-name"): "-title",
("data-pivot", "name"): "title",
("data-pivot", "-name"): "-title",
("study", "name"): "short_citation",
("study", "-name"): "-short_citation",
}
model_class: dict[str, ModelBase] = {
"visual": summary_models.Visual,
"data-pivot": summary_models.DataPivotQuery,
}

def __init__(self, *args, **kwargs):
self.user = kwargs.pop("user")
Expand Down Expand Up @@ -684,10 +674,9 @@ def search(self):
.prefetch_related("identifiers")
.order_by(order_by)
)
case "visual" | "data-pivot":
case "visual":
return (
search.search_visuals(
model_cls=self.model_class[data["type"]],
query=data["query"],
all_public=data["all_public"],
public=data["public"],
Expand Down
9 changes: 1 addition & 8 deletions hawc/apps/assessment/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,20 +331,13 @@ def prefetch_content_objects(self):
"content_object",
[
apps.get_model("summary", "Visual").objects.all(),
apps.get_model("summary", "DataPivotUpload").objects.all(),
apps.get_model("summary", "DataPivotQuery").objects.all(),
apps.get_model("summary", "SummaryTable").objects.all(),
],
)
)

def filter_title(self, query: str):
filter = (
Q(summary_table__title__icontains=query)
| Q(visual__title__icontains=query)
| Q(datapivot_query__title__icontains=query)
| Q(datapivot_upload__title__icontains=query)
)
filter = Q(summary_tables__title__icontains=query) | Q(visuals__title__icontains=query)
return self.filter(filter)

def matching_all_labels(self, labels: list):
Expand Down
15 changes: 0 additions & 15 deletions hawc/apps/assessment/templates/assessment/published_items.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,6 @@ <h3>Visuals</h3>
{% bs4_colgroup '20,80' %}
{% bs4_thead 'Published,Visual' %}
<tbody>
{% for dp in datapivots %}
{% if forloop.first %}
<tr>
<th colspan="2">Data Pivots</th>
</tr>
{% endif %}
<tr>
{% include 'assessment/fragments/publish_item_td.html' with name="datapivot" object=dp %}
<td><a href="{{dp.get_absolute_url}}">{{dp}}</a></td>
</tr>
{% empty %}
<tr>
<td colspan="2"><i>No data pivots exist.</i></td>
</tr>
{% endfor %}
{% for visual in visuals %}
{% ifchanged visual.visual_type %}
<tr>
Expand Down
15 changes: 1 addition & 14 deletions hawc/apps/assessment/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,10 +178,7 @@ def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
context = super().get_context_data(**kwargs)
if context["form"].is_valid():
context.update(paginate(context["form"].search(), self.request))
if context["object_list"].model in (
summary_models.Visual,
summary_models.DataPivotQuery,
):
if context["object_list"].model in (summary_models.Visual,):
self.set_visible_labels(self.request.user, context["object_list"])
return context

Expand Down Expand Up @@ -840,9 +837,6 @@ def get_cts(self):
cts["epimeta.metaresult"],
cts["summary.summarytable"],
cts["summary.visual"],
cts["summary.datapivot"],
cts["summary.datapivotupload"],
cts["summary.datapivotquery"],
]

def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
Expand All @@ -858,7 +852,6 @@ class PublishedItemsChecklist(HtmxViewSet):
model_lookups = {
"study": apps.get_model("study", "Study"),
"visual": apps.get_model("summary", "Visual"),
"datapivot": apps.get_model("summary", "DataPivot"),
"dataset": apps.get_model("assessment", "Dataset"),
"summarytable": apps.get_model("summary", "SummaryTable"),
"attachment": apps.get_model("assessment", "Attachment"),
Expand Down Expand Up @@ -919,11 +912,6 @@ def get_list_context_data(self, user, assessment):
.objects.filter(assessment=assessment)
.order_by("short_citation".lower())
)
datapivots = (
apps.get_model("summary", "DataPivot")
.objects.filter(assessment=assessment)
.order_by("title".lower())
)
visuals = (
apps.get_model("summary", "Visual")
.objects.filter(assessment=assessment)
Expand All @@ -947,7 +935,6 @@ def get_list_context_data(self, user, assessment):
"assessment": assessment,
"breadcrumbs": crumbs,
"studies": studies,
"datapivots": datapivots,
"visuals": visuals,
"datasets": datasets,
"summarytables": summarytables,
Expand Down
Loading
Loading