Skip to content
This repository has been archived by the owner on Jan 28, 2020. It is now read-only.

Commit

Permalink
Added delete term functionality in taxonomy panel
Browse files Browse the repository at this point in the history
  • Loading branch information
amir-qayyum-khan committed Sep 18, 2015
1 parent d968511 commit 320fea3
Show file tree
Hide file tree
Showing 3 changed files with 259 additions and 5 deletions.
206 changes: 204 additions & 2 deletions ui/jstests/test_manage_taxonomies.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ define(['QUnit', 'jquery', 'manage_taxonomies', 'react',
}
});

QUnit.test('Assert that TermComponent renders properly',
QUnit.test('Assert that edit TermComponent renders properly',
function(assert) {
assert.ok(TermComponent, "class object not found");
var done = assert.async();
Expand Down Expand Up @@ -415,7 +415,7 @@ define(['QUnit', 'jquery', 'manage_taxonomies', 'react',
waitForAjax(1, function() {
assert.equal(component.state.label, "TestB");
assert.equal(
component.state.errorMessage, 'Unable to update term'
component.state.errorMessage, 'Unable to update term.'
);
assert.equal(component.state.formatActionState, 'edit');
assert.equal(parentUpdateCount, 0);
Expand Down Expand Up @@ -465,6 +465,137 @@ define(['QUnit', 'jquery', 'manage_taxonomies', 'react',
}
);

QUnit.test('Assert that delete TermComponent renders properly',
function(assert) {
assert.ok(TermComponent, "class object not found");
var done = assert.async();
var term = {
"id": 9,
"slug": "test",
"label": "test",
"weight": 1
};
var parentUpdateCount = 0;
var deleteTerm = function() {
parentUpdateCount += 1;
};
var renderConfirmationDialog = function(options) {
options.confirmationHandler(true);
};

TestUtils.initMockjax({
url: "/api/v1/repositories/repo/vocabularies/difficulty/terms/test/",
type: "DELETE"
});

var refreshCount = 0;
var refreshFromAPI = function() {
refreshCount++;
};

var afterMount = function(component) {
var deleteButton = React.addons.TestUtils.
findRenderedDOMComponentWithClass(
component,
'revert-button'
);
//select delete
React.addons.TestUtils.Simulate.click(deleteButton);
component.forceUpdate(function() {
assert.equal(component.state.formatActionState, 'show');
waitForAjax(1, function() {
// term is delete in parent
assert.equal(parentUpdateCount, 1);
// listing was asked to refresh
assert.equal(refreshCount, 1);
done();
});
});
};

React.addons.TestUtils.
renderIntoDocument(
<TermComponent
term={term}
repoSlug="repo"
renderConfirmationDialog={renderConfirmationDialog}
deleteTerm={deleteTerm}
vocabularySlug={vocabulary.slug}
refreshFromAPI={refreshFromAPI}
ref={afterMount}
/>
);
}
);

QUnit.test('Assert that delete ajax call fail TermComponent' +
' renders properly',
function(assert) {
assert.ok(TermComponent, "class object not found");
var done = assert.async();
var term = {
"id": 9,
"slug": "test",
"label": "test",
"weight": 1
};
var parentUpdateCount = 0;
var deleteTerm = function() {
parentUpdateCount += 1;
};
var renderConfirmationDialog = function(options) {
options.confirmationHandler(true);
};

TestUtils.initMockjax({
url: "/api/v1/repositories/repo/vocabularies/difficulty/terms/test/",
type: "DELETE",
status: 400
});

var refreshCount = 0;
var refreshFromAPI = function() {
refreshCount++;
};

var afterMount = function(component) {
var deleteButton = React.addons.TestUtils.
findRenderedDOMComponentWithClass(
component,
'revert-button'
);
//select delete
React.addons.TestUtils.Simulate.click(deleteButton);
component.forceUpdate(function() {
assert.equal(
component.state.errorMessage, ''
);
assert.equal(component.state.formatActionState, 'show');
waitForAjax(1, function() {
// check state of error message
assert.equal(
component.state.errorMessage, 'Unable to delete term.'
);
done();
});
});
};

React.addons.TestUtils.
renderIntoDocument(
<TermComponent
term={term}
repoSlug="repo"
renderConfirmationDialog={renderConfirmationDialog}
deleteTerm={deleteTerm}
vocabularySlug={vocabulary.slug}
refreshFromAPI={refreshFromAPI}
ref={afterMount}
/>
);
}
);

QUnit.test('Assert that VocabularyComponent renders properly',
function(assert) {
assert.ok(VocabularyComponent, "class object not found");
Expand Down Expand Up @@ -1535,6 +1666,77 @@ define(['QUnit', 'jquery', 'manage_taxonomies', 'react',
}
);

QUnit.test('Assert that delete term works in TaxonomyComponent',
function(assert) {
assert.ok(TaxonomyComponent, "class object not found");
var done = assert.async();
var refreshCount = 0;
var refreshFromAPI = function() {
refreshCount++;
};

var renderConfirmationDialog = function(options) {
options.confirmationHandler(true);
};

var afterMount = function(component) {
assert.equal(
component.state.vocabularies.length,
0
);
waitForAjax(2, function() {
assert.equal(
component.state.vocabularies.length,
1
);
assert.equal(
component.state.vocabularies[0].terms.length,
2
);
var updateTermUrl = "/api/v1/repositories/repo/vocabularies/" +
component.state.vocabularies[0].vocabulary.slug + "/terms/" +
component.state.vocabularies[0].terms[0].slug + "/";
TestUtils.initMockjax({
url: updateTermUrl,
type: "DELETE"
});
var deleteButtons = React.addons.TestUtils.
scryRenderedDOMComponentsWithClass(
component,
'revert-button'
);
var deleteButton = deleteButtons[0];
//open edit mode
React.addons.TestUtils.Simulate.click(deleteButton);
component.forceUpdate(function() {
waitForAjax(1, function () {
assert.equal(refreshCount, 1);
//assert term update
assert.equal(
component.state.vocabularies.length,
1
);
assert.equal(
component.state.vocabularies[0].terms.length,
1
);
done();
});
});
});
};
React.addons.TestUtils.renderIntoDocument
(
<TaxonomyComponent
repoSlug="repo"
refreshFromAPI={refreshFromAPI}
renderConfirmationDialog={renderConfirmationDialog}
ref={afterMount}
/>
);
}
);

QUnit.test("Test that ManageTaxonomies.loader renders into div",
function(assert) {
var container = document.createElement("div");
Expand Down
54 changes: 52 additions & 2 deletions ui/static/ui/js/manage_taxonomies.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ define('manage_taxonomies', ['react', 'lodash', 'jquery', 'utils', 'bootstrap'],

if (formatActionState === 'show') {
this.setState({
formatActionState: 'edit',
formatActionState: 'edit'
}, function() {
var $editText = $(React.findDOMNode(this.refs.editText));
$editText.focus();
Expand All @@ -76,6 +76,16 @@ define('manage_taxonomies', ['react', 'lodash', 'jquery', 'utils', 'bootstrap'],
if (formatActionState === 'edit') {
// user is in edit mode. Cancel edit if user presses cross icon.
this.resetUtilityFeatures();
} else if (formatActionState === 'show') {
var options = {
actionButtonName: "Delete",
actionButtonClass: "btn btn-danger btn-ok",
title: "Confirm Delete",
message: "Are you sure you want to delete term '" +
this.props.term.label + "'?",
confirmationHandler: this.confirmedDeleteResponse
};
this.props.renderConfirmationDialog(options);
}
},
/**
Expand Down Expand Up @@ -110,13 +120,33 @@ define('manage_taxonomies', ['react', 'lodash', 'jquery', 'utils', 'bootstrap'],
contentType: "application/json"
}).fail(function() {
thiz.setState({
errorMessage: 'Unable to update term'
errorMessage: 'Unable to update term.'
});
}).done(function(term) {
thiz.resetUtilityFeatures();
thiz.props.updateTerm(thiz.props.vocabularySlug, term);
thiz.props.refreshFromAPI();
});
},
confirmedDeleteResponse: function(success) {
var thiz = this;
if (success) {
var API_ROOT_VOCAB_URL = '/api/v1/repositories/' + this.props.repoSlug +
'/vocabularies/' + this.props.vocabularySlug + '/terms/' +
this.props.term.slug + "/";
$.ajax({
type: 'DELETE',
url: API_ROOT_VOCAB_URL,
contentType: "application/json"
}).fail(function() {
thiz.setState({
errorMessage: 'Unable to delete term.'
});
}).done(function() {
thiz.props.deleteTerm(thiz.props.vocabularySlug, thiz.props.term);
thiz.props.refreshFromAPI();
});
}
}
});

Expand All @@ -126,11 +156,13 @@ define('manage_taxonomies', ['react', 'lodash', 'jquery', 'utils', 'bootstrap'],
var thiz = this;
var items = _.map(this.props.terms, function (term) {
return <TermComponent
deleteTerm={thiz.props.deleteTerm}
updateTerm={thiz.props.updateTerm}
vocabularySlug={thiz.props.vocabulary.slug}
repoSlug={thiz.props.repoSlug}
term={term}
key={term.slug}
renderConfirmationDialog={thiz.props.renderConfirmationDialog}
refreshFromAPI={thiz.props.refreshFromAPI}
/>;
});
Expand Down Expand Up @@ -256,6 +288,7 @@ define('manage_taxonomies', ['react', 'lodash', 'jquery', 'utils', 'bootstrap'],
var thiz = this;
var items = _.map(this.props.vocabularies, function (obj) {
return <VocabularyComponent
deleteTerm={thiz.props.deleteTerm}
updateTerm={thiz.props.updateTerm}
vocabulary={obj.vocabulary}
deleteVocabulary={thiz.props.deleteVocabulary}
Expand Down Expand Up @@ -510,11 +543,28 @@ define('manage_taxonomies', ['react', 'lodash', 'jquery', 'utils', 'bootstrap'],
});
this.setState({vocabularies: vocabularies});
},
deleteTerm: function(vocabSlug, term) {
var vocabularies = _.map(this.state.vocabularies, function(tuple) {
if (tuple.vocabulary.slug === vocabSlug) {
var terms = _.filter(tuple.terms, function (tupleTerm) {
return tupleTerm.id !== term.id;
});
return {
terms: terms,
vocabulary: tuple.vocabulary
};
} else {
return tuple;
}
});
this.setState({vocabularies: vocabularies});
},
render: function() {
return (
<div className="tab-content drawer-tab-content">
<div className="tab-pane active" id="tab-taxonomies">
<AddTermsComponent
deleteTerm={this.deleteTerm}
updateTerm={this.updateTerm}
vocabularies={this.state.vocabularies}
repoSlug={this.props.repoSlug}
Expand Down
4 changes: 3 additions & 1 deletion ui/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,9 @@ def get_vocabularies(facets):
vocab = (vocabulary_id, vocabs[int(vocabulary_id)])
vocabularies[vocab] = []
for t_id, count in term_data:
vocabularies[vocab].append((t_id, terms[int(t_id)], count))
t_id_int = int(t_id)
if t_id_int in terms:
vocabularies[vocab].append((t_id, terms[t_id_int], count))
# By default, sort alphabetically.
vocabularies[vocab].sort(key=lambda x: x[1])
return vocabularies
Expand Down

0 comments on commit 320fea3

Please sign in to comment.