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

Marketing Dashboard and Program Detail Optimization by adding the Content Fragment Path #165

Merged
merged 8 commits into from
Aug 29, 2024
71 changes: 47 additions & 24 deletions blocks/gmo-program-details/gmo-program-details.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,19 @@ const startDateProp = 'taskPlannedStartDate';
const endDateProp = 'taskPlannedEndDate';
let viewStart, viewEnd, calendarDeliverables;

// Thumbnail cache array object to store the image objects using cacheKey = `${programName}-${campaignName}-${deliverableType}`;
const thumbnailCache = {};

export default async function decorate(block) {
const encodedSemi = encodeURIComponent(';');
const encodedProgram = encodeURIComponent(programName);
const encodedPath = queryVars.path ? `${encodeURIComponent(queryVars.path)}` : '';

blockConfig = readBlockConfig(block);
// Including path in the query if present
const programQueryString = `getProgramDetails${encodedSemi}programName=${encodedProgram}${encodedSemi}programID=${encodeURIComponent(programID)}` +
(encodedPath ? `${encodedSemi}path=${encodedPath}` : '');

const programQueryString = `getProgramDetails${encodedSemi}programName=${encodedProgram}${encodedSemi}programID=${encodeURIComponent(programID)}`;
const deliverableQueryString = `getProgramDeliverables${encodedSemi}programName=${encodedProgram}${encodedSemi}programID=${encodeURIComponent(programID)}`;

// Immediately render a placeholder header
Expand Down Expand Up @@ -705,23 +711,26 @@ function attachListener(htmlElement) {

function extractQueryVars() {
const urlStr = window.location.href;
const pnRegex = /.*programName=(.*?)&programID=(.*)/;
const pnRegex = /[?&]programName=([^&]+)&programID=([^&]+)(&path=([^&]+))?/;
const match = urlStr.match(pnRegex);
if (match && match[1] && match[2]) {
const pName = decodeURIComponent(match[1]);
let pID = decodeURIComponent(match[2])
const pName = decodeURIComponent(match[1]); // Removed the replace method
let pID = decodeURIComponent(match[2]);
let pPath = match[4] ? decodeURIComponent(match[4]) : null;
if (pID.endsWith('#')) {
pID = pID.slice(0, -1);
}
return {
programName: pName,
programID: pID
}
programID: pID,
path: pPath
};
} else {
return {
programName: 'Program Name Not Available',
programID: 'Program ID Not Available'
}
programID: 'Program ID Not Available',
path: null
};
}
}

