Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
84 changes: 73 additions & 11 deletions www/addons/mod/glossary/controllers/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ angular.module('mm.addons.mod_glossary')
* @name mmaModGlossaryEditCtrl
*/
.controller('mmaModGlossaryEditCtrl', function($stateParams, $scope, mmaModGlossaryComponent, $mmUtil, $q, $mmaModGlossary, $mmText,
$translate, $ionicHistory, $mmEvents, mmaModGlossaryAddEntryEvent, $mmaModGlossaryOffline) {
$translate, $ionicHistory, $mmEvents, mmaModGlossaryAddEntryEvent, $mmaModGlossaryOffline, $mmaModGlossaryHelper) {

var module = $stateParams.module,
courseId = $stateParams.courseid,
Expand All @@ -46,6 +46,7 @@ angular.module('mm.addons.mod_glossary')
casesensitive: false,
fullmatch: false
};
$scope.attachments = [];

if (entry) {
$scope.entry.concept = entry.concept || '';
Expand All @@ -54,40 +55,70 @@ angular.module('mm.addons.mod_glossary')
$scope.options.categories = entry.options.categories || null;
$scope.options.aliases = entry.options.aliases || "";
$scope.options.usedynalink = !!entry.options.usedynalink || glossary.usedynalink;
$scope.options.casesensitive = !!entry.options.casesensitive
$scope.options.casesensitive = !!entry.options.casesensitive;
$scope.options.fullmatch = !!entry.options.fullmatch;
}

// Treat offline attachments if any.
if (entry.attachments && entry.attachments.offline) {
$mmaModGlossaryHelper.getStoredFiles(glossaryId, entry.concept).then(function(files) {
$scope.attachments = files;
});
}
}

// Block leaving the view, we want to show a confirm to the user if there's unsaved data.
$mmUtil.blockLeaveView($scope, cancel);

