diff --git a/blocks/gmo-program-details/gmo-program-details.css b/blocks/gmo-program-details/gmo-program-details.css index 9f43a01..5c69faa 100644 --- a/blocks/gmo-program-details/gmo-program-details.css +++ b/blocks/gmo-program-details/gmo-program-details.css @@ -31,10 +31,12 @@ body { .gmo-program-details-wrapper { margin-top: 50px; + min-height: 400px; } .gmo-program-details.block { position: relative; + min-height: 400px; & .h1 { font: normal normal bold 18px/27px Adobe Clean; } @@ -48,6 +50,8 @@ body { font: normal normal normal 14px/21px Adobe Clean; } & > .main-body-wrapper { + min-height: 300px; + position: relative; display: flex; flex-direction: column; background: #FFFFFF; diff --git a/blocks/gmo-program-details/gmo-program-details.js b/blocks/gmo-program-details/gmo-program-details.js index 23ef08a..42efbb9 100644 --- a/blocks/gmo-program-details/gmo-program-details.js +++ b/blocks/gmo-program-details/gmo-program-details.js @@ -1,16 +1,20 @@ import { decorateIcons, readBlockConfig } from '../../scripts/lib-franklin.js'; import { executeQuery } from '../../scripts/graphql.js'; -import { filterArray, getProductMapping, checkBlankString, dateFormat, statusMapping, getMappingArray, showLoadingOverlay, hideLoadingOverlay } from '../../scripts/shared-program.js'; import { getBaseConfigPath } from '../../scripts/site-config.js'; import { searchAsset } from '../../scripts/assets.js'; +import { + filterArray, getProductMapping, checkBlankString, + dateFormat, statusMapping, getMappingArray, + showLoadingOverlay, hideLoadingOverlay, div, + span, img +} from '../../scripts/shared-program.js'; + let blockConfig; +let deliverableMappings, platformMappings, taskStatusMappings; const queryVars = extractQueryVars(); const programName = queryVars.programName; const programID = queryVars.programID; -const deliverableMappings = getMappingArray('deliverableType'); -const platformMappings = getMappingArray('platforms'); -const taskStatusMappings = getMappingArray('taskStatus'); const startDateProp = 'taskPlannedStartDate'; const endDateProp = 'taskPlannedEndDate'; let viewStart, viewEnd, calendarDeliverables; @@ -19,37 +23,228 @@ let viewStart, viewEnd, calendarDeliverables; const thumbnailCache = {}; export default async function decorate(block) { + blockConfig = readBlockConfig(block); + block.innerHTML = ` `; + + const currentYear = new Date().getFullYear(); + + const backButton = div({ class: 'back-button'}, span({ class: 'icon icon-back'}), span({ class: 'back-label'}, 'Back')); + const bodyWrapper = div({ class: 'main-body-wrapper'}); + const headerWrapper = div( + { class: 'details-header-wrapper'}, + div({ class: 'campaign-img'}), + div( + { class: 'header-title'}, + div({ class: 'header-row1'}, span({ class: 'h1'}, 'Loading details..')), + div( + { class: 'header-row2 header-row3'}, + div({ class: 'header-row3 data-element'}, + span({ class: 'icon icon-calendar'}), + span({ class: 'date-tooltip'}, 'Proposed Launch Date'), + span({ class: 'campaign-date'}, 'Loading details..'), + ), + span({ class: 'driver-text'}, 'Project Owner: Loading details..'), + div( + { class: 'header-row3 data-element'}, + span({ class: 'icon icon-release-tier'}), + span({ class: 'release-tier'}, 'Release Tier: Loading details..'), + ), + div( + { class: 'header-row3 data-element'}, + span({ class: 'icon icon-productGroup'}), + span({ class: 'productGroup'}, 'Loading details..'), + ), + ), + ), + ); + + // tab wrapper + const tabWrapper = div( + { class: 'tab-wrapper'}, + div({ id: 'tab1toggle', class: 'tabBtn active', 'data-target': 'tab1'}, 'Overview'), + div({ id: 'tab2toggle', class: 'tabBtn', 'data-target': 'tab2'}, 'Deliverables'), + div({ id: 'tab3toggle', class: 'tabBtn', 'data-target': 'tab3'}, 'Calendar'), + ); + + // overview tab + const overviewTab = div( + { id: 'tab1', class: 'two-column overview tab'}, + div( + { class: 'overview-wrapper'}, + span({ class: 'h1 overview-heading'}, 'At a Glance'), + div( + { class: 'product-overview-wrapper'}, + span({ class: 'h3'}, 'Marketing Goal'), + div({ class: 'overview paragraph hide-overflow'}, ' '), + div({ class: 'button no-bg read-more'}, 'Read more'), + ), + div( + { class: 'product-value-wrapper'}, + span({ class: 'h3'}, 'Product Value'), + div({ class: 'description paragraph hide-overflow'}, ' '), + div({ class: 'button no-bg read-more'}, 'Read more'), + ), + div( + { class: 'kpis-wrapper'}, + span({ class: 'h3'}, 'KPIs to Measure Success'), + ), + div( + { class: 'kpis-wrapper market-wrapper'}, + span({ class: 'h3'}, 'Target Market Area'), + ), + div( + { class: 'use-cases-wrapper inactive'}, + span({ class: 'h3'}, 'Hero Use Cases'), + div( + { class: 'tags-wrapper'}, + div({ class: 'use-case-tag'}, 'Text to Image'), + div({ class: 'use-case-tag'}, 'Use Case 2'), + ) + + ), + div( + { id: 'deliverable-type', class: 'channel-scope-wrapper'}, + span({ class: 'h3'}, 'Deliverable Type'), + div({ class: 'tags-wrapper'}), + ), + div( + { id: 'platforms', class: 'channel-scope-wrapper'}, + span({ class: 'h3'}, 'Platforms'), + div({ class: 'tags-wrapper'}), + ), + ), + div( + { class: 'infocards-wrapper'}, + div( + { class: 'card products'}, + div({ class: 'card-heading h3'}, 'Products'), + ), + div( + { class: 'card audiences'}, + div({ class: 'card-heading h3'}, 'Audiences'), + ) + ), + ); + + // deliverables tab + const deliverablesTab = div( + { id: 'tab2', class: 'deliverables tab inactive'}, + div( + { class: 'page-heading'}, + div( + { class: 'total-assets total-assets-tooltip' }, + div({ class: 'h3'}, 'Total Approved Assets'), + span({ id: 'totalassets', class: 'description'}, 'Not Available'), + span( + { class: 'tooltiptext'}, + 'To view the assets, go to the "All Asset" search page and use Program and Campaign name facet to filter the assets.', + ), + ), + ), + div( + { class: 'table-wrapper'}, + div( + { class: 'table-header' }, + div({ class: 'header table-column column1' }, 'Deliverable Task Name'), + div({ class: 'header table-column column2' }, 'Deliverable Type'), + div({ class: 'header table-column column3' }, 'Platforms'), + div({ class: 'header table-column column4' }, 'QA Files'), + div({ class: 'header table-column column5' }, 'Final Asset'), + div({ class: 'header table-column column7' }, 'Status Update'), + div({ class: 'header table-column column8' }, 'Completion Date'), + div({ class: 'header table-column column9' }, 'Task Owner'), + ), + div({ class: 'table-content' }), + ) + ); + + // calendar tab + const calendarTab = div( + { id: 'tab3', class: 'calendar tab inactive'}, + div( + { class: 'control-wrapper' }, + div( + { class: 'inc-dec-wrapper' }, + div( + { class: 'year-switch' }, + div( + { id: 'dec-year', class: 'year-toggle' }, + img( + { class: 'left', 'data-direction': 'left', src: '/icons/chevron-right.svg'}, + ), + ), + div( + { id: 'inc-year', class: 'year-toggle' }, + img( + { class: 'right', 'data-direction': 'right', src: '/icons/chevron-right.svg'}, + ), + ) + ), + div( + { class: 'current-year', 'data-quarter': '1', 'data-year': `${currentYear}` }, + `${currentYear}`, + ), + ), + div( + { class: 'right-controls' }, + div({ class: 'today-button' }, 'Today'), + div( + { class: 'filter-dropdown-wrapper' }, + div( + { class: 'filter-dropdown-button' }, + div({ class: 'label' }, 'Selected View: Year'), + span({ class: 'icon icon-chevronDown' }), + span({ class: 'icon icon-chevronUp inactive' }), + ), + ), + ), + ), + ); + + bodyWrapper.appendChild(headerWrapper); + bodyWrapper.appendChild(tabWrapper); + bodyWrapper.appendChild(overviewTab); + bodyWrapper.appendChild(deliverablesTab); + bodyWrapper.appendChild(calendarTab); + showLoadingOverlay(bodyWrapper); + block.appendChild(backButton); + block.appendChild(bodyWrapper); + decorateIcons(block); + + // add dynamic data + addProgramStats(block); + + // enable back button + enableBackBtn(block, blockConfig); +} + +async function addProgramStats(block) { + // mappings + deliverableMappings = getMappingArray('deliverableType'); + platformMappings = getMappingArray('platforms'); + taskStatusMappings = getMappingArray('taskStatus'); + + // main program data 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 deliverableQueryString = `getProgramDeliverables${encodedSemi}programName=${encodedProgram}${encodedSemi}programID=${encodeURIComponent(programID)}`; - - // Immediately render a placeholder header - block.innerHTML = ` -
-