Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ISSUE-463: The ADO to ADO JOIN filter #464

Open
wants to merge 20 commits into
base: 1.5.0
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
3f13235
Improve Ajax/Facet/Views update interactions & Controller
DiegoPino Aug 22, 2024
18386eb
WIP. Use the Ajax update View instead of the View trigger, when Facet…
DiegoPino Aug 22, 2024
ab773da
First attempt on updating arguments on other views that are not facet…
DiegoPino Aug 23, 2024
c777654
Dissallow RESET button to have AJAX behavior (breaking in better expo…
DiegoPino Sep 2, 2024
423233f
use new for 10.3 renderInIsolation()
DiegoPino Sep 2, 2024
cafe17d
In the case reset makes it to ajax, at least remove some of the argum…
DiegoPino Sep 2, 2024
d6e28fd
Adds #search/term reaction to Mirador to Match Bookreader one
DiegoPino Sep 4, 2024
527d9cd
Only act on fragment change on mirador if there is a new search
DiegoPino Sep 4, 2024
732cf40
First pass on ADO to ADO filter
DiegoPino Sep 9, 2024
fa0b3f4
Ok.. this adds an extra query element to the join so we can filter by…
DiegoPino Sep 10, 2024
4951d26
Make sure that "types" part of the query is OR
DiegoPino Sep 10, 2024
54e264e
Allow any View to opt out of setting (via Ajax) the Browser URL
DiegoPino Sep 10, 2024
8fc193e
Add a delay so we have time for a string update.
DiegoPino Sep 10, 2024
9b85aea
Join was omitting fields
DiegoPino Sep 12, 2024
adf755b
Allow the source NODE ID to be selected to
DiegoPino Sep 12, 2024
663ceea
Not sure why this is now complaining... mmm
DiegoPino Sep 12, 2024
11fa9bb
More consistent parsing of IIIF Info JSON for IABookreader page source
DiegoPino Sep 19, 2024
3942215
return the image itself if not matching IIIF component parts
DiegoPino Sep 19, 2024
1ed525c
Clean some code/routes we don't need anymore.
DiegoPino Sep 20, 2024
e5f16d9
Better logic for reset variabilty
DiegoPino Sep 27, 2024
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
8 changes: 5 additions & 3 deletions js/iiif-iabookreader_strawberry.js
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ BookReader.prototype.buildViewpageDiv = function(jViewpageDiv) {
var index = this.currentIndex();
//OLD//var tilesourceUri = this.getPageURI(index, 1, 0).replace(/full.*/, "info.json");
//var tilesourceUri = this.getPageProp(index, 'infojson');
var tilesourceUri = this.getPageURI(index, 1, 0).replace(/full.*/, "info.json") + getURLArgument(this.getPageURI(index, 1, 0));
var tilesourceUri = this.getIIIFInfoJsonFromURL(this.getPageURI(index, 1, 0)) ;
var dosd = $(osd_common.replace(/\[ID\]/g, "osd_s").replace('[TS]', tilesourceUri));
jViewpageDiv.html(dosd);
}
Expand All @@ -346,7 +346,8 @@ BookReader.prototype.buildViewpageDiv = function(jViewpageDiv) {
if (typeof this.getPageURI(indices[0], 1, 0) != 'undefined') {
//OLD//var tilesourceUri_left = this.getPageURI(indices[0], 1, 0).replace(/full.*/, "info.json");
//var tilesourceUri_left = this.getPageProp(indices[0], 'infojson');
var tilesourceUri_left = this.getPageURI(indices[0], 1, 0).replace(/full.*/, "info.json") + getURLArgument(this.getPageURI(indices[0], 1, 0));

var tilesourceUri_left = this.getIIIFInfoJsonFromURL(this.getPageURI(indices[0], 1, 0)) ;
var osd_left = osd_common.replace(/\[ID\]/g, "osd_l").replace('[TS]', tilesourceUri_left);
}
else {
Expand All @@ -358,7 +359,8 @@ BookReader.prototype.buildViewpageDiv = function(jViewpageDiv) {
if (typeof this.getPageURI(indices[1], 1, 0) != 'undefined') {
//OLD//var tilesourceUri_right = this.getPageURI(indices[1], 1, 0).replace(/full.*/, "info.json");
//var tilesourceUri_right = this.getPageProp(indices[1], 'infojson');
var tilesourceUri_right = this.getPageURI(indices[1], 1, 0).replace(/full.*/, "info.json") + getURLArgument(this.getPageURI(indices[1], 1, 0));

var tilesourceUri_right = this.getIIIFInfoJsonFromURL(this.getPageURI(indices[1], 1, 0)) ;
var osd_right = osd_common.replace(/\[ID\]/g, "osd_r").replace('[TS]', tilesourceUri_right);
}
else {
Expand Down
59 changes: 42 additions & 17 deletions js/mirador_strawberry.js
Original file line number Diff line number Diff line change
Expand Up @@ -281,13 +281,6 @@
);
}

// Build page parameter
const canvasIndices = visibleCanvases.map(c => canvasIds.indexOf(c) + 1)
if (view === 'single' || canvasIndices.length == 1) {
newParams.page = canvasIndices[0]
} else if (view === 'book') {
newParams.page = canvasIndices.find(e => !!e).join(',')
}
// Now at the end. If a VTT annotation requested a Canvas to be set. we need to check if we have in the config
// A temporary stored valued of the last clicked annotation.
// Use if here.
Expand All @@ -305,22 +298,33 @@
const { windowId, companionWindowId } = action
const query = yield effects.select(Mirador.selectors.getSearchQuery, { companionWindowId, windowId })
newParams.search = query
let $fragment = '';
for (const [p, val] of new URLSearchParams(newParams).entries()) {
$fragment += `${p}/${val}/`;
};
$fragment = $fragment.slice(0, -1);
history.replaceState(
{ searchParams: newParams },
'',
`${window.location.pathname}#${$fragment}`
);
}
else if (action.type === ActionTypes.REMOVE_SEARCH) {
delete newParams.search
let $fragment = '';
for (const [p, val] of new URLSearchParams(newParams).entries()) {
$fragment += `${p}/${val}/`;
};
$fragment = $fragment.slice(0, -1);
history.replaceState(
{ searchParams: newParams },
'',
`${window.location.pathname}#${$fragment}`
);
}

let $fragment = '';
for (const [p, val] of new URLSearchParams(newParams).entries()) {
$fragment += `${p}/${val}/`;
};
$fragment = $fragment.slice(0, -1);

history.replaceState(
{ searchParams: newParams },
'',
`${window.location.pathname}#${$fragment}`
);

}
function* rootSaga() {
yield effects.takeEvery(
Expand Down Expand Up @@ -403,6 +407,25 @@
$options.manifests = $manifests;
}

const readFragmentSearch = function() {
const urlArray = window.location.hash.replace('#','').split('/');
const urlHash = {};
for (let i = 0; i < urlArray.length; i += 2) {
urlHash[urlArray[i]] = urlArray[i + 1];
}
if (urlHash['search'] != undefined) {
return decodeURIComponent(urlHash['search'].replace(/\+/g, " "));
}
else {
return '';
}
};

const search_string = readFragmentSearch();
if (search_string.length > 0 ) {
$options.windows[0].defaultSearchQuery = search_string;
}

// Allow last minute overrides. These are more complex bc we have windows as an array and window too.
// Allow a last minute override, exclude main element manifest
if (typeof drupalSettings.format_strawberryfield.mirador[element_id]['viewer_overrides'] == 'object' &&
Expand Down Expand Up @@ -434,6 +457,8 @@
};
}



//@TODO add an extra Manifests key with every other one so people can select the others.
if (drupalSettings.format_strawberryfield.mirador[element_id]['custom_js'] == true) {
const miradorInstance = renderMirador($options);
Expand Down
34 changes: 33 additions & 1 deletion js/plugin.iiif-iabookreader_strawberry.js
Original file line number Diff line number Diff line change
Expand Up @@ -668,9 +668,41 @@ BookReader.prototype.parseSequence = function (sequenceId) {

return url.search
}

};



BookReader.prototype.getIIIFInfoJsonFromURL = function(string){
let url;

try {
url = new URL(string);
} catch (_) {
return '';
}
let path = url.pathname;
// IIIF will have id/crop/size/rotation/filename So we will split and reverse
if (path !== '/') {
let path_parts = path.split("/");
if (path_parts.length >= 5) {
path_parts = path_parts.reverse();
path_parts = path_parts.slice(4);
//reverse again
path_parts = path_parts.reverse();
path = path_parts.join('/') + '/info.json';
url.pathname = path;
return url.toString();
}
else {
// Might be non IIIF, so we return the Image itself.
return string;
}
}
else {
return string;
}
}

/**
* @param {number} index
* @return {Number|undefined}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,10 @@ function format_strawberryfield_views_views_data_alter(array &$data) {
'id' => 'sbf_flavors_join',
],
];
if ($sbf_join_field != 'sbf_flavors_join') {
$table[$sbf_join_field]['real field'] = 'sbf_flavors_join';
}

// @TODO add also an argument ID if relationships are enabled to
// $table[$advanced_fulltext_field]['argument']['id'] = 'sbf_advanced_search_api_fulltext';
// Requires a special Argument Plugin. Not needed right now.
Expand All @@ -208,6 +212,24 @@ function format_strawberryfield_views_views_data_alter(array &$data) {
if ($ado_filter != 'sbf_ado_filter') {
$table[$ado_filter]['real field'] = 'sbf_ado_filter';
}

$sbf_ado_join_field = _search_api_views_find_field_alias('sbf_ado_join', $table);
$table[$sbf_ado_join_field] = [
'title' => t('ADO(node) to ADO(node) Join'),
'group' => t('Search'),
'help' => t('Joins ADOs to ADOs when doing a Full Text Search.'),
'filter' => [
'title' => t('ADO(node) to ADO(node) Join'),
'field' => 'id',
'id' => 'sbf_ado_join',
],
];
if ($sbf_ado_join_field != 'sbf_ado_join') {
$table[$sbf_ado_join_field]['real field'] = 'sbf_ado_join';
}



}
catch (\Exception $e) {
$args = [
Expand Down Expand Up @@ -258,7 +280,7 @@ function format_strawberryfield_views_library_info_alter(&$libraries, $extension
function format_strawberryfield_views_views_pre_render(ViewExecutable $view) {
$current_display = $view->current_display;
$view_config = $view->storage->getDisplay($current_display);
if (!empty($view_config['display_options']['display_extenders']['sbf_ajax_interactions'] ?? NULL)) {
if (!empty($view_config['display_options']['display_extenders']['sbf_ajax_interactions'] ?? NULL) && !empty($view_config['display_options']['display_extenders']['sbf_ajax_interactions']['sbf_ajax_interactions_arguments'] ?? NULL)) {
if ($view_config['display_options']['display_extenders']['sbf_ajax_interactions']) {
$view->element['#attached']['library'][] = 'format_strawberryfield_views/view-ajax-interactions';
$view->element['#attached']['drupalSettings']['sbf_ajax_interactions'][$view->dom_id] = $view_config['display_options']['display_extenders']['sbf_ajax_interactions']['sbf_ajax_interactions_arguments'];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,3 @@ exposed_views_form_modal.block.ajax:
_controller: '\Drupal\format_strawberryfield_views\Controller\ViewsExposedFormModalBlockAjaxController::ajaxExposedFormBlockView'
requirements:
_access: 'TRUE'
format_strawberryfield_views.views.sajax:
path: '/sbf/views-ajax'
defaults:
_controller: '\Drupal\format_strawberryfield_views\Controller\FormatStrawberryfieldViewAjaxController::ajaxViewAdd'
requirements:
_access: 'TRUE'
65 changes: 50 additions & 15 deletions modules/format_strawberryfield_views/js/facets-views-ajax.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
// Loop through all facets.
$.each(settings.facets_views_ajax, function (facetId, facetSettings) {
// Get the View for the current facet.
var view, current_dom_id, view_path;
var view, current_dom_id, view_path, all_dom_ids_need_refresh = [];
if (settings.views && settings.views.ajaxViews) {
$.each(settings.views.ajaxViews, function (domId, viewSettings) {
// Check if we have facet for this view.
Expand All @@ -31,20 +31,37 @@
current_dom_id = viewSettings.view_dom_id;
view_path = facetSettings.ajax_path;
}
else {
// Means we don't have facets for this view, but we still might have a pager that needs to be reloaded, so it catches up with the Facet Query arguments.
const pagers = $('.js-view-dom-id-' + viewSettings.view_dom_id).find(
'.js-pager__items a, th.views-field a, .attachment .views-summary a',
);
if (typeof pagers !== "undefined" && pagers.length > 0) {
// means we have a pager
all_dom_ids_need_refresh.push(viewSettings.view_dom_id);
}
}
});
}

if (!view || view.length != 1) {
return;
}

all_dom_ids_need_refresh = Array.from(new Set(all_dom_ids_need_refresh));
// Update view on summary block click.
if (Drupal.AjaxFacetsView.updateFacetsSummaryBlock() && (facetId === 'facets_summary_ajax')) {
const elementsToAttach = once('summaryblock_attache', '[data-drupal-facets-summary-id=' + facetSettings.facets_summary_id + ']', context);
$(elementsToAttach).children('ul').children('li').click(function (e) {
e.preventDefault();
var facetLink = $(this).find('a');
// Note for myself here. Only the actual View that is targeted by the current Facet can use facetLink.attr('href')
// the other ones need to use the original URL cleaned up + the arguments of the facetLink.attr('href')
// This is needed since Facet URL generator will (for good reasons) the ?page=argument.
// And also is absolutely unaware of pagers with different names!
Drupal.AjaxFacetsView.UpdateView(facetLink.attr('href'), current_dom_id, view_path);
all_dom_ids_need_refresh.forEach((other_dom_id) => {
});

});
}
// Update view on facet item click.
Expand All @@ -54,7 +71,13 @@
$(facet_item).unbind('facets_filter.facets');
$(facet_item).on('facets_filter.facets', function (event, url) {
$('.js-facets-widget').trigger('facets_filtering');
// Note for myself here. Only the actual View that is targeted by the current Facet can use facetLink.attr('href')
// the other ones need to use the original URL cleaned up + the arguments of the facetLink.attr('href')
// This is needed since Facet URL generator will (for good reasons) the ?page=argument.
// And also is absolutely unaware of pagers with different names!
Drupal.AjaxFacetsView.UpdateView(url, current_dom_id, view_path);
all_dom_ids_need_refresh.forEach((other_dom_id) => {
});
});
}
});
Expand All @@ -68,29 +91,45 @@

Drupal.AjaxFacetsView.UpdateView = function (href, current_dom_id, view_path) {
// Refresh view.
if (typeof(Drupal.views.instances['views_dom_id:' + current_dom_id]) !== 'undefined') {
var atLeastone = false;
if (typeof(Drupal.views.instances['views_dom_id:' + current_dom_id]) !== 'undefined') {
atLeastone = true;
var views_parameters = Drupal.Views.parseQueryString(href);
let views_path = 'search';
if (Drupal.views.instances['views_dom_id:' + current_dom_id].settings.view_base_path !== 'undefined') {
views_path = Drupal.views.instances['views_dom_id:' + current_dom_id].settings.view_base_path;
}
var views_arguments = Drupal.Views.parseViewArgs(href, views_path);
var views_settings = $.extend(
const views_arguments = Drupal.Views.parseViewArgs(href, views_path);
const views_settings = $.extend(
{},
Drupal.views.instances['views_dom_id:' + current_dom_id].settings,
views_arguments,
views_parameters
);
// Not even needed here if we are using the original element settings ....mmmm
// Update View.
var views_ajax_settings = Drupal.views.instances['views_dom_id:' + current_dom_id].element_settings;
const views_ajax_settings = Drupal.views.instances['views_dom_id:' + current_dom_id].element_settings;
views_ajax_settings.submit = views_settings;
// Used to be the way in Drupal 9.x to 10.0 ... views_ajax_settings.url = view_path + '?q=' + href;
views_ajax_settings.url = view_path;

var viewRefreshAjaxObject = Drupal.ajax(views_ajax_settings);
const viewRefreshAjaxObject = Drupal.ajax(views_ajax_settings);
const success = viewRefreshAjaxObject.success();

viewRefreshAjaxObject.success = function (response, status) {
return Promise.resolve(
Drupal.Ajax.prototype.success.call(viewRefreshAjaxObject, response, status),
).then(() => {
Drupal.AjaxFacetsView.updateFacetsBlocks(href, views_settings.view_name, views_settings.view_display_id);
if (typeof(drupalSettings.format_strawberryfield_views) !== 'undefined') {
// Refresh facets blocks.
Drupal.updateModalViewsFormBlocks(href, views_settings.view_name, views_settings.view_display_id);
}
});
};
viewRefreshAjaxObject.execute();

}
if (atLeastone) {
// Update url.
window.historyInitiated = true;
window.history.pushState(null, document.title, href);
Expand All @@ -102,11 +141,6 @@
window.location.reload();
}
});
this.updateFacetsBlocks(href, views_settings.view_name, views_settings.view_display_id);
if (typeof(drupalSettings.format_strawberryfield_views) !== 'undefined') {
// Refresh facets blocks.
Drupal.updateModalViewsFormBlocks(href, views_settings.view_name, views_settings.view_display_id);
}
}
}
Drupal.AjaxFacetsView.updateFacetsBlocks = function (href, view_id, current_display_id) {
Expand All @@ -133,7 +167,6 @@

// Update facets summary block.
if (this.updateFacetsSummaryBlock()) {

var $facet_summary_wrapper = $('[data-drupal-facets-summary-id=' + settings.facets_views_ajax.facets_summary_ajax.facets_summary_id + ']');
if ($facet_summary_wrapper.length > 0) {
var facet_summary_wrapper_id = $facet_summary_wrapper.attr('id');
Expand All @@ -148,7 +181,9 @@
facet_settings.submit.facet_summary_wrapper_id = settings.facets_views_ajax.facets_summary_ajax.facets_summary_id;
}
}
Drupal.ajax(facet_settings).execute();
if (Object.keys(facet_settings.submit.facets_blocks).length > 0) {
Drupal.ajax(facet_settings).execute();
}
};

// Helper function to determine if we should update the summary block.
Expand Down
Loading