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

Commit

Permalink
Added warning message when user try to close learning resource panel …
Browse files Browse the repository at this point in the history
…without saving
  • Loading branch information
amir-qayyum-khan committed Mar 12, 2016
1 parent 81aad5d commit f31eff8
Show file tree
Hide file tree
Showing 6 changed files with 290 additions and 28 deletions.
11 changes: 8 additions & 3 deletions ui/jstests/learningresources/test-learning-resource.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,14 @@ define(
function (assert) {
var div = document.createElement("div");
assert.ok($(div).html().length === 0);
LearningResources.loader("repo", "1", function () {
}, function () {
}, div);
var options = {
"repoSlug": "repo",
"learningResourceId": "1",
"refreshFromAPI": this.refreshFromAPI,
"markDirty": function() {},
"closeLearningResourcePanel": function() {}
};
LearningResources.loader(options, div);
assert.ok($(div).html().length > 0);
}
);
Expand Down
130 changes: 130 additions & 0 deletions ui/jstests/learningresources/test_learning_resource_panel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -248,11 +248,136 @@ define(["QUnit", "react", "test_utils", "jquery", "lodash",

React.addons.TestUtils.renderIntoDocument(<LearningResourcePanel
repoSlug="repo"
markDirty={function() {}}
closeLearningResourcePanel={closeLearningResourcePanel}
learningResourceId="1"
ref={afterMount}/>);
}
);

QUnit.test(
'Assert that mark dirty sets properly when description change.',
function (assert) {
var done = assert.async();

var markDirtyState = false;
var markDirty = function (state) {
markDirtyState = state;
};

var afterMount = function (component) {
// wait for calls to populate form
waitForAjax(3, function () {
var textarea = React.addons.TestUtils.
findRenderedDOMComponentWithTag(
component,
'textarea'
);
React.addons.TestUtils.Simulate.change(
textarea, {target: {value: "x"}}
);
component.forceUpdate(function () {
assert.equal(component.state.description, "x");
assert.ok(markDirtyState, "Marked dirty");
done();
});
});
};
React.addons.TestUtils.renderIntoDocument(<LearningResourcePanel
repoSlug="repo"
markDirty={markDirty}
closeLearningResourcePanel={function() {}}
learningResourceId="1"
ref={afterMount}/>);
}
);

QUnit.test(
'Assert that mark dirty sets properly when terms change.',
function (assert) {
var done = assert.async();
var markDirtyState = false;
var markDirty = function (state) {
markDirtyState = state;
};
var closeLearningResourcePanel = function () {
};

var afterMount = function (component) {
// wait for calls to populate form
waitForAjax(3, function () {
// two menus: vocabulary and terms.
var $node = $(React.findDOMNode(component));

var $allSelects = $node.find("#vocabularies select");
assert.equal($allSelects.size(), 2);

var $vocabSelect = $node.find($allSelects).first();
assert.equal($vocabSelect.size(), 1);

// first vocab, two options
var $vocabOptions = $vocabSelect.find("option");
assert.equal($vocabOptions.size(), 2);

assert.equal($vocabOptions[0].selected, true);
assert.equal($vocabOptions[1].selected, false);

// TestUtils.Simulate.change only simulates a change event,
// we need to update the value first ourselves
$vocabSelect.val("prerequisite").trigger('change');
component.forceUpdate(function () {
assert.equal($vocabOptions[0].selected, false);
assert.equal($vocabOptions[1].selected, true);
// re-fetch the selects to get the prerequisite one
$allSelects = $node.find("#vocabularies select");
var termsSelect = $allSelects[1];
var $termsOptions = $(termsSelect).find("option");
assert.equal($termsOptions.size(), 2);
assert.equal($termsOptions[0].selected, true);
assert.equal($termsOptions[1].selected, false);

// remove selection for this vocabulary to not interfere to the rest of the test
$(termsSelect).val("").trigger('change');
component.forceUpdate(function () {
// Switch to difficulty
$vocabSelect.val("difficulty").trigger('change');
component.forceUpdate(function () {
// re-fetch the selects to get the difficulty one
$allSelects = $node.find("#vocabularies select");
// update the term select
termsSelect = $allSelects[1];
$termsOptions = $(termsSelect).find("option");

assert.equal($termsOptions.size(), 2);
assert.equal($termsOptions[0].selected, false);
assert.equal($termsOptions[1].selected, false);
// the second vocabulary can be a multi select
$(termsSelect)
.val(["hard", "easy"])
.trigger('change');
markDirtyState = false;
component.forceUpdate(function () {
// when terms are change then markDirtyState flag is set.
assert.equal(markDirtyState, true);
assert.equal($termsOptions[0].selected, true);
assert.equal($termsOptions[1].selected, true);
done();
});
});
});
});
});
};

React.addons.TestUtils.renderIntoDocument(<LearningResourcePanel
repoSlug="repo"
markDirty={markDirty}
closeLearningResourcePanel={closeLearningResourcePanel}
learningResourceId="1"
ref={afterMount}/>);
}
);

