import {
BannerBlockConfiguration,
BuildingBlockConfiguration,
PageConfigurationWithTransformedDynamicForms,
OverarchingDetailsBlockConfiguration,
PageConfiguration
} from '@allianz/taly-core/schemas';
import { transformJourneyToInternalJourney } from '../journey/transform/transform';
import { Journey } from '../model/journey';
type PageWithBlocks = PageConfigurationWithTransformedDynamicForms &
Required<Pick<PageConfigurationWithTransformedDynamicForms, 'blocks'>>;
interface BuildingBlockWithJourneyMetadata {
block: BuildingBlockConfiguration;
meta: {
onPages: { pageId: string; count: number }[];
count: number;
};
}
/**
* @param journey Journey configuration
* @returns An array of the unique Building Block selectors that are used in the given journey configuration
*/
export function getUniqueBuildingBlocks(journey: Journey): string[] {
const uniqueBuildingBlocks = new Set<string>();
getBuildingBlockConfigurations(journey).forEach((block) =>
uniqueBuildingBlocks.add(block.selector)
);
return Array.from(uniqueBuildingBlocks);
}
/**
* @param journey Journey configuration
* @returns An array of all building block configurations across all pages
*/
export function getBuildingBlockConfigurations(
journey: Journey
): (
| BuildingBlockConfiguration
| OverarchingDetailsBlockConfiguration
| BannerBlockConfiguration
)[] {
const transformedPagesConfiguration =
transformJourneyToInternalJourney(journey).pagesConfiguration;
const buildingBlocks = transformedPagesConfiguration.pages
.filter((page: PageConfiguration) => isPageWithBlocks(page))
.flatMap((page) => getAllBuildingBlocksInPage(page));
if (journey.pagesConfiguration.frame?.header?.actions?.length) {
buildingBlocks.push(...journey.pagesConfiguration.frame.header.actions);
}
return buildingBlocks;
}
/**
* @param page Page configuration
* @returns An array of all building block configurations in a page
*/
export function getAllBuildingBlocksInPage(
page: PageConfigurationWithTransformedDynamicForms
): (
| BuildingBlockConfiguration
| OverarchingDetailsBlockConfiguration
| BannerBlockConfiguration
)[] {
const result: (
| BuildingBlockConfiguration
| OverarchingDetailsBlockConfiguration
| BannerBlockConfiguration
)[] = [];
result.push(...(page.blocks ?? []));
if (page.overarchingDetailsBlock) {
result.push(page.overarchingDetailsBlock);
}
if (page.bannerBlock) {
result.push(page.bannerBlock);
}
return result;
}
/**
* @param journey Journey configuration
* @returns A map with building block selectors as keys and the count how often they are used in the journey as values
*/
export function getBuildingBlockUsageCounts(journey: Journey): Map<string, number> {
const usageCounts = new Map<string, number>();
getBuildingBlockConfigurations(journey).forEach((block) =>
usageCounts.set(block.selector, (usageCounts.get(block.selector) ?? 0) + 1)
);
return usageCounts;
}
/**
* @param journey Journey configuration
* @returns An Array with the Building Block libraries used within the journey.
*/
export function getBuildingBlockLibraries(journey: Journey): string[] {
const journeyPackages = new Set<string>();
getBuildingBlockConfigurations(journey).forEach((block) => journeyPackages.add(block.package));
return Array.from(journeyPackages);
}
/**
* @param journey Journey configuration
* @returns An Array with the libraries listed within the journey configuration.
*/
export function getJourneyPackages(journey: Journey): string[] {
const set = new Set(journey.pagesConfiguration.libraries.map((library) => library.package));
return [...set];
}
/**
* @param journey Journey configuration
* @returns An Array with {@link BuildingBlockWithJourneyMetadata} objects.
* Each object contains the building block configuration in the `block`
* property, and meta data on the building block inside the journey
* context (i.e. which pages the block is used on, and if it is global
* or local).
*/
export function getBuildingBlocksWithJourneyMetadata(
journey: Journey
): BuildingBlockWithJourneyMetadata[] {
const blocks: BuildingBlockWithJourneyMetadata[] = [];
const transformedPagesConfiguration =
transformJourneyToInternalJourney(journey).pagesConfiguration;
for (const page of transformedPagesConfiguration.pages) {
const allBlocks = getAllBuildingBlocksInPage(page) ?? [];
for (const block of allBlocks) {
let entryForBlock = blocks.find((entry) => entry.block.selector === block.selector);
if (!entryForBlock) {
entryForBlock = {
block,
meta: {
onPages: [],
count: 0
}
};
blocks.push(entryForBlock);
}
entryForBlock.meta.count++;
let onPagesEntry = entryForBlock?.meta.onPages.find((onPage) => onPage.pageId === page.id);
if (!onPagesEntry) {
onPagesEntry = {
pageId: page.id,
count: 0
};
entryForBlock?.meta.onPages.push(onPagesEntry);
}
onPagesEntry.count++;
}
}
return blocks;
}
function isPageWithBlocks(page: PageConfiguration): page is PageWithBlocks {
return Boolean(page.blocks) || Boolean(page.overarchingDetailsBlock) || Boolean(page.bannerBlock);
}