// Fetch Glossary data.
function fetchGlossaryData(refresh) {
function fetchGlossaryData() {
return $mmaModGlossary.getAllCategories(glossaryId).then(function(categories) {
$scope.categories = categories;

if ($scope.options.categories) {
var cats = $scope.options.categories.split(",");
angular.forEach(cats, function(catId) {
angular.forEach($scope.categories, function(category) {
if (category.id == catId) {
category.selected = true;
}
});
});
}
});
}

// Just ask to confirm the lost of data.
function cancel() {
if (!$scope.entry.text && !$scope.entry.concept) {
return $q.when();
var promise;

if (!$mmaModGlossaryHelper.hasEntryDataChanged($scope.entry, $scope.attachments)) {
promise = $q.when();
} else {
// Show confirmation if some data has been modified.
return $mmUtil.showConfirm($translate('mm.core.confirmcanceledit'));
promise = $mmUtil.showConfirm($translate('mm.core.confirmcanceledit'));
}

return promise.then(function() {
// Delete the local files from the tmp folder.
$mmaModGlossaryHelper.clearTmpFiles($scope.attachments);
});
}

$scope.save = function() {
var concept = $scope.entry.concept,
definition = $scope.entry.text;
definition = $scope.entry.text,
modal,
attachments,
saveOffline = false;

if (!concept || !definition) {
$mmUtil.showErrorModal('mma.mod_glossary.fillfields', true);
return;
}

modal = $mmUtil.showModalLoading('mm.core.sending', true);

// Check if rich text editor is enabled or not.
$mmUtil.isRichTextEditorEnabled().then(function(enabled) {
if (!enabled) {
Expand All @@ -101,7 +132,19 @@ angular.module('mm.addons.mod_glossary')
}
return $q.when();

}).then(function(entryId) {
}).then(function() {
attachments = $scope.attachments;

// Upload attachments first if any.
if (attachments.length) {
return $mmaModGlossaryHelper.uploadOrStoreFiles(glossaryId, concept, attachments, false)
.catch(function() {
// Cannot upload them in online, save them in offline.
saveOffline = true;
return $mmaModGlossaryHelper.uploadOrStoreFiles(glossaryId, concept, attachments, true);
});
}
}).then(function(attach) {
var cats = $scope.categories.filter(function(category) {
return category.selected;
}).map(function(category) {
Expand All @@ -120,24 +163,43 @@ angular.module('mm.addons.mod_glossary')
options.fullmatch = $scope.options.fullmatch ? 1 : 0;
}
}
return $mmaModGlossary.addEntry(glossaryId, concept, courseId, definition, options);

if (saveOffline) {
// Save entry in offline.
return $mmaModGlossaryOffline.saveAddEntry(glossaryId, concept, definition, courseId, options, attach).then(function() {
// Don't return anything.
});
} else {
// Try to send it to server.
// Don't allow offline if there are attachments since they were uploaded fine.
return $mmaModGlossary.addEntry(glossaryId, concept, definition, courseId, options, attach, undefined,
!attachments.length);
}
}).then(function(entryId) {
if (entryId) {
$scope.entry.id = entryId;
// Data sent to server, delete stored files (if any).
$mmaModGlossaryHelper.deleteStoredFiles(glossaryId, concept);
}
$scope.entry.glossaryid = glossaryId;
$scope.entry.id = entryId;
$scope.entry.definition = definition;
return returnToEntryList();
}).catch(function(error) {
$mmUtil.showErrorModalDefault(error, 'mma.mod_glossary.cannoteditentry', true);
}).finally(function() {
modal.dismiss();
});
};

function returnToEntryList(entryId) {
function returnToEntryList() {
var data = {
glossaryid: glossaryId,
cmid: cmid,
entry: $scope.entry
};

$mmaModGlossaryHelper.clearTmpFiles($scope.attachments);

$mmEvents.trigger(mmaModGlossaryAddEntryEvent, data);

// Go back to discussions list.
Expand Down
1 change: 1 addition & 0 deletions www/addons/mod/glossary/lang/en.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
{
"addentry": "Add a new entry",
"aliases": "Keyword(s)",
"attachment": "Attachment",
"browsemode": "Browse entries",
"byalphabet": "Alphabetically",
"byauthor": "Group by author",
Expand Down
41 changes: 26 additions & 15 deletions www/addons/mod/glossary/services/glossary.js
Original file line number Diff line number Diff line change
Expand Up @@ -630,41 +630,44 @@ angular.module('mm.addons.mod_glossary')
* @module mm.addons.mod_glossary
* @ngdoc method
* @name $mmaModGlossary#addEntry
* @param {Number} glossaryId Glossary ID.
* @param {String} concept Glossary entry concept.
* @param {String} definition Glossary entry concept definition.
* @param {Number} courseId Course ID of the glossary.
* @param {Array} [options] Array of options for the entry.
* @param {String} [siteId] Site ID. If not defined, current site.
* @param {Number} glossaryId Glossary ID.
* @param {String} concept Glossary entry concept.
* @param {String} definition Glossary entry concept definition.
* @param {Number} courseId Course ID of the glossary.
* @param {Array} [options] Array of options for the entry.
* @param {Mixed} [attach] Attachments ID if sending online, result of $mmFileUploader#storeFilesToUpload otherwise.
* @param {String} [siteId] Site ID. If not defined, current site.
* @param {Boolean} allowOffline True if it can be stored in offline, false otherwise.
* @return {Promise} Promise resolved with entry ID if entry was created in server, false if stored in device.
*/
self.addEntry = function(glossaryId, concept, definition, courseId, options, siteId) {
self.addEntry = function(glossaryId, concept, definition, courseId, options, attach, siteId, allowOffline) {
siteId = siteId || $mmSite.getId();

if (!$mmApp.isOnline()) {
if (!$mmApp.isOnline() && allowOffline) {
// App is offline, store the action.
return storeOffline();
}

// Discard stored content for this entry. If it exists it means the user is editing it.
return $mmaModGlossaryOffline.deleteAddEntry(glossaryId, concept, siteId).then(function() {
// Try to add it in online.
return self.addEntryOnline(glossaryId, concept, definition, options, siteId).then(function(entryId) {
return self.addEntryOnline(glossaryId, concept, definition, options, attach, siteId).then(function(entryId) {
return entryId;
}).catch(function(error) {
if (error && error.wserror) {
// The WebService has thrown an error, this means that responses cannot be deleted.
return $q.reject(error.error);
} else {
if (allowOffline && error && !error.wserror) {
// Couldn't connect to server, store in offline.
return storeOffline();
} else {
// The WebService has thrown an error or offline not supported, reject.
return $q.reject(error.error);
}
});
});

// Convenience function to store a new page to be synchronized later.
function storeOffline() {
return $mmaModGlossaryOffline.saveAddEntry(glossaryId, concept, definition, courseId, options, siteId).then(function() {
return $mmaModGlossaryOffline.saveAddEntry(glossaryId, concept, definition, courseId, options, attach,
siteId).then(function() {
return false;
});
}
Expand All @@ -680,12 +683,13 @@ angular.module('mm.addons.mod_glossary')
* @param {String} concept Glossary entry concept.
* @param {String} definition Glossary entry concept definition.
* @param {Array} [options] Array of options for the entry.
* @param {Number} [attachId] Attachments ID (if any attachment).
* @param {String} [siteId] Site ID. If not defined, current site.
* @return {Promise} Promise resolved if created, rejected otherwise. Reject param is an object with:
* - error: The error message.
* - wserror: True if it's an error returned by the WebService, false otherwise.
*/
self.addEntryOnline = function(glossaryId, concept, definition, options, siteId) {
self.addEntryOnline = function(glossaryId, concept, definition, options, attachId, siteId) {
return $mmSitesManager.getSite(siteId).then(function(site) {
var params = {
glossaryid: glossaryId,
Expand All @@ -697,6 +701,13 @@ angular.module('mm.addons.mod_glossary')
params.options = $mmUtil.objectToArrayOfObjects(options, 'name', 'value');
}

if (attachId) {
params.options.push({
name: 'attachmentsid',
value: attachId
});
}

return addEntryOnline(site, params).then(function(response) {
if (response.entryid) {
return response.entryid;
Expand Down
68 changes: 54 additions & 14 deletions www/addons/mod/glossary/services/glossary_offline.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ angular.module('mm.addons.mod_glossary')
* @ngdoc service
* @name $mmaModGlossaryOffline
*/
.factory('$mmaModGlossaryOffline', function($mmSitesManager, $log, mmaModGlossaryAddEntryStore) {
.factory('$mmaModGlossaryOffline', function($mmSitesManager, $log, mmaModGlossaryAddEntryStore, $mmFS) {
$log = $log.getInstance('$mmaModGlossaryOffline');

var self = {};
Expand Down Expand Up @@ -127,35 +127,75 @@ angular.module('mm.addons.mod_glossary')
* @module mm.addons.mod_glossary
* @ngdoc method
* @name $mmaModGlossaryOffline#saveAddEntry
* @param {Number} glossaryId Glossary ID.
* @param {String} concept Glossary entry concept.
* @param {String} definition Glossary entry concept definition.
* @param {Number} courseId Course ID of the glossary.
* @param {Array} [options] Array of options for the entry.
* @param {String} [siteId] Site ID. If not defined, current site.
* @param {Number} [userId] User the entry belong to. If not defined, current user in site.
* @return {Promise} Promise resolved if stored, rejected if failure.
* @param {Number} glossaryId Glossary ID.
* @param {String} concept Glossary entry concept.
* @param {String} definition Glossary entry concept definition.
* @param {Number} courseId Course ID of the glossary.
* @param {Array} [options] Array of options for the entry.
* @param {Object} [attach] Result of $mmFileUploader#storeFilesToUpload for attachments.
* @param {String} [siteId] Site ID. If not defined, current site.
* @param {Number} [userId] User the entry belong to. If not defined, current user in site.
* @return {Promise} Promise resolved if stored, rejected if failure.
*/
self.saveAddEntry = function(glossaryId, concept, definition, courseId, options, siteId, userId) {
self.saveAddEntry = function(glossaryId, concept, definition, courseId, options, attach, siteId, userId) {
return $mmSitesManager.getSite(siteId).then(function(site) {
userId = userId || site.getUserId();

var now = new Date().getTime(),
entry = {
var entry = {
glossaryid: glossaryId,
courseid: courseId,
concept: concept,
definition: definition,
definitionformat: 'html',
options: options,
userid: userId,
timecreated: now,
timemodified: now
timecreated: new Date().getTime()
};

if (attach) {
entry.attachments = attach;
}

return site.getDb().insert(mmaModGlossaryAddEntryStore, entry);
});
};

/**
* Get the path to the folder where to store files for offline attachments in a glossary.
*
* @module mm.addons.mod_glossary
* @ngdoc method
* @name $mmaModGlossaryOffline#getGlossaryFolder
* @param {Number} glossaryId Glossary ID.
* @param {String} [siteId] Site ID. If not defined, current site.
* @return {Promise} Promise resolved with the path.
*/
self.getGlossaryFolder = function(glossaryId, siteId) {
return $mmSitesManager.getSite(siteId).then(function(site) {

var siteFolderPath = $mmFS.getSiteFolder(site.getId()),
folderPath = 'offlineglossary/' + glossaryId;

return $mmFS.concatenatePaths(siteFolderPath, folderPath);
});
};

/**
* Get the path to the folder where to store files for a new offline entry.
*
* @module mm.addons.mod_glossary
* @ngdoc method
* @name $mmaModGlossaryOffline#getEntryFolder
* @param {Number} glossaryId Glossary ID.
* @param {Number} entryName The name of the entry.
* @param {String} [siteId] Site ID. If not defined, current site.
* @return {Promise} Promise resolved with the path.
*/
self.getEntryFolder = function(glossaryId, entryName, siteId) {
return self.getGlossaryFolder(glossaryId, siteId).then(function(folderPath) {
return $mmFS.concatenatePaths(folderPath, 'newentry_' + entryName);
});
};

return self;
});
Loading