Skip to content

Commit

Permalink
New requestMethod GET to get and show response
Browse files Browse the repository at this point in the history
  • Loading branch information
MattiasSp committed Sep 27, 2024
1 parent 769863d commit 786447a
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 4 deletions.
4 changes: 4 additions & 0 deletions scss/_infowindow.scss
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,10 @@
text-align: left;
}

.export-response-container {
margin: 0.5em 0.5em 0.5em 3.6em;
}

.toaster {
border-radius: 0.5em;
box-shadow: 0 0 8px #888;
Expand Down
16 changes: 15 additions & 1 deletion src/infowindow.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ let exportContainer;
let groupFooterContainer;
let sublists;
let subexports;
let subexportResponses;
let urvalElements;
let footerContainers;
let expandableContents;
Expand Down Expand Up @@ -203,6 +204,8 @@ function showSelectedList(selectionGroup) {
}
const subexportToAppend = subexports.get(selectionGroup);
exportContainer.appendChild(subexportToAppend);
const subexportResponseToAppend = subexportResponses.get(selectionGroup);
exportContainer.appendChild(subexportResponseToAppend);
selectionManager.clearHighlightedFeatures();
selectionManager.refreshAllLayers();
urvalElements.forEach((value, key) => {
Expand Down Expand Up @@ -238,8 +241,18 @@ function createUrvalElement(selectionGroup, selectionGroupTitle) {
const footerContainer = document.createElement('div');
footerContainers.set(selectionGroup, footerContainer);

const subexportComponent = createSubexportComponent({ selectionGroup, viewer, exportOptions });
// Updates the response content for the given selectionGroup
const responseHandler = function responseHandler(responseSelectionGroup, text) {
const responseContainer = subexportResponses.get(responseSelectionGroup);
responseContainer.innerHTML = text;
};

const subexportComponent = createSubexportComponent({ selectionGroup, viewer, exportOptions, responseHandler });
subexports.set(selectionGroup, subexportComponent);

const subexportResponseComponent = document.createElement('div');
subexportResponseComponent.classList.add('export-response-container');
subexportResponses.set(selectionGroup, subexportResponseComponent);
}

function createExpandableContent(listElementContentContainer, content, elementId) {
Expand Down Expand Up @@ -427,6 +440,7 @@ function init(options) {
exportOptions = infowindowOptions.export || {};
sublists = new Map();
subexports = new Map();
subexportResponses = new Map();
urvalElements = new Map();
expandableContents = new Map();
footerContainers = new Map();
Expand Down
61 changes: 58 additions & 3 deletions src/infowindow_exporthandler.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,45 @@ export function simpleExportHandler(simpleExportUrl, activeLayer, selectedItems,
});
}

/**
* Makes a HEAD request to find out what the content type of the response will be, so that the
* response can be handled accordingly. Non-images will be blocked by CORS restrictions unless
* the server/API is set to allow the client's origin.
* @param {string} url The url to fetch
* @returns {Promise<string>} HTML content containing the response
*/
async function fetchByContentTypes(url) {
try {
// Perform the HEAD request to check response content type
const headResponse = await fetch(url, { method: 'HEAD' });
if (!headResponse.ok) {
throw new Error(`HEAD request failed with status: ${headResponse.status}`);
}
// Get the content-type header
const contentType = headResponse.headers.get('Content-Type');

// Generate content to display based on Content-Type
if (contentType.startsWith('image/')) {
return `<img class="pointer" src="${url}"></img>`;
} else if (contentType.startsWith('text/plain') || contentType.startsWith('application/json')) {
const getResponse = await fetch(url, { method: 'GET' });
if (!getResponse.ok) {
throw new Error(`GET request failed with status: ${getResponse.status}`);
}
const responseText = await getResponse.text();
if (contentType.startsWith('text/plain')) {
return `<span>${responseText}</span>`;
} else if (contentType.startsWith('application/json')) {
return `<pre><code>${responseText}</code></pre>`;
}
}
return '<span>Unsupported response Content-Type</span>';
} catch (err) {
console.error(err);
throw err;
}
}

export function layerSpecificExportHandler(url, requestMethod, urlParameters, activeLayer, selectedItems, attributesToSendToExport, exportedFileName) {
if (!url) {
throw new Error('Export URL is not specified.');
Expand Down Expand Up @@ -108,6 +147,8 @@ export function layerSpecificExportHandler(url, requestMethod, urlParameters, ac

if (requestMethod === 'OPEN') {
return window.open(requestUrl, '_blank') ? Promise.resolve() : Promise.reject();
} else if (requestMethod === 'GET') {
return fetchByContentTypes(requestUrl);
}
// eslint-disable-next-line consistent-return
return fetch(requestUrl, {
Expand Down Expand Up @@ -272,10 +313,12 @@ function createExportButtons(
urlParametersPerLayer,
attributesToSendToExportPerLayer,
exportedFileNamePerLayer,
displayExportResponsePerLayer,
selectionGroup,
activeLayer,
selectionManager,
exportOptions
exportOptions,
responseHandler
) {
const roundButton = obj.button.roundButton || false;
const buttonText = obj.button.buttonText || defaultText;
Expand All @@ -284,6 +327,12 @@ function createExportButtons(
const urlParameters = obj.urlParameters || urlParametersPerLayer;
const attributesToSendToExport = obj.attributesToSendToExport || attributesToSendToExportPerLayer;
const exportedFileName = obj.exportedFileName || exportedFileNamePerLayer;
const displayExportResponse = obj.displayExportResponse || displayExportResponsePerLayer || false;
// No point in creating a button that will make unnecessary GET requests
if (requestMethod === 'GET' && !displayExportResponse) {
console.warn('Skipping button for GET request with nothing to display.');
return '';
}
const exportBtn = roundButton
? createCustomExportButton(
obj.button.roundButtonIcon || defaultIcon,
Expand Down Expand Up @@ -319,6 +368,9 @@ function createExportButtons(
default:
break;
}
if (requestMethod === 'GET') {
responseHandler(selectionGroup, data);
}
}
btn.loadStop();
})
Expand All @@ -331,7 +383,7 @@ function createExportButtons(
return exportBtn;
}

export function createSubexportComponent({ selectionGroup, viewer, exportOptions }) {
export function createSubexportComponent({ selectionGroup, viewer, exportOptions, responseHandler }) {
viewerId = viewer.getId();
const selectionManager = viewer.getSelectionManager();
// OBS! selectionGroup corresponds to a layer with the same name in most cases, but in case of a group layer it can contain selected items from all the layers in that GroupLayer.
Expand All @@ -352,6 +404,7 @@ export function createSubexportComponent({ selectionGroup, viewer, exportOptions
const urlParametersPerLayer = layerSpecificExportOptions.urlParameters;
const attributesToSendToExportPerLayer = layerSpecificExportOptions.attributesToSendToExport;
const exportedFileNamePerLayer = layerSpecificExportOptions.exportedFileName;
const displayExportResponsePerLayer = layerSpecificExportOptions.displayExportResponse;

exportUrls.sort((exportUrl) => (exportUrl.button.roundButton ? -1 : 1))
.forEach((obj) => {
Expand All @@ -361,10 +414,12 @@ export function createSubexportComponent({ selectionGroup, viewer, exportOptions
urlParametersPerLayer,
attributesToSendToExportPerLayer,
exportedFileNamePerLayer,
displayExportResponsePerLayer,
selectionGroup,
activeLayer,
selectionManager,
exportOptions
exportOptions,
responseHandler
);
subexportContainer.appendChild(button);
});
Expand Down

0 comments on commit 786447a

Please sign in to comment.