Expand Down Expand Up @@ -890,8 +899,9 @@ async function buildCalendar(dataObj, block, type, mappingArray, period) {
</div>
`;
itemEl.style.width = itemDurationPct + '%';
// Call the new function to fetch and add the thumbnail
addThumbnailToItem(itemEl, item.programName, item.campaignName,item.deliverableType);

// Call the new function to fetch and add the thumbnail, ensuring sequential execution
await addThumbnailToItem(itemEl, item.programName, item.campaignName,item.deliverableType);
itemWrapper.appendChild(itemEl);

};
Expand Down Expand Up @@ -1015,20 +1025,33 @@ async function getTaskStatusMapping(taskStatus) {
}

async function addThumbnailToItem(itemEl, programName, campaignName, deliverableType) {
try {
const imageObject = await searchAsset(programName, campaignName,deliverableType);
if (imageObject && imageObject.imageUrl) {
const thumbnailDiv = itemEl.querySelector('.thumbnail');
const imgElement = document.createElement('img');
imgElement.src = imageObject.imageUrl;
imgElement.alt = imageObject.imageAltText;
imgElement.loading = 'lazy';
thumbnailDiv.appendChild(imgElement);
} else {
console.error("Image Object does not have a valid imageUrl");
// Create a unique key for the cache based on the parameters, only add the campaignName in cacheKey when it is not null or empty
const cacheKey = campaignName ? `${programName}-${campaignName}-${deliverableType}` : `${programName}-${deliverableType}`;

// Check if the imageObject is already cached
let imageObject = thumbnailCache[cacheKey];

// If not cached, make the API call and store the result in the cache
if (!imageObject) {
try {
imageObject = await searchAsset(programName, campaignName, deliverableType);
thumbnailCache[cacheKey] = imageObject; // Store the result in the cache
} catch (error) {
console.error("Failed to load thumbnail image:", error);
return; // Exit the function if the API call fails
}
} catch (error) {
console.error("Failed to load thumbnail image:", error);
}

// Use the cached or newly fetched imageObject
if (imageObject && imageObject.imageUrl) {
const thumbnailDiv = itemEl.querySelector('.thumbnail');
const imgElement = document.createElement('img');
imgElement.src = imageObject.imageUrl;
imgElement.alt = imageObject.imageAltText;
imgElement.loading = 'lazy';
thumbnailDiv.appendChild(imgElement);
} else {
console.error("Image Object does not have a valid imageUrl");
}
}

Expand Down Expand Up @@ -1367,4 +1390,4 @@ function calculateScroll(type, viewStartYear, displayYear, displayQuarter, numYe

function isValidDate(dateObj) {
return dateObj instanceof Date && !isNaN(dateObj);
}
}
6 changes: 3 additions & 3 deletions blocks/gmo-program-list/gmo-program-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,7 @@ async function buildCampaignList(campaigns, numPerPage) {
const programName = campaign.node.programName;
const campaignName = campaign.node.campaignName;
const programID = campaign.node.programID ? campaign.node.programID : "";
const path = campaign.node._path;

campaignRow.classList.add('campaign-row');
if ((index + 1) > numPerPage) campaignRow.classList.add('hidden');
Expand All @@ -190,9 +191,9 @@ async function buildCampaignList(campaigns, numPerPage) {

const campaignIconLink = document.createElement('a');
let campaignDetailsLink = host + `/${detailsPage}?programName=${programName}&`;
campaignDetailsLink += `programID=${programID}`
campaignDetailsLink += `programID=${programID}`;
campaignDetailsLink += `&path=${path}`;
campaignIconLink.href = campaignDetailsLink;

const campaignIcon = document.createElement('div');
campaignIcon.classList.add('campaign-icon');
campaignIcon.dataset.programname = programName;
Expand All @@ -203,7 +204,6 @@ async function buildCampaignList(campaigns, numPerPage) {
const campaignNameWrapper = document.createElement('div');
campaignNameWrapper.classList.add('campaign-name-wrapper', 'vertical-center');


campaignNameWrapper.innerHTML = `
<div class='campaign-name-label' data-property='campaign'>
${checkBlankString(programName)}
Expand Down
14 changes: 14 additions & 0 deletions scripts/graphql.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ export async function graphqlAllCampaignsFilter(first,cursor,filter) {
const encodedCursor = encodeURIComponent(cursor);
const encodedFilter = encodeURIComponent(JSON.stringify(filter));
const graphqlEndpoint = `${baseApiUrl}/${projectId}/${queryName}${encodedSemiColon}first=${encodedFirst}${encodedSemiColon}cursor=${encodedCursor}${encodedSemiColon}filter=${encodedFilter}`;
//Performance logging
const startTime = performance.now();
const jwtToken = await getBearerToken();

try {
Expand All @@ -57,6 +59,11 @@ export async function graphqlAllCampaignsFilter(first,cursor,filter) {
},
};
const response = await fetch(`${graphqlEndpoint}`, options);
//Performance logging
const endTime = performance.now();
const executionTime = endTime - startTime;
console.debug(`getAllCampaigns Execution Time: ${executionTime} ms`);

// Handle response codes
if (response.status === 200) {
const responseBody = await response.json();
Expand Down Expand Up @@ -170,6 +177,8 @@ export async function executeQuery(queryString) {
const baseApiUrl = `${await getGraphqlEndpoint()}/graphql/execute.json`;
const projectId = 'gmo';
const queryEndpoint = `${baseApiUrl}/${projectId}/${queryString}`;
//Performance logging
const startTime = performance.now();
const jwtToken = await getBearerToken();

return fetch(queryEndpoint, {
Expand All @@ -181,6 +190,11 @@ export async function executeQuery(queryString) {
if (!response.ok) {
throw new Error(`HTTP error! Status: ${response.status}`);
}
//Performance logging
const endTime = performance.now();
const executionTime = endTime - startTime;
console.debug(`executeQuery for ${queryString} Execution Time: ${executionTime} ms`);

return response.json();
}).then(data => {
return data; // Make sure to return the data so that the promise resolves with it
Expand Down
Loading