Skip to content

Commit

Permalink
Merge pull request #343 from RTIInternational/validated_updates
Browse files Browse the repository at this point in the history
Add ability to un-verify data, lock changing verified labels
  • Loading branch information
AstridKery authored Jul 2, 2024
2 parents e1147ff + 99ccc4c commit 39afa6c
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 34 deletions.
8 changes: 5 additions & 3 deletions backend/django/core/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,10 +142,13 @@ class Meta:
fields = ["allow_coders_view_labels"]

def __init__(self, *args, **kwargs):
percentage_irr = kwargs.pop('percentage_irr')
percentage_irr = kwargs.pop("percentage_irr")
super(ProjectUpdateAdvancedForm, self).__init__(*args, **kwargs)
if percentage_irr > 0:
self.fields['allow_coders_view_labels'].widget.attrs['disabled'] = 'disabled'
self.fields["allow_coders_view_labels"].widget.attrs[
"disabled"
] = "disabled"


class LabelForm(forms.ModelForm):
class Meta:
Expand Down Expand Up @@ -276,7 +279,6 @@ class Meta:

allow_coders_view_labels = forms.BooleanField(initial=False, required=False)


def clean(self):
use_active_learning = self.cleaned_data.get("use_active_learning")
use_default_batch_size = self.cleaned_data.get("use_default_batch_size")
Expand Down
4 changes: 3 additions & 1 deletion backend/django/core/urls/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,9 @@
),
re_path(r"^unassign_data/(?P<data_pk>\d+)/$", api_annotate.unassign_data),
re_path(r"^skip_data/(?P<data_pk>\d+)/$", api_annotate.skip_data),
re_path(r"^verify_label/(?P<data_pk>\d+)/$", api_annotate.verify_label),
re_path(
r"^toggle_verify_label/(?P<data_pk>\d+)/$", api_annotate.toggle_verify_label
),
re_path(
r"^enter_coding_page/(?P<project_pk>\d+)/$", api_annotate.enter_coding_page
),
Expand Down
35 changes: 22 additions & 13 deletions backend/django/core/views/api_annotate.py
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ def unassign_data(request, data_pk):

@api_view(["POST"])
@permission_classes((IsCoder,))
def verify_label(request, data_pk):
"""Take a data label that was not verified, and verify it.
def toggle_verify_label(request, data_pk):
"""Either verify or unverify a data item.
Args:
request: The POST request
Expand All @@ -227,15 +227,22 @@ def verify_label(request, data_pk):
return Response(response)
elif DataLabel.objects.filter(data=data).count() > 1:
response["error"] = (
"ERROR: This data has multiple labels. This shouldn't "
"be possible with unverified data as it is pre-labeled."
"ERROR: This data has multiple labels which only occurs for incomplete IRR data which cannot be verified."
)
else:
VerifiedDataLabel.objects.create(
data_label=DataLabel.objects.get(data=data),
verified_timestamp=timezone.now(),
verified_by=request.user.profile,
)
datalabel = DataLabel.objects.get(data=data)
# if it's verified, un-verify it.
if VerifiedDataLabel.objects.filter(data_label=datalabel).exists():
VerifiedDataLabel.objects.filter(
data_label=datalabel,
).delete()
else:
# the data is not verified so we verify it
VerifiedDataLabel.objects.create(
data_label=DataLabel.objects.get(data=data),
verified_timestamp=timezone.now(),
verified_by=request.user.profile,
)

return Response(response)

Expand Down Expand Up @@ -1095,13 +1102,15 @@ def get_label_history(request, project_pk):
labeled_data_df["pre_loaded"] = labeled_data_df["pre_loaded"].apply(
lambda x: "Yes" if x else "No"
)
labeled_data_df["edit"] = "yes"
labeled_data_df["edit"] = labeled_data_df["verified"].apply(
lambda verified: "No" if verified == "Yes" else "Yes"
)
labeled_data_df["label"] = labeled_data_df["labelID"].apply(
lambda x: label_dict[x]
)

