Skip to content

Commit

Permalink
fix a bug in favorites where favorites would go out of sync
Browse files Browse the repository at this point in the history
after submitting the facet modal, the favorites would be wiped out.
This change will fix that
  • Loading branch information
RFSH committed Aug 27, 2021
1 parent 0f1215b commit 6420d29
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 70 deletions.
2 changes: 1 addition & 1 deletion common/ellipsis.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
129 changes: 84 additions & 45 deletions common/faceting.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand All @@ -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);
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -1468,6 +1505,8 @@
params.displayMode = recordsetDisplayModes.facetPopup;
params.editable = false;

params.enableFavorites = scope.enableFavorites;

params.selectedRows = [];

// generate list of rows needed for modal
Expand Down
1 change: 1 addition & 0 deletions common/modal.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,

Expand Down
26 changes: 9 additions & 17 deletions common/table.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down
6 changes: 3 additions & 3 deletions common/templates/ellipsis.html
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@
<div ng-switch-when="multi-select" class="chaise-checkbox">
<input type="checkbox" ng-checked="selected || selectDisabled" ng-click="onSelect($event)" ng-disabled="selectDisabled">
<label />
<span ng-if="isFavoriteLoading" class="favorite-icon favorite-spinner-container pull-right">
<span ng-if="config.enableFavorites && isFavoriteLoading" class="favorite-icon favorite-spinner-container pull-right">
<span class="glyphicon glyphicon-refresh glyphicon-refresh-animate"></span>
</span>
<span ng-if="!isFavoriteLoading && canFavorite(tuple) && tuple.isFavorite" class="favorite-icon glyphicon glyphicon-star pull-right" ng-click="callToggleFavorite()"></span>
<span ng-if="!isFavoriteLoading && canFavorite(tuple) && !tuple.isFavorite" class="favorite-icon hover-show glyphicon glyphicon-star-empty pull-right" ng-click="callToggleFavorite()"></span>
<span ng-if="config.enableFavorites && !isFavoriteLoading && tuple.isFavorite" class="favorite-icon glyphicon glyphicon-star pull-right" ng-click="callToggleFavorite()"></span>
<span ng-if="config.enableFavorites && !isFavoriteLoading && !tuple.isFavorite" class="favorite-icon hover-show glyphicon glyphicon-star-empty pull-right" ng-click="callToggleFavorite()"></span>
</div>
<div class="chaise-btn-group" ng-switch-default>
<a ng-if="applySavedQuery" class="apply-saved-query-button chaise-btn chaise-btn-tertiary chaise-btn-link icon-btn" ng-href="{{applySavedQuery}}" tooltip-placement="bottom" uib-tooltip="Apply search criteria">
Expand Down
2 changes: 1 addition & 1 deletion common/templates/faceting/choice-picker.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<chaise-search-input ng-show="showSearch"
input-class="facet-search-input" search-columns="searchColumns"
search-term="searchTerm" search-callback="search" disabled="facetColumn.hasNotNullFilter"></chaise-search-input>
<record-list rows='checkboxRows' on-row-click='onRowClick' initialized='facetModel.initialized && facetModel.isOpen && facetPanelOpen'></record-list>
<record-list rows='checkboxRows' on-row-click='onRowClick' initialized='facetModel.initialized && facetModel.isOpen && facetPanelOpen' enable-favorites="enableFavorites" table="reference.table"></record-list>
<button id="show-more" ng-click="openSearchPopup()" ng-disabled="facetColumn.hasNotNullFilter" class="chaise-btn chaise-btn-sm chaise-btn-tertiary pull-right show-more-btn">
<span class="chaise-btn-icon far fa-window-restore"></span>
<span ng-bind="hasMore || showFindMore ? 'Show More' : 'Show Details'"></span>
Expand Down
6 changes: 3 additions & 3 deletions common/templates/list.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
<label ng-if="row.displayname.value && !row.displayname.isHTML" ng-bind="row.displayname.value" tooltip-enable="tooltipEnabled" uib-tooltip="{{row.tooltip.value}}" tooltip-placement="bottom-left" chaise-enable-tooltip-width></label>
<label ng-if="row.displayname.value == ''" uib-tooltip-html="tooltip.empty" tooltip-placement="bottom-left" ng-bind-html="defaultDisplayname.empty"></label>
<label ng-if="row.displayname.value == null" class="chaise-icon-for-tooltip" uib-tooltip-html="tooltip.null" tooltip-placement="bottom-left" ng-bind-html="defaultDisplayname.null" style="padding-right: 2px;"></label>
<span ng-if="row.isFavoriteLoading" class="favorite-icon favorite-spinner-container pull-right">
<span ng-if="enableFavorites && row.isFavoriteLoading" class="favorite-icon favorite-spinner-container pull-right">
<span class="glyphicon glyphicon-refresh glyphicon-refresh-animate"></span>
</span>
<span ng-if="!row.isFavoriteLoading && canFavorite(row.tuple) && row.isFavorite" class="favorite-icon glyphicon glyphicon-star pull-right" ng-click="callToggleFavorite(row)"></span>
<span ng-if="!row.isFavoriteLoading && canFavorite(row.tuple) && !row.isFavorite" class="favorite-icon hover-show glyphicon glyphicon-star-empty pull-right" ng-click="callToggleFavorite(row)"></span>
<span ng-if="enableFavorites && !row.isFavoriteLoading && (!row.isNotNull && row.displayname.value != null) && row.isFavorite" class="favorite-icon glyphicon glyphicon-star pull-right" ng-click="callToggleFavorite(row)"></span>
<span ng-if="enableFavorites && !row.isFavoriteLoading && (!row.isNotNull && row.displayname.value != null) && !row.isFavorite" class="favorite-icon hover-show glyphicon glyphicon-star-empty pull-right" ng-click="callToggleFavorite(row)"></span>
</li>
</ul>

0 comments on commit 6420d29

Please sign in to comment.