diff --git a/common/ellipsis.js b/common/ellipsis.js index 49fd7181d..44e7e8d2f 100644 --- a/common/ellipsis.js +++ b/common/ellipsis.js @@ -115,7 +115,7 @@ scope.callToggleFavorite = function () { if (scope.isFavoriteLoading) return; scope.isFavoriteLoading = true; - scope.toggleFavorite(scope.tuple, scope.tuple.isFavorite).then(function (isFavorite) { + scope.toggleFavorite(scope.tuple.data, scope.tuple.reference.table, scope.tuple.isFavorite).then(function (isFavorite) { // attached value is to the tuple // TODO: this should be changed but it was the only value shared between ellipsis // and when I read in the data for setting favorites diff --git a/common/faceting.js b/common/faceting.js index e3c41712f..2a14342c5 100644 --- a/common/faceting.js +++ b/common/faceting.js @@ -1139,7 +1139,11 @@ scope.checkboxRows = appliedFiltersToCheckBoxRows(scope); // there might be more, we're not sure scope.hasMore = false; - defer.resolve(true); + updateFavorites(scope).then(function (res) { + defer.resolve(res); + }).catch(function (err) { + defer.reject(err); + }); return defer.promise; } @@ -1150,6 +1154,11 @@ scope.reference = scope.reference.contextualize.compactSelect; } } + + // since reference will be populated here and before this we're not showing the list, + // we have to populate this here (and not directly in link function) + scope.enableFavorites = scope.$root.session && scope.facetColumn.isEntityMode && scope.reference.table.favoritesPath && scope.reference.table.stableKey.length == 1; + // read new data if needed (function (uri) { var facetLog = getDefaultLogInfo(scope); @@ -1220,54 +1229,82 @@ var table = scope.reference.table; // if the stable key is greater than length 1, the favorites won't be supported for now // TODO: support this for composite stable keys - if (scope.$root.session && table.favoritesPath && scope.facetColumn.isEntityMode && table.stableKey.length == 1) { - // array of column names that represent the stable key of leaf with favorites - // favorites_* will use stable key to store this information - // NOTE: hardcode `scope.reference.table.name` for use in pure and binary table mapping - var key = table.stableKey[0]; - var displayedFacetIds = "("; - scope.checkboxRows.forEach(function (row, idx) { - // filter out null and not null rows - if (row.tuple) { - // use the stable key here - displayedFacetIds += UriUtils.fixedEncodeURIComponent(table.name) + "=" + UriUtils.fixedEncodeURIComponent(row.tuple.data[key.name]); - if (idx !== scope.checkboxRows.length-1) displayedFacetIds += ";"; + return updateFavorites(scope); + }).then(function (result) { + // if this is not the result of latest facet change + if (scope.reference.uri !== uri) { + defer.resolve(false); + return defer.promise; + } + + defer.resolve(result); + }).catch(function (err) { + defer.reject(err); + }); + })(scope.reference.uri); + + return defer.promise; + } + + function updateFavorites(scope) { + var defer = $q.defer(), table = scope.reference.table; + + if (!scope.enableFavorites) { + return defer.resolve(true), defer.promise; + } + + // if the stable key is greater than length 1, the favorites won't be supported for now + // TODO: support this for composite stable keys + // array of column names that represent the stable key of leaf with favorites + // favorites_* will use stable key to store this information + // NOTE: hardcode `scope.reference.table.name` for use in pure and binary table mapping + var key = table.stableKey[0]; + var displayedFacetIds = "(", rowCount = 0; + scope.checkboxRows.forEach(function (row, idx) { + // filter out null and not null rows + if (row.tuple) { + rowCount++; + + // use the stable key here + displayedFacetIds += UriUtils.fixedEncodeURIComponent(table.name) + "=" + UriUtils.fixedEncodeURIComponent(row.tuple.data[key.name]); + if (idx !== scope.checkboxRows.length-1) displayedFacetIds += ";"; + } + }); + displayedFacetIds += ")" + // resolve favorites reference for this table with given user_id + var favoritesUri = $window.location.origin + table.favoritesPath + "/user_id=" + UriUtils.fixedEncodeURIComponent(scope.$root.session.client.id) + "&" + displayedFacetIds; + + (function (uri) { + ERMrest.resolve(favoritesUri, ConfigUtils.getContextHeaderParams()).then(function (favoritesReference) { + // read favorites on reference + // TODO proper log object + return favoritesReference.contextualize.compact.read(rowCount, null, true, true); + }).then(function (favoritesPage) { + // if this is not the result of latest facet change + if (scope.reference.uri !== uri) { + defer.resolve(false); + return defer.promise; + } + + // find the favorite in the list of visible rows + favoritesPage.tuples.forEach(function (tuple) { + // should only be 1 + var matchedRow = scope.checkboxRows.filter(function (cbRow) { + if (cbRow.tuple) { + // tuple has data as table.name and user_id + // cbRow.tuple is the whole row of data with ermrest columns + return tuple.data[table.name] == cbRow.tuple.data[key.name] } + return false; }); - displayedFacetIds += ")" - // resolve favorites reference for this table with given user_id - var favoritesUri = $window.location.origin + table.favoritesPath + "/user_id=" + UriUtils.fixedEncodeURIComponent(scope.$root.session.client.id) + "&" + displayedFacetIds; - - ERMrest.resolve(favoritesUri, ConfigUtils.getContextHeaderParams()).then(function (favoritesReference) { - - // read favorites on reference - // use 10 since that's the max our facets will show at once - return favoritesReference.contextualize.compact.read(10); - }).then(function (favoritesPage) { - favoritesPage.tuples.forEach(function (tuple) { - // should only be 1 - var matchedRow = scope.checkboxRows.filter(function (cbRow) { - if (cbRow.tuple) { - // tuple has data as table.name and user_id - // cbRow.tuple is the whole row of data with ermrest columns - return tuple.data[table.name] == cbRow.tuple.data[key.name] - } - return false; - }); - matchedRow[0].isFavorite = true; - }); + matchedRow[0].isFavorite = true; + }); - defer.resolve(true); - }).catch(function (error) { - console.log(error); - defer.resolve(true) - }); - } else { - defer.resolve(true); - } - }).catch(function (err) { - defer.reject(err); + defer.resolve(true); + }).catch(function (error) { + console.log(error); + defer.resolve(true) }); })(scope.reference.uri); @@ -1468,6 +1505,8 @@ params.displayMode = recordsetDisplayModes.facetPopup; params.editable = false; + params.enableFavorites = scope.enableFavorites; + params.selectedRows = []; // generate list of rows needed for modal diff --git a/common/modal.js b/common/modal.js index 5fe6863fa..1261e50d0 100644 --- a/common/modal.js +++ b/common/modal.js @@ -355,6 +355,7 @@ hideNotNullChoice: params.hideNotNullChoice, hideNullChoice: params.hideNullChoice, displayMode: params.displayMode ? params.displayMode : recordsetDisplayModes.popup, + enableFavorites: params.enableFavorites ? params.enableFavorites : false }, getDisabledTuples: params.getDisabledTuples, diff --git a/common/table.js b/common/table.js index 18a9f3fce..1c6c0931a 100644 --- a/common/table.js +++ b/common/table.js @@ -1022,20 +1022,9 @@ * @param {object} scope the scope object */ function registerFavoritesCallbacks(scope, elem, attrs) { - scope.canFavorite = function (tuple, value) { - // NOTE: When a value comes back from the modal, we are dropping the tuple object - // and creating a new one with basic filter information that no longer has the tuple - // or other relevent information like table - // Maybe list directive should have the table (or reference) available - if (!(tuple && tuple.reference && tuple.reference.table) || !scope.$root.session) return false; - return tuple.reference.table.favoritesPath; - } - - scope.toggleFavorite = function (tuple, isFavorite) { - // tuple can get all information about the row and create a request to favorite the term + scope.toggleFavorite = function (tupleData, favoriteTable,isFavorite) { var defer = $q.defer(); - var favoriteTable = tuple.reference.table; var favoriteTablePath = favoriteTable.favoritesPath; // TODO: show spinning wheel and disable star @@ -1049,7 +1038,7 @@ // assumption that the data to store in above mentioned column is the value of the id column // assupmtion that the column to store the user information is the user_id column // TODO: add all three to config language - favoriteRow[favoriteTable.name] = tuple.data.id + favoriteRow[favoriteTable.name] = tupleData.id favoriteRow.user_id = scope.$root.session.client.id; // TODO pass proper log object @@ -1073,7 +1062,7 @@ // assumption that the data to associate for delete in above mentioned column is the value of the id column // assupmtion that the column to delete the user information is the user_id column // TODO: add all three to config language - var deleteFavoritePath = $window.location.origin + favoriteTablePath + "/" + UriUtils.fixedEncodeURIComponent(favoriteTable.name) + "=" + UriUtils.fixedEncodeURIComponent(tuple.data.id) + "&user_id=" + UriUtils.fixedEncodeURIComponent(scope.$root.session.client.id); + var deleteFavoritePath = $window.location.origin + favoriteTablePath + "/" + UriUtils.fixedEncodeURIComponent(favoriteTable.name) + "=" + UriUtils.fixedEncodeURIComponent(tupleData.id) + "&user_id=" + UriUtils.fixedEncodeURIComponent(scope.$root.session.client.id); // if favorited, delete it ERMrest.resolve(deleteFavoritePath, ConfigUtils.getContextHeaderParams()).then(function (favoriteReference) { // delete the favorite @@ -2251,7 +2240,9 @@ scope: { initialized: '=?', onRowClick: '=', - rows: '=' // each row: {uniqueId, displayname, count, selected} + rows: '=', // each row: {uniqueId, displayname, count, selected} + enableFavorites: "=?", + table: "=?" }, link: function (scope, elem, attr) { scope.defaultDisplayname = defaultDisplayname; @@ -2268,7 +2259,7 @@ if (row.isFavoriteLoading) return; row.isFavoriteLoading = true; - scope.toggleFavorite(row.tuple, row.isFavorite).then(function (isFavorite) { + scope.toggleFavorite(row.tuple.data, scope.table, row.isFavorite).then(function (isFavorite) { row.isFavorite = isFavorite; row.isFavoriteLoading = false; @@ -2361,7 +2352,8 @@ ERMrest.resolve(favoritesUri, ConfigUtils.getContextHeaderParams()).then(function (favoritesReference) { // read favorites on reference // use 10 since that's the max our facets will show at once - return favoritesReference.contextualize.compact.read(scope.vm.pageLimit); + // TODO proper log object + return favoritesReference.contextualize.compact.read(scope.vm.pageLimit, null, true, true); }).then(function (favoritesPage) { favoritesPage.tuples.forEach(function (favTuple) { // should only be 1 diff --git a/common/templates/ellipsis.html b/common/templates/ellipsis.html index ce29af07e..a8ccfde37 100644 --- a/common/templates/ellipsis.html +++ b/common/templates/ellipsis.html @@ -5,11 +5,11 @@