QUnit.test(
'Assert that LearningResourcePanel saves properly',
function (assert) {
Expand Down Expand Up @@ -300,6 +425,7 @@ define(["QUnit", "react", "test_utils", "jquery", "lodash",
React.addons.TestUtils.renderIntoDocument(<LearningResourcePanel
repoSlug="repo"
learningResourceId="1"
markDirty={function() {}}
closeLearningResourcePanel={closeLearningResourcePanel}
refreshFromAPI={refreshFromAPI}
ref={afterMount}/>);
Expand Down Expand Up @@ -353,6 +479,7 @@ define(["QUnit", "react", "test_utils", "jquery", "lodash",

React.addons.TestUtils.renderIntoDocument(<LearningResourcePanel
repoSlug="repo"
markDirty={function() {}}
closeLearningResourcePanel={closeLearningResourcePanel}
learningResourceId="1"
refreshFromAPI={refreshFromAPI}
Expand Down Expand Up @@ -386,6 +513,7 @@ define(["QUnit", "react", "test_utils", "jquery", "lodash",
};
React.addons.TestUtils.renderIntoDocument(<LearningResourcePanel
repoSlug="repo"
markDirty={function() {}}
closeLearningResourcePanel={closeLearningResourcePanel}
learningResourceId="1"
ref={afterMount}/>);
Expand Down Expand Up @@ -418,6 +546,7 @@ define(["QUnit", "react", "test_utils", "jquery", "lodash",
};
React.addons.TestUtils.renderIntoDocument(<LearningResourcePanel
repoSlug="repo"
markDirty={function() {}}
closeLearningResourcePanel={closeLearningResourcePanel}
learningResourceId="1"
ref={afterMount}/>);
Expand Down Expand Up @@ -482,6 +611,7 @@ define(["QUnit", "react", "test_utils", "jquery", "lodash",
<LearningResourcePanel
repoSlug="repo"
closeLearningResourcePanel={function() {}}
markDirty={function() {}}
learningResourceId="1"
ref={afterMount}/>
);
Expand Down
58 changes: 58 additions & 0 deletions ui/jstests/listing/test_listing.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -971,5 +971,63 @@ define(['QUnit', 'jquery', 'react', 'test_utils', 'utils', 'listing'],
);

});

QUnit.test('Open and close learning resource panel', function(assert) {
var done = assert.async();
TestUtils.initMockjax({
url: '/api/v1/repositories/test/learning_resources/' +
'1/?remove_content_xml=true',
type: 'GET',
responseText: learningResourceResponse
});
TestUtils.initMockjax({
url: '/api/v1/repositories/test/vocabularies/?type_name=course',
type: 'GET',
responseText: vocabularyResponse
});

var afterMount = function(component) {
waitForAjax(1, function() {
assert.notOk($('.cd-panel').hasClass("is-visible"));
component.openResourcePanel(1);
waitForAjax(2, function() {
assert.equal(component.state.currentResourceId , 1);
assert.ok($('.cd-panel').hasClass("is-visible"));
component.setState({
isLearningResourcePanelDirty: true
}, function () {
component.closeLearningResourcePanel();
assert.ok($('.cd-panel').hasClass("is-visible"),
"LR Panel should not close because it is marked dirty");
component.setState({
isLearningResourcePanelDirty: false
}, function() {
component.closeLearningResourcePanel();
assert.notOk($('.cd-panel').hasClass("is-visible"),
"LR Panel should close");
done();
});
});
});
});
};

var options = {
allExports: listingOptions.allExports,
sortingOptions: listingOptions.sortingOptions,
imageDir: listingOptions.imageDir,
pageSize: 25,
repoSlug: listingOptions.repoSlug,
loggedInUsername: listingOptions.loggedInUsername,
updateQueryString: updateQueryString,
getQueryString: getQueryString,
showConfirmationDialog: function() {},
ref: afterMount
};

React.addons.TestUtils.renderIntoDocument(
React.createElement(Listing.ListingContainer, options)
);
});
}
);
35 changes: 31 additions & 4 deletions ui/static/ui/js/learningresources/learning_resource_panel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ define("learning_resource_panel", ['react', 'jquery', 'lodash',

this.setState({
vocabulariesAndTerms: newVocabulariesAndTerms
}, function () {
this.updateDirty();
});
},

Expand Down Expand Up @@ -115,8 +117,7 @@ define("learning_resource_panel", ['react', 'jquery', 'lodash',
<button className="btn btn-lg btn-primary"
onClick={this.saveLearningResourcePanel}>
Save
</button>
<button className="btn btn-lg btn-success"
</button> <button className="btn btn-lg btn-success"
onClick={this.saveAndCloseLearningResourcePanel}>
Save and Close
</button>
Expand All @@ -133,8 +134,14 @@ define("learning_resource_panel", ['react', 'jquery', 'lodash',
this.setState({
description: event.target.value,
message: undefined
}, function() {
this.updateDirty();
});
},
closeLearningResourcePanel: function(event) {
event.preventDefault();
this.props.closeLearningResourcePanel();
},
saveLearningResourcePanel: function (event) {
event.preventDefault();
this.saveForm(false);
Expand Down Expand Up @@ -165,8 +172,12 @@ define("learning_resource_panel", ['react', 'jquery', 'lodash',
data: JSON.stringify(data)
}).then(function () {
thiz.setState({
message: "Form saved successfully!"
message: "Form saved successfully!",
descriptionOriginal: thiz.state.description,
vocabulariesAndTermsOriginal: thiz.state.vocabulariesAndTerms
});
// user can close panel
thiz.updateDirty();
if (closePanel) {
thiz.props.closeLearningResourcePanel();
}
Expand All @@ -179,6 +190,16 @@ define("learning_resource_panel", ['react', 'jquery', 'lodash',
thiz.setState({loaded: true});
});
},
updateDirty: function() {
// When use change description or terms the mark panel dirty
var isDirty = !_.eq(
this.state.description, this.state.descriptionOriginal
) || !_.eq(
this.state.vocabulariesAndTerms,
this.state.vocabulariesAndTermsOriginal
);
this.props.markDirty(isDirty);
},
componentDidMount: function () {
var thiz = this;

Expand All @@ -204,6 +225,7 @@ define("learning_resource_panel", ['react', 'jquery', 'lodash',
message: undefined,
description: description,
previewUrl: previewUrl,
descriptionOriginal: description,
});
return Utils.getVocabulariesAndTerms(
thiz.props.repoSlug, learningResourceType)
Expand All @@ -230,6 +252,9 @@ define("learning_resource_panel", ['react', 'jquery', 'lodash',

thiz.setState({
vocabulariesAndTerms: vocabulariesAndTerms,
vocabulariesAndTermsOriginal: _.cloneDeep(
vocabulariesAndTerms
)
});

if (vocabulariesAndTerms.length) {
Expand All @@ -255,7 +280,9 @@ define("learning_resource_panel", ['react', 'jquery', 'lodash',
return {
description: "",
vocabulariesAndTerms: [],
selectedVocabulary: {}
selectedVocabulary: {},
descriptionOriginal: "",
vocabulariesAndTermsOriginal: []
};
}
});
Expand Down
17 changes: 9 additions & 8 deletions ui/static/ui/js/learningresources/learning_resources.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,18 @@ define('learning_resources',
'use strict';

return {
loader: function (repoSlug, learningResourceId, refreshFromAPI,
closeLearningResourcePanel, container) {
/** Current list of options are:
repoSlug
learningResourceId
refreshFromAPI
markDirty
closeLearningResourcePanel
*/
loader: function (options, container) {
// Unmount and remount the component to ensure that its state
// is always up to date with the rest of the app.
React.unmountComponentAtNode(container);
React.render(<LearningResourcePanel
repoSlug={repoSlug}
learningResourceId={learningResourceId}
refreshFromAPI={refreshFromAPI}
closeLearningResourcePanel={closeLearningResourcePanel}
/>, container);
React.render(<LearningResourcePanel {...options} />, container);
}
};
});

0 comments on commit f31eff8

Please sign in to comment.