Skip to content

Commit

Permalink
show form preview
Browse files Browse the repository at this point in the history
  • Loading branch information
shapiromatron committed Jan 28, 2025
1 parent b6eacd4 commit c227ffc
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 30 deletions.
6 changes: 6 additions & 0 deletions frontend/summary/summary/RoBBarchart.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ class RoBBarchart extends RoBHeatmap {
.show({maxWidth: 1200});
}

displayAsPreview(el) {
const options = {dev: true},
data = this.getPlotData();
return new RoBBarchartPlot(this, data, options).render($(el));
}

getPlotData() {
return {
aggregation: this.roba,
Expand Down
6 changes: 6 additions & 0 deletions frontend/summary/summary/RoBHeatmap.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,12 @@ class RoBHeatmap extends BaseVisual {
.show({maxWidth: 1200});
}

displayAsPreview(el) {
const options = {dev: true},
data = this.getPlotData();
return new RoBHeatmapPlot(this, data, options).render($(el));
}

getPlotData() {
return {
aggregation: this.roba,
Expand Down
29 changes: 27 additions & 2 deletions frontend/summary/summaryForms/rob/PreviewPanel.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,45 @@
import {toJS} from "mobx";
import {inject, observer} from "mobx-react";
import PropTypes from "prop-types";
import React, {Component} from "react";
import Loading from "shared/components/Loading";

import RoBBarchart from "../../summary/RoBBarchart";
import RoBHeatmap from "../../summary/RoBHeatmap";

@inject("store")
@observer
class PreviewPanel extends Component {
constructor(props) {
super(props);
this.visualRef = React.createRef();
}
_maybeShowVisual() {
const store = this.props.store.subclass;
store.checkDataHash();
if (this.visualRef.current) {
const data = toJS(store.visualData),
el = $(this.visualRef.current);
// TODO - update legend dragging x/y somehow?
if (store.isHeatmap) {
new RoBHeatmap(data, {}).displayAsPreview(el);
} else if (store.isBarchart) {
new RoBBarchart(data, {}).displayAsPreview(el);
}
}
}
componentDidMount() {
this.props.store.subclass.checkDataHash();
this._maybeShowVisual();
}
componentDidUpdate() {
this._maybeShowVisual();
}
renderVisual() {
const {store} = this.props;
if (store.subclass.dataFetchRequired) {
return <Loading />;
}
return <p>Visual</p>;
return <div ref={this.visualRef}></div>;
}
render() {
return (
Expand Down
3 changes: 3 additions & 0 deletions frontend/summary/summaryForms/stores/BaseDjangoStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ class BaseDjangoStore {
@action.bound toJsonObject() {
return h.formToJsonObject(this.djangoForm);
}
@action.bound toFormData() {
return new FormData(this.djangoForm);
}
@computed get isCreate() {
return this.config.crud === "Create";
}
Expand Down
27 changes: 9 additions & 18 deletions frontend/summary/summaryForms/stores/RobStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -102,27 +102,18 @@ class RobStore {
@action.bound getVisualData() {
const {config} = this.root.base,
url = `/summary/api/assessment/${config.assessment}/json_data/`,
payload = this.root.base.toJsonObject();
payload["visual_type"] = config.visual_type;
payload["evidence_type"] = config.initial_data.evidence_type;
h.handleSubmit(
url,
"POST",
config.csrf,
payload,
response => {
console.log(response);
formData = this.root.base.toFormData();
formData.append("visual_type", config.visual_type);
formData.append("evidence_type", config.initial_data.evidence_type);

fetch(url, h.fetchPostForm(config.csrf, formData))
.then(resp => resp.json())
.then(response => {
response.settings = this.settings;
this.currentDataHash = this.visualDataHash;
this.visualData = response;
this.dataFetchRequired = false;
},
err => {
console.error(err);
},
err => {
console.error(err);
}
);
});
}

// check if visualization data is needed
Expand Down
38 changes: 28 additions & 10 deletions hawc/apps/summary/api.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from uuid import uuid4

from django.shortcuts import get_object_or_404
from rest_framework.decorators import action
from rest_framework.filters import BaseFilterBackend
Expand All @@ -13,7 +15,7 @@
from ..assessment.constants import AssessmentViewSetPermissions
from ..assessment.models import Assessment
from ..common.api import DisabledPagination
from ..common.helper import FlatExport, PydanticToDjangoError, cacheable
from ..common.helper import FlatExport, PydanticToDjangoError, cacheable, tryParseInt
from ..common.renderers import DocxRenderer, PandasRenderers
from ..common.serializers import UnusedSerializer
from . import constants, forms, models, schemas, serializers, table_serializers
Expand Down Expand Up @@ -55,19 +57,35 @@ def heatmap_datasets(self, request, pk):
action_perms=AssessmentViewSetPermissions.TEAM_MEMBER_OR_HIGHER,
)
def json_data(self, request, pk):
"""Get json data for a Visual using a configuration given in the payload."""
"""Get json data for a Visual; designed for create/update operations."""
assessment = self.get_object()
if request.data.get("visual_type") in [2, 3]:

# get visual_type
try:
visual_type = constants.VisualType(tryParseInt(request.data.get("visual_type", -1)))
except ValueError:
return Response({"error": "Bad Request"}, status=HTTP_400_BAD_REQUEST)

# check ROB style visuals
if visual_type in [constants.VisualType.ROB_HEATMAP, constants.VisualType.ROB_BARCHART]:
# data is not JSON; it's POST form data for proper prefilter form validation logic
data = request.data.copy()
data["evidence_type"] = constants.StudyType(data["evidence_type"])
try:
evidence_type = constants.StudyType(tryParseInt(data["evidence_type"], -1))
except ValueError:
return Response({"error": "Bad Request"}, status=HTTP_400_BAD_REQUEST)
uuid = str(uuid4())
data.update(title=uuid, slug=uuid, evidence_type=evidence_type)
form = forms.RoBForm(
data,
evidence_type=data["evidence_type"],
visual_type=data["visual_type"],
parent=assessment,
data, evidence_type=evidence_type, visual_type=visual_type, parent=assessment
)
form.instance.id = -1
return Response(serializers.VisualSerializer(form.instance).data)
if form.is_valid() is False:
return Response({"error": "Bad Request"}, status=HTTP_400_BAD_REQUEST)
instance = form.save(commit=False)
instance.prefilters = form.cleaned_data["prefilters"]
instance.id = -1
return Response(serializers.VisualSerializer(instance).data)

with PydanticToDjangoError(drf=True):
config = schemas.VisualDataRequest.model_validate(request.data.get("config", {}))
instance = config.mock_visual(assessment)
Expand Down

0 comments on commit c227ffc

Please sign in to comment.