Skip to content

Commit

Permalink
Enable deletion of resolved reference tags (#741)
Browse files Browse the repository at this point in the history
* Added delete functionality for resolved tags when conflict resolution is enabled

* Refactor js

* Update conflict resolution view

* Add transparency to tag linethrough

* rename classes

* rewrite; remove working tags

* extra space

Co-authored-by: Andy Shapiro <shapiromatron@gmail.com>
  • Loading branch information
rabstejnek and shapiromatron authored Dec 8, 2022
1 parent a45f14f commit 28915f3
Show file tree
Hide file tree
Showing 7 changed files with 86 additions and 105 deletions.
2 changes: 1 addition & 1 deletion frontend/lit/Reference.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Reference {
this.data = data;
this._quickSearchText = `${data.title}-${data.year}-${data.authors}-${data.authors_short}`.toLowerCase();
this.tags = data.tags.map(tagId => tagtree.dict[tagId]);
this.userTags = data.user_tags ? data.user_tags.map(tagId => tagtree.dict[tagId]) : [];
this.userTags = data.user_tags ? data.user_tags.map(tagId => tagtree.dict[tagId]) : null;
}

static get_detail_url(id, subtype) {
Expand Down
57 changes: 26 additions & 31 deletions frontend/lit/TagReferences/Main.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class ReferenceListItem extends Component {
title = store.config.conflict_resolution ? "has resolved tag(s)" : "tagged";

return (
<div className={divClass} onClick={() => store.changeSelectedReference(reference)}>
<div className={divClass} onClick={() => store.setReference(reference)}>
<p className="mb-0 pr-1">{reference.shortCitation()}</p>
{reference.tags.length > 0 ? (
<i className="fa fa-fw fa-tags mx-1" title={title} aria-hidden="true"></i>
Expand Down Expand Up @@ -62,11 +62,8 @@ class TagReferencesMain extends Component {
}
render() {
const {store} = this.props,
selectedReferencePk = store.selectedReference ? store.selectedReference.data.pk : null,
selectedReferenceTags = store.selectedReferenceTags ? store.selectedReferenceTags : [],
selectedReferenceUserTags = store.selectedReferenceUserTags
? store.selectedReferenceUserTags
: [];
{hasReference, reference, referenceTags, referenceUserTags} = store,
selectedReferencePk = hasReference ? reference.data.pk : -1; // -1 will never match
return (
<div className="row">
<div className={store.filterClass} id="refFilter">
Expand Down Expand Up @@ -94,7 +91,7 @@ class TagReferencesMain extends Component {
</div>
</div>
<div className={store.filterClass} id="taggingCol">
{store.selectedReference ? (
{store.hasReference ? (
<div>
<div className="d-flex justify-content-between">
<h4 className="my-0">
Expand Down Expand Up @@ -134,40 +131,38 @@ class TagReferencesMain extends Component {
</button>
</div>
<div className="well" style={{minHeight: "50px"}}>
{selectedReferenceTags.map((tag, i) => (
{referenceTags.map((tag, i) => (
<span
key={i}
title={
store.config.conflict_resolution
? "Resolved Tag: ".concat(tag.get_full_name())
? "Tag: ".concat(tag.get_full_name())
: tag.get_full_name()
}
className="refTag refTagEditing"
onClick={
store.config.conflict_resolution
? null
: () => store.removeTag(tag)
}>
{this.state.showFullTag
? tag.get_full_name()
: tag.data.name}
</span>
))}
{selectedReferenceUserTags.map((tag, i) => (
<span
key={i}
title={tag.get_full_name()}
className="refTag refUserTag refTagEditing"
onClick={
store.config.conflict_resolution
? () => store.removeTag(tag)
: null
}>
className={
store.hasTag(referenceUserTags, tag)
? "refTag cursor-pointer"
: "refTag refUserTagRemove cursor-pointer"
}
onClick={() => store.toggleTag(tag)}>
{this.state.showFullTag
? tag.get_full_name()
: tag.data.name}
</span>
))}
{referenceUserTags
.filter(tag => !store.hasTag(referenceTags, tag))
.map((tag, i) => (
<span
key={i}
title={"Proposed: ".concat(tag.get_full_name())}
className="refTag refUserTag cursor-pointer"
onClick={() => store.removeTag(tag)}>
{this.state.showFullTag
? tag.get_full_name()
: tag.data.name}
</span>
))}
</div>
{store.errorOnSave ? (
<div className="alert alert-danger">
Expand All @@ -176,7 +171,7 @@ class TagReferencesMain extends Component {
</div>
) : null}
<Reference
reference={store.selectedReference}
reference={reference}
keywordDict={store.config.keywords}
showActions={false}
showHr={false}
Expand Down
87 changes: 36 additions & 51 deletions frontend/lit/TagReferences/store.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import _ from "lodash";
import {action, observable, toJS} from "mobx";
import {action, computed, observable, toJS} from "mobx";

import {sortReferences} from "../constants";
import Reference from "../Reference";
Expand All @@ -10,9 +10,9 @@ class Store {
saveIndicatorElement = null;
@observable tagtree = null;
@observable references = [];
@observable selectedReference = null;
@observable selectedReferenceTags = null;
@observable selectedReferenceUserTags = null;
@observable reference = null;
@observable referenceTags = null;
@observable referenceUserTags = null;
@observable errorOnSave = false;
@observable filterClass = "";
@observable showInstructionsModal = false;
Expand All @@ -23,50 +23,47 @@ class Store {
this.references = Reference.array(config.refs, this.tagtree);
// set first reference
if (this.references.length > 0) {
this.changeSelectedReference(this.references[0]);
this.setReference(this.references[0]);
}
}

@action.bound changeSelectedReference(reference) {
this.selectedReference = reference;
this.selectedReferenceTags = reference.tags.slice(0); // shallow copy
this.selectedReferenceUserTags = reference.userTags.slice(0);
@computed get hasReference() {
return this.reference !== null;
}
@action.bound setReference(reference) {
this.reference = reference;
this.referenceTags = reference.tags.slice(0); // shallow copy
this.referenceUserTags = reference.userTags
? reference.userTags.slice(0)
: reference.tags.slice(0);
}
hasTag(tags, tag) {
return !!_.find(tags, e => e.data.pk == tag.data.pk);
}
@action.bound addTag(tag) {
if (
this.selectedReference &&
!_.find(
this.config.conflict_resolution
? this.selectedReferenceUserTags
: this.selectedReferenceTags,
el => el.data.pk === tag.data.pk
)
this.hasReference &&
!_.find(this.referenceUserTags, el => el.data.pk === tag.data.pk)
) {
this.config.conflict_resolution
? this.selectedReferenceUserTags.push(tag)
: this.selectedReferenceTags.push(tag);
this.referenceUserTags.push(tag);
}
}
@action.bound removeTag(tag) {
_.remove(
this.config.conflict_resolution
? this.selectedReferenceUserTags
: this.selectedReferenceTags,
el => el.data.pk === tag.data.pk
);
_.remove(this.referenceUserTags, el => el.data.pk === tag.data.pk);
}
@action.bound toggleTag(tag) {
return this.hasTag(this.referenceUserTags, tag) ? this.removeTag(tag) : this.addTag(tag);
}
@action.bound saveAndNext() {
const payload = {
pk: this.selectedReference.data.pk,
tags: this.config.conflict_resolution
? this.selectedReferenceUserTags.map(tag => tag.data.pk)
: this.selectedReferenceTags.map(tag => tag.data.pk),
pk: this.reference.data.pk,
tags: this.referenceUserTags.map(tag => tag.data.pk),
},
url = `/lit/api/reference/${this.reference.data.pk}/tag/`,
success = () => {
const $el = $(this.saveIndicatorElement),
index = _.findIndex(
this.references,
ref => ref.data.pk === this.selectedReference.data.pk
ref => ref.data.pk === this.reference.data.pk
);

if ($el.length !== 1) {
Expand All @@ -76,46 +73,34 @@ class Store {
this.errorOnSave = false;
$el.fadeIn().fadeOut({
complete: () => {
this.selectedReference.tags = toJS(this.selectedReferenceTags);
this.selectedReference.userTags = toJS(this.selectedReferenceUserTags);
this.references.splice(index, 1, toJS(this.selectedReference));
this.selectedReference = null;
this.selectedReferenceTags = null;
this.selectedReferenceUserTags = null;
if (this.references.length > index + 1) {
this.changeSelectedReference(this.references[index + 1]);
} else {
this.changeSelectedReference(this.references[0]);
this.reference.userTags = toJS(this.referenceUserTags);
if (!this.config.conflict_resolution) {
this.reference.tags = toJS(this.referenceUserTags);
}
const nextIndex = this.references.length > index + 1 ? index + 1 : 0,
reference = this.references[nextIndex];
this.setReference(reference);
},
});
},
failure = data => {
console.error(data);
this.errorOnSave = true;
};

$.post(`/lit/api/reference/${this.selectedReference.data.pk}/tag/`, payload, v =>
v.status === "success" ? success() : failure()
).fail(failure);
$.post(url, payload, v => (v.status === "success" ? success() : failure())).fail(failure);
}
@action.bound removeAllTags() {
this.config.conflict_resolution
? (this.selectedReferenceUserTags = [])
: (this.selectedReferenceTags = []);
this.referenceUserTags = [];
}
@action.bound setSaveIndicatorElement(el) {
this.saveIndicatorElement = el;
}

@action.bound sortReferences(sortBy) {
this.references = sortReferences(this.references, sortBy);
}

@action.bound toggleSlideAway() {
this.filterClass = this.filterClass == "" ? "slideAway" : "";
}

@action.bound setInstructionsModal(input) {
this.showInstructionsModal = input;
}
Expand Down
17 changes: 8 additions & 9 deletions hawc/apps/lit/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -1176,16 +1176,15 @@ class UserReferenceTag(models.Model):
def assessment_id(self) -> int:
return self.reference.assessment_id

def get_tags_diff(self):
all_tags = set(self.reference.tags.all())
for user_tag in self.reference.user_tags.all():
if user_tag.id == self.id:
continue
all_tags.update(set(user_tag.tags.all()))
def consensus_diff(self):
# returns set operations done against consensus tags
consensus_tags = set(self.reference.tags.all())
self_tags = set(self.tags.all())
tags_diff = self_tags.difference(all_tags)
tags_same = self_tags.intersection(all_tags)
return dict(diff=tags_diff, same=tags_same)
return dict(
intersection=self_tags.intersection(consensus_tags),
difference=self_tags.difference(consensus_tags),
reverse_difference=consensus_tags.difference(self_tags),
)


reversion.register(LiteratureAssessment)
Expand Down
14 changes: 9 additions & 5 deletions hawc/apps/lit/templates/lit/_reference_tag_conflict.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,16 @@
<b class="mb-0">{{user_tag.user.get_full_name}}</b> <i class="m-0 small">{{user_tag.user.email}}</i>
<input name="user_tag_id" value={{user_tag.pk}} class="hidden">
</div>
{% with user_tag.get_tags_diff as tags%}
{% for tag in tags.same %}
{% include 'lit/_nested_tag.html' with tag=tag extra_classes='refUserTag' %}
{% with user_tag.consensus_diff as diff %}
{% for tag in ref.tags.all %}
{% if tag in diff.intersection %}
{% include 'lit/_nested_tag.html' with tag=tag extra_classes='' %}
{% else %}
{% include 'lit/_nested_tag.html' with tag=tag extra_classes='refUserTagRemove' %}
{% endif %}
{% endfor %}
{% for tag in tags.diff %}
{% include 'lit/_nested_tag.html' with tag=tag extra_classes='refUserTagDiff' %}
{% for tag in diff.difference %}
{% include 'lit/_nested_tag.html' with tag=tag extra_classes='refUserTag' %}
{% endfor %}
{% endwith %}
</form>
Expand Down
2 changes: 1 addition & 1 deletion hawc/apps/lit/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ def get_app_config(self, context) -> WebappConfig:
references = [ref.to_dict() for ref in context["object_list"]]
ref_tags = context["object_list"].user_tags(user_id=self.request.user.id)
for reference in references:
reference["user_tags"] = ref_tags.get(reference["pk"], [])
reference["user_tags"] = ref_tags.get(reference["pk"])
return WebappConfig(
app="litStartup",
page="startupTagReferences",
Expand Down
12 changes: 5 additions & 7 deletions hawc/static/css/hawc.css
Original file line number Diff line number Diff line change
Expand Up @@ -345,9 +345,6 @@ div.smart-tag.active {
text-align: left;
white-space: pre-wrap;
}
.refTagEditing {
cursor: pointer;
}
.abstract_label {
font-weight: bold;
}
Expand Down Expand Up @@ -476,10 +473,11 @@ div.smart-tag.active {
display: inline-block;
}

.refUserTagDiff {
color: #ffffff;
background-color: maroon;
border: 0.15rem dotted #ffffff;
.refUserTagRemove {
color: rgb(128,0,0);
background-color: #ffffff;
border: 0.15rem dotted rgb(128,0,0);
text-decoration: line-through rgba(128,0,0,0.5);
}

.refTagSame {
Expand Down

0 comments on commit 28915f3

Please sign in to comment.