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

Assets 98996 #93

Merged
merged 18 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion blocks/gmo-campaign-details/gmo-campaign-details.css
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,7 @@ body {
&:first-child, &:nth-child(2) {
border-top: 2px solid #F4F4F4;
}
& .deliverable-name, .platforms {
& .deliverable-name, .platforms, .deliverable-type, .review-link, .kpi {
overflow: hidden;
text-overflow: ellipsis;
line-height: 16px;
Expand Down
117 changes: 43 additions & 74 deletions blocks/gmo-campaign-details/gmo-campaign-details.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { decorateIcons, readBlockConfig } from '../../scripts/lib-franklin.js';
import { getQueryVariable } from '../../scripts/shared.js';
import { getProgramInfo } from '../../scripts/graphql.js';
import { resolveMappings, filterArray, getProductMapping } from '../../scripts/shared-mappings.js';
import { checkBlankString } from '../gmo-campaign-list/gmo-campaign-list.js'
import { statusMappings, productMappings, typeMappings } from '../../scripts/shared-campaigns.js';
import { getBaseConfigPath } from '../../scripts/site-config.js';
import { searchAsset } from '../../scripts/assets.js';

let blockConfig;
const programName = getQueryVariable('programName');
const deliverableMappings = resolveMappings("getDeliverableTypeMapping");
//const productMappings = resolveMappings("getProductList");

export default async function decorate(block) {

const programData = await getProgramInfo(programName, "getProgramDetails");
const deliverables = await getProgramInfo(programName, "getProgramDeliverables");
const deliverables = getProgramInfo(programName, "getProgramDeliverables");

const p0TargetMarketArea = programData.data.programList.items[0].p0TargetMarketArea;
const p1TargetMarketArea = programData.data.programList.items[0].p1TargetMarketArea;
Expand All @@ -27,7 +29,6 @@ export default async function decorate(block) {

const targetMarketAreas = buildTargetMarketAreaList(p0TargetMarketArea,p1TargetMarketArea).outerHTML;

const products = buildProductList(program).outerHTML;
const audiences = buildAudienceList(program).outerHTML;
const date = formatDate(program.launchDate);
const artifactLinks = buildArtifactLinks(program).outerHTML;
Expand All @@ -44,10 +45,8 @@ export default async function decorate(block) {
<div class="header-title">
<div class="header-row1">
<span class="h1">${program.programName}</span>
${status}
</div>
${program.campaignName ? '<div class="header-row2"><span class="subtitle">' + program.campaignName + '</span></div> ': ""}
<div class="header-row3">
<div class="header-row2">
<span class="icon icon-calendar"></span>
<span class="date-tooltip">Launch date</span>
<span class="campaign-date">${date}</span>
Expand Down Expand Up @@ -138,7 +137,6 @@ export default async function decorate(block) {
</div>
<div class="card products">
<div class="card-heading h3">Products</div>
${products}
</div>
<div class="card scope inactive">
<div class="card-heading h3">Feature Scope</div>
Expand Down Expand Up @@ -190,7 +188,7 @@ export default async function decorate(block) {
</div>
</div>
`;

buildProductCard(program);
try {
const imageObject = await searchAsset(program.programName, program.campaignName);
insertImageIntoCampaignImg(block,imageObject);
Expand All @@ -217,7 +215,12 @@ export default async function decorate(block) {
decorateIcons(block);
buildFieldScopes('deliverable-type',uniqueDeliverableTypes, block);
buildFieldScopes('platforms',uniquePlatforms, block);
buildDeliverablesTable(deliverables, block);
const table = await buildTable(await deliverables).then(async (rows) => {
await decorateIcons(rows);
return rows;
})
const tableRoot = block.querySelector('.table-content');
tableRoot.appendChild(table);
buildStatus(program.status);
}

Expand All @@ -244,12 +247,6 @@ function insertImageIntoCampaignImg(block,imageObject) {
imgElement.alt = imageObject.imageAltText;
campaignImgDiv.appendChild(imgElement);
}
async function buildDeliverablesTable(deliverables, block) {
const rows = buildTable(deliverables)
const tableRoot = block.querySelector('.table-content');
decorateIcons(rows);
tableRoot.appendChild(rows);
}

function switchTab(tab) {
if (tab.classList.contains('active') || tab.classList.contains('tab-wrapper')) {
Expand All @@ -270,11 +267,11 @@ async function buildFieldScopes(scopeTypeId, scopes, block) {
return;
}
const scopesParent = block.querySelector(`#${scopeTypeId}.channel-scope-wrapper .tags-wrapper`);
scopes.forEach((scope) => {
scopes.forEach(async (scope) => {
if (scope == null || scope == undefined || scope == '') return;
const tag = document.createElement('div');
tag.classList.add('scope-tag');
tag.textContent = scope;
tag.textContent = await lookupType(scope);
scopesParent.appendChild(tag);
});
}
Expand Down Expand Up @@ -323,23 +320,15 @@ function createLI(li) {
return liItem;
}

function buildProductList(program) {
let product = checkBlankString(program.productOffering);
async function buildProductCard(program) {
const productMapping = await getProductMapping(program.productOffering);
const productList = document.createElement('div');
productList.classList.add('product', 'card-content');

// Ensure the product exists in the productMappings, otherwise use 'Not Available'
if (!productMappings[product]) {
product = 'Not Available';
}

const productName = productMappings[product].name;
const productLabel = productMappings[product].icon;
productList.innerHTML = `
<span class="icon icon-${productLabel}"></span>
${productName}
<img class="icon" src=${productMapping.icon}></img>
${productMapping.label}
`
return productList;
document.querySelector('.card.products').appendChild(productList);
}

function buildAudienceList(program) {
Expand Down Expand Up @@ -381,11 +370,9 @@ function buildArtifactLinks(program) {
async function buildStatus(status) {
const statusDiv = document.createElement('div');
statusDiv.classList.add('campaign-status');
const statusJson = await getProgramInfo(programName, "getStatusList")
// use new function that doesn't require programname
const statusArray = statusJson.data.jsonByPath.item.json.options;
const statusMatch = statusArray.filter(item => item.value === status);
const statusText = statusMatch.length > 0 ? statusMatch[0].text : status;
const statusArray = await resolveMappings("getStatusList");
const statusMatch = filterArray(statusArray, 'value', status);
const statusText = statusMatch ? statusMatch[0].text : status;
const statusHex = statusMatch[0]["color-code"];
statusDiv.textContent = statusText;
statusDiv.style.backgroundColor = "#" + statusHex;
Expand Down Expand Up @@ -422,13 +409,13 @@ function formatDate(dateString) {
return formattedDate;
}

function buildTable(jsonResponse) {
async function buildTable(jsonResponse) {
const deliverableList = jsonResponse.data.deliverableList.items;
const programKpi = jsonResponse.data.programList.items.primaryKpi;
const rows = document.createElement('div');
const uniqueCategories = getUniqueValues(deliverableList, 'deliverableType');
const uniqueCategories = getUniqueItems(deliverableList, 'deliverableType');
let emptyCategory = false;
uniqueCategories.forEach((category) => {
uniqueCategories.forEach(async (category) => {
// build header row
let headerRow;
const matchingCampaigns = deliverableList.filter(deliverable => deliverable.deliverableType === category);
Expand All @@ -437,22 +424,23 @@ function buildTable(jsonResponse) {
emptyCategory = true;
headerRow = rows;
} else {
headerRow = buildHeaderRow(category, 'header', false, matchCount);
headerRow = await buildHeaderRow(category, 'header', false, matchCount);
attachListener(headerRow);
rows.appendChild(headerRow);
}
matchingCampaigns.forEach((campaign) => {
const tableRow = buildTableRow(campaign, programKpi, !emptyCategory);
matchingCampaigns.forEach(async (campaign) => {
const tableRow = await buildTableRow(campaign, programKpi, !emptyCategory);
headerRow.appendChild(tableRow);
})
// sort grouped rows by date
if (!emptyCategory) {
dateSort(headerRow);
}
emptyCategory = false;
})
});
//sort the rows
sortRows(rows);
await decorateIcons(rows);
return rows;
}

Expand All @@ -465,48 +453,29 @@ function dateSort(parent) {
if (isNaN(dateA.getTime()) || isNaN(dateB.getTime())) {
return 0; // Move on if date is invalid
}

return dateA - dateB;
})

childNodes.forEach((node) => {
parent.appendChild(node);
})
}

function buildTableNoGroups(response) {
const deliverableList = response.data.deliverableList.items;
const programKpi = response.data.programList.items.primaryKpi;
const rows = document.createElement('div');
deliverableList.forEach((deliverable) => {
const tableRow = buildTableRow(deliverable, programKpi, false);
rows.appendChild(tableRow);
})
return rows;
}

function getUniqueValues(array, filterValue) {
const uniqueValues = new Set();
array.forEach(obj => {
uniqueValues.add(obj[filterValue]);
})
return Array.from(uniqueValues);
}

function lookupType(rawType) {
const typeLookup = typeMappings[rawType]?.name;
const deliverableTypeLabel = (typeLookup != undefined) ? typeLookup : deliverableJson.deliverableType;
return deliverableTypeLabel;
async function lookupType(rawType) {
const mappings = await deliverableMappings;
const typeMatch = mappings.filter(item => item.value === rawType);
const typeText = typeMatch.length > 0 ? typeMatch[0].text : rawType;
return typeText;
}

/**
* @param {string} category - String value of the category property
* @param {string} headerType - Type of header. Either 'category' or 'subcategory'
* @param {boolean} isInactive - Determines whether or not the header will be hidden initially
* @param {number} matchCount - Number of matching items, will display beside the label
*/
function buildHeaderRow(category, headerType, isInactive, matchCount) {
async function buildHeaderRow(category, headerType, isInactive, matchCount) {
//look up friendly name for deliverable type
const typeLabel = lookupType(category);
const typeLabel = await lookupType(category);
const headerRow = document.createElement('div');
headerRow.classList.add('row', 'collapsible', 'header');
let divopen;
Expand All @@ -526,9 +495,9 @@ function buildHeaderRow(category, headerType, isInactive, matchCount) {
return headerRow;
}

function buildTableRow(deliverableJson, kpi, createHidden) {
async function buildTableRow(deliverableJson, kpi, createHidden) {
//look up friendly name for deliverable type
const typeLabel = lookupType(deliverableJson.deliverableType);
const typeLabel = await lookupType(deliverableJson.deliverableType);
const dataRow = document.createElement('div');
dataRow.classList.add('row', 'datarow');
if (createHidden) dataRow.classList.add('inactive');
Expand All @@ -541,14 +510,14 @@ function buildTableRow(deliverableJson, kpi, createHidden) {
platformString = platformString.slice(0, -2);
dataRow.innerHTML = `
<div class='property table-column column1 deliverable-name'>${deliverableJson.deliverableName}</div>
<div class='property table-column column2'>${typeLabel}</div>
<div class='property table-column column2 deliverable-type'>${typeLabel}</div>
<div class='property table-column column3 platforms'>${platformString}</div>
<div class='property table-column column4'>
<div class='property table-column column4 review-link'>
<a href="${deliverableJson.reviewLink}" class="campaign-link" target="_blank">Review Link</a>
</div>
<div class='property table-column column5'>
</div>
<div class='property table-column column6'>${checkBlankString(kpi)}</div>
<div class='property table-column column6 kpi'>${checkBlankString(kpi)}</div>
<div class='property table-column column7 justify-center'>
<div class='status-wrapper'>
<div class='status-heading'>
Expand Down
39 changes: 12 additions & 27 deletions blocks/gmo-campaign-list/gmo-campaign-list.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { readBlockConfig } from '../../scripts/lib-franklin.js';
import { decorateIcons } from '../../scripts/lib-franklin.js';
import { graphqlAllCampaignsFilter, graphqlCampaignCount, generateFilterJSON, getMappingInfo } from '../../scripts/graphql.js';
import { productMappings, statusMappings } from '../../scripts/shared-campaigns.js'
import { getProductMapping } from '../../scripts/shared-mappings.js'
import { getBaseConfigPath } from '../../scripts/site-config.js';
import { searchAsset } from '../../scripts/assets.js';

Expand Down Expand Up @@ -72,7 +72,6 @@ document.addEventListener('gmoCampaignListBlock', async function() {

export default async function decorate(block, numPerPage = currentNumberPerPage, cursor = '', previousPage = false, nextPage = false, graphQLFilter = {}) {
if (blockConfig == undefined) blockConfig = readBlockConfig(block);

const campaignPaginatedResponse = await graphqlAllCampaignsFilter(numPerPage, cursor,graphQLFilter);
const campaigns = campaignPaginatedResponse.data.programPaginated.edges;
currentPageInfo = campaignPaginatedResponse.data.programPaginated.pageInfo;
Expand Down Expand Up @@ -100,7 +99,7 @@ export default async function decorate(block, numPerPage = currentNumberPerPage,
const listFooter = buildListFooter(campaignCount, numPerPage);

block.innerHTML = `
<div class="refresh-notification">Last refreshed date: TBD</div>
<div class="refresh-notification"></div>
<div class="list-container">
</div>`;
const listContainer = block.querySelector('.list-container');
Expand Down Expand Up @@ -188,8 +187,8 @@ async function buildCampaignList(campaigns, numPerPage) {
const campaignName = document.createElement('div');
campaignName.classList.add('campaign-name-wrapper', 'vertical-center');
campaignName.innerHTML = `
<div class='campaign-name-label'>${checkBlankString(campaign.node.programName)}</div>
<div class='campaign-name' data-property='campaign'>${checkBlankString(campaign.node.campaignName)}</div>
<div class='campaign-name-label' data-property='campaign'>${checkBlankString(campaign.node.programName)}</div>
<div class='campaign-name'>${checkBlankString(campaign.node.campaignName)}</div>
`
campaignInfoWrapper.appendChild(campaignIconLink);
campaignInfoWrapper.appendChild(campaignName);
Expand All @@ -208,7 +207,7 @@ async function buildCampaignList(campaigns, numPerPage) {
campaignLaunch.classList.add('column-3', 'campaign-launch-date', 'vertical-center');
campaignLaunch.dataset.property = 'launch';

const campaignProducts = buildProductsList(checkBlankString(campaign.node.productOffering));
const campaignProducts = await buildProduct(checkBlankString(campaign.node.productOffering));
campaignProducts.classList.add('column-4', 'vertical-center');

var campaignStatusWrapper = document.createElement('div');
Expand Down Expand Up @@ -239,31 +238,17 @@ function buildStatus(statusWrapper, campaign) {
return statusWrapper;
}

function buildProductsList(productList) {
const campaignProducts = document.createElement('div');
const productEl = buildProduct(productList);
campaignProducts.appendChild(productEl);
return campaignProducts;
}

function buildProduct(product) {
async function buildProduct(product) {
const productParent = document.createElement('div');
const productMapping = await getProductMapping(product);
const productEl = document.createElement('div');
productEl.classList.add('product-entry');

// Ensure the product exists in the productMappings, otherwise use 'Not Available'
if (!productMappings[product]) {
product = 'Not Available';
}

const productLabel = productMappings[product].name;
const productIcon = productMappings[product].icon;

productEl.innerHTML = `
<span class='icon icon-${productIcon}'></span>
<span class='product-label'>${productLabel}</span>
<img class='icon' src=${productMapping.icon}></img>
<span class='product-label'>${productMapping.label}</span>
`;

return productEl;
productParent.appendChild(productEl);
return productParent;
}

function buildListHeaders(headerConfig) {
Expand Down
File renamed without changes
Loading
Loading