if len(irr_data_df) > 0:
irr_data_df["edit"] = "no"
irr_data_df["edit"] = "No"
irr_data_df["label"] = irr_data_df["labelID"].apply(lambda x: label_dict[x])
irr_data_df["verified"] = (
"N/A (IRR)" # Technically resolved IRR is verified but perhaps not this user's specific label so just NA
Expand All @@ -1116,9 +1125,9 @@ def get_label_history(request, project_pk):
# merge the data info with the label info
if len(all_labeled_stuff) > 0:
data_df = data_df.merge(all_labeled_stuff, on=["id"], how="left")
data_df["edit"] = data_df["edit"].fillna("yes")
data_df["edit"] = data_df["edit"].fillna("Yes")
else:
data_df["edit"] = "yes"
data_df["edit"] = "Yes"
data_df["label"] = ""
data_df["profile"] = ""
data_df["timestamp"] = ""
Expand Down
12 changes: 6 additions & 6 deletions backend/django/core/views/frontend.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,9 @@ def done(self, form_list, form_dict, **kwargs):
proj_obj.percentage_irr = advanced_data["percentage_irr"]
proj_obj.num_users_irr = advanced_data["num_users_irr"]
proj_obj.classifier = advanced_data["classifier"]
proj_obj.allow_coders_view_labels = advanced_data["allow_coders_view_labels"]
proj_obj.allow_coders_view_labels = advanced_data[
"allow_coders_view_labels"
]

# use the data dedup choice to set dedup property of metadata fields
proj_obj.dedup_on = data.cleaned_data["dedup_on"]
Expand Down Expand Up @@ -444,13 +446,12 @@ def form_valid(self, form):
else:
return self.render_to_response(context)


class ProjectUpdateAdvanced(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Project
form_class = ProjectUpdateAdvancedForm
template_name = "projects/update/advanced.html"
permission_denied_message = (
"You must be an Admin or Project Creator to access the Advanced Project Settings Update page."
)
permission_denied_message = "You must be an Admin or Project Creator to access the Advanced Project Settings Update page."
raise_exception = True

def test_func(self):
Expand All @@ -465,7 +466,7 @@ def get_form_kwargs(self):
# pass the percentage_irr to the form
kwargs = super().get_form_kwargs()
project = self.get_object()
kwargs['percentage_irr'] = project.percentage_irr
kwargs["percentage_irr"] = project.percentage_irr
return kwargs

def form_valid(self, form):
Expand All @@ -478,7 +479,6 @@ def form_valid(self, form):
return self.render_to_response(context)



class ProjectUpdateData(LoginRequiredMixin, UserPassesTestMixin, UpdateView):
model = Project
form_class = DataUpdateWizardForm
Expand Down
37 changes: 28 additions & 9 deletions frontend/src/components/History/HistoryTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ const HistoryTable = () => {
const [shouldRefetch, setShouldRefetch] = useState(false);

const { data: historyData, refetch: refetchHistory } = useHistory(page + 1, unlabeled, filters);
const { mutate: verifyLabel } = useVerifyLabel();
const { mutate: toggleVerifyLabel } = useVerifyLabel();

const metadataColumnsAccessorKeys = [];
if (historyData) {
Expand Down Expand Up @@ -171,17 +171,30 @@ const HistoryTable = () => {
accessorKey: "verified",
cell: (info) => {
if (info.getValue() == "Yes") {
return (<p>Yes</p>);
return (
<div>
<p>Yes</p>
<Button
onClick={() => toggleVerifyLabel({ dataID: info.row.original.id })}
variant="danger"
>
X
</Button>
</div>
);
} else if (info.getValue() != "No") {
return (<p>{info.getValue()}</p>);
} else {
return (
<Button
onClick={() => verifyLabel({ dataID: info.row.original.id })}
variant="success"
>
Verify
</Button>
<div>
<p>No</p>
<Button
onClick={() => toggleVerifyLabel({ dataID: info.row.original.id })}
variant="success"
>
</Button>
</div>
);
}
},
Expand All @@ -195,7 +208,13 @@ const HistoryTable = () => {
getExpandedRowModel: getExpandedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getRowCanExpand: () => true,
getRowCanExpand: (data) => {
if (data.original.edit === "Yes") {
return true;
} else {
return false;
}
},
getSortedRowModel: getSortedRowModel(),
initialState: {
pagination: {
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/hooks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,4 @@ export { default as useLabels } from "./useLabels";
export { default as useMetadataValue } from "./useMetadataValue";
export { default as useModifyLabel } from "./useModifyLabel";
export { default as useSuggestedLabels } from "./useSuggestedLabels";
export { default as useVerifyLabel } from "./useVerifyLabel";
export { default as useVerifyLabel } from "./useToggleVerifyLabel";
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { postConfig } from "../utils/fetch_configs";
const useVerifyLabel = () =>
useMutation({
mutationFn: ({ dataID }) =>
fetch(`/api/verify_label/${dataID}/`, postConfig({ dataID })),
fetch(`/api/toggle_verify_label/${dataID}/`, postConfig({ dataID })),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: ["history", PROJECT_ID] });
}
Expand Down

0 comments on commit 39afa6c

Please sign in to comment.