Skip to content

Commit

Permalink
Refactor search engine into own endpoint (o19s#788)
Browse files Browse the repository at this point in the history
You can now reuse/archive/share a search endpoint across multiple tries/cases/teams.   Set it up once, forget it after that!
  • Loading branch information
epugh committed Oct 16, 2023
1 parent 4abd795 commit 34beb16
Show file tree
Hide file tree
Showing 160 changed files with 3,791 additions and 1,260 deletions.
6 changes: 3 additions & 3 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ AllCops:
- config/initializers/content_security_policy.rb
- test/support/json_response.rb

Capybara/ClickLinkOrButtonStyle:
Enabled: false # we aren't running system tests

Rails/I18nLocaleTexts:
Enabled: false # we are only english

Expand Down Expand Up @@ -43,9 +46,6 @@ Lint/MissingSuper:
Style/GuardClause:
Enabled: false # I don't like this one, so ignore it!




Rails:
Enabled: true

Expand Down
1 change: 1 addition & 0 deletions Dockerfile.prod
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ RUN gem install bundler:2.4.9

# Clean up Bundle
RUN bundle config set without 'development test'
RUN bundle config set deployment true
RUN bundle install && \
bundle clean --force && \
rm -rf /app/.bundle/cache && \
Expand Down
Binary file added app/assets/images/es-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/assets/images/os-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/assets/images/searchapi-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/assets/images/solr-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/assets/images/static-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/assets/images/vectara-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<div class="modal-header">
<button type="button" class="close" ng-click="ctrl.cancel()" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h3 class="modal-title">Archive This Search Endpoint for Later?</h3>
</div>
<div class="modal-body">
<p ng-show="ctrl.canDelete">You're about to put this search endpoint into deep freeze. You'll be able to unarchive it later through the "Archived Search Endpoints" filter in the Search Endpoint Listings.</p>
<p ng-hide="ctrl.canDelete">You do not have delete (and archive) permissions for search endpoints.</p>
<p ng-show="ctrl.canDelete && ctrl.notOwner()">
<div class="alert alert-warning" role="alert" ng-if="ctrl.canDelete && !ctrl.isOwnerOfSearchEndpoint()">
Only the owner of a search endpoint can restore it. You will take over ownership of this search endpoint from <i>{{ ctrl.theSearchEndpoint.ownerName}}</i> by archiving it.
</div>
</div>
<div class="modal-footer">
<button class="btn btn-danger" ng-show="ctrl.canDelete" ng-click="ctrl.ok()">Archive</button>
<button class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<a class="action-icon" ng-click="ctrl.openArchiveModal()">
<i
class="fa fa-archive"
aria-hidden="true"
title="Archive"
alt="Archive"
></i>
</a>
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
'use strict';

/*jshint latedef:false*/

angular.module('QuepidApp')
.controller('ArchiveSearchEndpointCtrl', [
'$scope',
'$uibModal',
'flash',
'searchEndpointSvc',
function (
$scope,
$uibModal,
flash,
searchEndpointSvc
) {
var ctrl = this;

ctrl.thisSearchEndpoint = $scope.thisSearchEndpoint;
ctrl.archiveSearchEndpoint = archiveSearchEndpoint;
ctrl.openArchiveModal = openArchiveModal;

function archiveSearchEndpoint() {
searchEndpointSvc.archiveSearchEndpoint(ctrl.thisSearchEndpoint).then(
function () {
flash.success = 'Search endpoint archived successfully.';
}, function (data) {
var message = 'Oooops! Could not archive the search endpoint. ';
message += data.message;
flash.error = message;
}
);
}

function openArchiveModal() {
var modalInstance = $uibModal.open({
templateUrl: 'archive_search_endpoint/_modal.html',
controller: 'ArchiveSearchEndpointModalInstanceCtrl',
controllerAs: 'ctrl',
resolve: {
theSearchEndpoint: function() {
return ctrl.thisSearchEndpoint;
}
}
});

modalInstance.result.then(function (archiveClicked) {
if( archiveClicked ){
ctrl.archiveSearchEndpoint();
}
});
}
}
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use strict';

angular.module('QuepidApp')
.directive('archiveSearchEndpoint', [
function () {
return {
restrict: 'E',
controller: 'ArchiveSearchEndpointCtrl',
controllerAs: 'ctrl',
templateUrl: 'archive_search_endpoint/archive_search_endpoint.html',
scope: {
thisSearchEndpoint: '=',
},
bindings: {
thisSearchEndpoint: '<',
}
};
}
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
'use strict';

angular.module('QuepidApp')
.controller('ArchiveSearchEndpointModalInstanceCtrl', [
'$rootScope',
'$uibModalInstance',
'theSearchEndpoint',
function ($rootScope, $uibModalInstance, theSearchEndpoint) {
var ctrl = this;

ctrl.theSearchEndpoint = theSearchEndpoint;
//ctrl.canDelete = false;
ctrl.canDelete = true; // hard code that anyone can delete ;-(

//$rootScope.$watch('currentUser', function() {
// if ( $rootScope.currentUser ) {
// ctrl.canDelete = $rootScope.currentUser.permissions.search_endpoint.delete;
// }
//});

ctrl.isOwnerOfSearchEndpoint = function() {
return ($rootScope.currentUser.id === ctrl.theSearchEndpoint.ownerId);
};

ctrl.ok = function () {
$uibModalInstance.close(true);
};

ctrl.cancel = function () {
$uibModalInstance.close(false);
};

}
]);
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ <h2>CSV</h2>

<ng-csv-import
class="import"
content="ctrl.snapshots.content"
content="content"
header="ctrl.snapshots.header"
header-visible="true"
separator="ctrl.snapshots.separator"
Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/components/judgements/_modal.html
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ <h3 class="modal-title">Judgements</h3>

<a class="btn btn-default pull-left" ng-click="ctrl.refreshRatingsFromBook()" ng-disabled="processingPrompt.inProgress || ctrl.populateBook || !ctrl.activeBookId || ctrl.share.acase.bookId !== ctrl.activeBookId" >
<i class="glyphicon glyphicon-refresh"></i>
Refresh ratings from book
Refresh ratings from book <i>{{ctrl.activeBookName}}
</a>

<button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ angular.module('QuepidApp')
};

ctrl.activeBookId = acase.bookId;
ctrl.activeBookName = acase.bookName;

$scope.processingPrompt = { inProgress: false, error: null};

Expand All @@ -60,8 +61,10 @@ angular.module('QuepidApp')

if (!book) {
ctrl.activeBookId = null;
ctrl.activeBookName = null;
} else {
ctrl.activeBookId = book.id;
ctrl.activeBookName = book.name;
}
ctrl.updateAssociatedBook = true;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<div class="item-box row">
<div class="col-xs-4">
<span class="search-endpoints-title">
<a ng-href="search_endpoints/{{ctrl.searchEndpoint.id}}" target="_self" class="action-icon">
{{ ctrl.searchEndpoint.name }}
</a>
</span>

<span class="item-actions">

<a ng-href="search_endpoints/{{ctrl.searchEndpoint.id}}/edit" target="_self" class="action-icon">
<i
class="fa fa-edit"
aria-hidden="true"
title="Edit"
alt="Edit"
></i>
</a>
<archive-search-endpoint this-search-endpoint="ctrl.searchEndpoint"></archive-search-endpoint>
</span>
</div>

<div class="col-xs-4">
<img ng-if="ctrl.searchEndpoint.searchEngine" ng-src="images/{{ ctrl.searchEndpoint.searchEngine }}-icon.png" width="32px" />
{{ ctrl.searchEndpoint.searchEngine }}
</div>

<div class="col-xs-4">
<i>Not Yet Implemented</i>
</div>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use strict';

/*jslint latedef:false*/

angular.module('QuepidApp')
.controller('SearchEndpointListingCtrl', [
'$scope',
function (
$scope
) {
var ctrl = this;
ctrl.searchEndpoint = $scope.searchEndpoint;
ctrl.team = $scope.team;

// Functions

}
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
'use strict';

angular.module('QuepidApp')
.directive('searchEndpointListing', [
function () {
return {
restrict: 'E',
controller: 'SearchEndpointListingCtrl',
controllerAs: 'ctrl',
templateUrl: 'search_endpoint_listing/search_endpoint_listing.html',
scope: {
searchEndpoint: '=',
team: '=',
},
};
}
]);
13 changes: 10 additions & 3 deletions app/assets/javascripts/components/share_scorer/_modal.html
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ <h4>Select a team to share this scorer with:</h4>
<h4>Already shared with:</h4>

<ul class="list-group">
<li class="list-group-item list-group-item-success" ng-repeat="team in ctrl.share.sharedTeams">
<li class="list-group-item list-group-item-success" ng-repeat="team in ctrl.share.sharedTeams" ng-class="{ active: team == ctrl.share.unselectedTeam }" ng-click="ctrl.unselectTeam(team)">
{{ team.name }}
</li>
</ul>
Expand All @@ -50,14 +50,21 @@ <h4>Already shared with:</h4>
<i class="fa fa-plus"></i>
Create a team
</a>

<button
class="btn btn-success"
ng-show="ctrl.canUpdateScorer && ctrl.share.selectedTeam"
ng-show="ctrl.canUpdateScorer && ctrl.share.selectedTeam && ctrl.share.action ==='select'"
ng-click="ctrl.ok()"
>
Share with {{ ctrl.share.selectedTeam.name }}
</button>
<button
class="btn btn-success"
ng-show="ctrl.canUpdateScorer && ctrl.share.unselectedTeam && ctrl.share.action ==='unselect'"
ng-click="ctrl.ok()"
>
Unshare from {{ ctrl.share.unselectedTeam.name }}
</button>

<button class="btn btn-default" ng-click="ctrl.cancel()">Cancel</button>
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,27 @@ angular.module('QuepidApp')
function(share) {
var scorerId = share.scorer.scorerId;
var team = share.selectedTeam;
if (share.action === 'select') {
team = share.selectedTeam;

teamSvc.shareScorer(team, scorerId)
.then(function() {
flash.success = 'Scorer shared with team successfully';
}, function(response) {
flash.error = response.data.message;
});
teamSvc.shareScorer(team, scorerId)
.then(function() {
flash.success = 'Scorer shared with team successfully.';
}, function() {
flash.error = 'Unable to share scorer with team.';
});
}
else {
team = share.unselectedTeam;
var scorer = share.scorer;

teamSvc.removeScorer(team, scorer)
.then(function() {
flash.success = 'Scorer unshared from team successfully.';
}, function() {
flash.error = 'Unable to unshare scorer from team.';
});
}
},
function() {
$log.info('INFO: Modal dismissed');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ angular.module('QuepidApp')
teams: [],
sharedTeams: [],
loading: true,
};
action: null,
unselectedTeam: null
};

var teamHasScorer = function(team, scorerId) {
return team.scorers.filter(function(e) {
Expand Down Expand Up @@ -65,7 +67,7 @@ angular.module('QuepidApp')
}
};

teamSvc.list()
teamSvc.listForSharing()
.then(function() {
angular.forEach(teamSvc.teams, function(team) {
addTeamToLists(team);
Expand All @@ -78,7 +80,14 @@ angular.module('QuepidApp')

ctrl.selectTeam = function(selectedTeam) {
ctrl.share.selectedTeam = selectedTeam;
ctrl.share.unselectedTeam = null;
ctrl.share.action = 'select';
};
ctrl.unselectTeam = function(selectedTeam) {
ctrl.share.selectedTeam = null;
ctrl.share.unselectedTeam = selectedTeam;
ctrl.share.action = 'unselect';
};

ctrl.ok = function () {
$uibModalInstance.close(ctrl.share);
Expand Down
6 changes: 3 additions & 3 deletions app/assets/javascripts/controllers/mainCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ angular.module('QuepidApp')
};

var getSearchEngine = function(tryNo) {
var sett = settingsSvc.editableSettings();
if (sett.hasOwnProperty('getTry')) {
var aTry = sett.getTry(tryNo);
var settings = settingsSvc.editableSettings();
if (settings.hasOwnProperty('getTry')) {
var aTry = settings.getTry(tryNo);
if (aTry) {
return aTry.searchUrl;
}
Expand Down
6 changes: 6 additions & 0 deletions app/assets/javascripts/controllers/queriesCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,12 @@ angular.module('QuepidApp')
// finished a batch run, log the result!
var caseNo = parseInt($routeParams.caseNo, 10);
var tryNo = parseInt($routeParams.tryNo, 10);

if (Object.keys($scope.queries.avgQuery.currentScore.queries).length === 0) {
// if we have no queries, then let's short circuit this. We don't need to
// record scores for cases with zero queries.
return;
}

if ( isNaN(tryNo) ) { // If we didn't specify a try, then we need to get the latest
caseSvc.get(caseNo)
Expand Down
Loading

0 comments on commit 34beb16

Please sign in to comment.