// (C) 2007-2021 GoodData Corporation import { flatMap, uniq } from "lodash"; import { format } from "date-fns"; import { ensureItems, ensureIdentifier } from "../helpers/objects"; import { elementUri } from "../../route/routes"; import { getProjectId } from "../../model/Project"; import { IElement } from "../../model/Element"; import { createAttributeIdentifier } from "./AttributeBuilder"; import { ISchema } from "../model/Schema"; import { createProject } from "./ProjectBuilder"; import { merge } from "../../utils/map"; import { createDateDataSet } from "./DateDataSetBuilder"; import { DateRange } from "../../utils/model/DateRange"; export type ElementMap = Map; function createAttributeElements(schema: ISchema): ElementMap { const project = createProject(schema); const groups = ensureItems(schema.groups); return flatMap(groups, group => ensureItems(group.attributes)).reduce((elementMap, attribute) => { const attributeId = ensureIdentifier(attribute, createAttributeIdentifier(attribute)); const elements = ensureItems(attribute.elements).map((title, i) => ({ element: { title, uri: elementUri(getProjectId(project), attributeId, `${i + 1}`), }, })); return elementMap.set(attributeId, elements); }, new Map()); } function getYearElements(dateRange: DateRange): string[] { const years = Array.from(dateRange.getDatesBetween()).map(date => date.getFullYear().toString()); return uniq(years); } function getMonthElements(dateRange: DateRange): string[] { const months = Array.from(dateRange.getDatesBetween()).map(date => format(date, "MMM YYYY")); return uniq(months); } function getQuarterElements(dateRange: DateRange): string[] { const quarters = Array.from(dateRange.getDatesBetween()).map(date => format(date, "[Q]Q/YYYY")); return uniq(quarters); } function getDateElements(dateRange: DateRange): string[] { const dates = Array.from(dateRange.getDatesBetween()).map(date => format(date, "MM-DD-YYYY")); return uniq(dates); } function getWeekUsElements(dateRange: DateRange): string[] { const weeks = Array.from(dateRange.getDatesBetween()).map(date => format(date, "[W]W/YYYY")); return uniq(weeks); } function createGenericDateValues(prefix: string, numberOfValues: number): string[] { return Array.from({ length: numberOfValues }, (_x, index) => `${prefix}${index + 1}`); } function getMonthInQuarterElements(): string[] { return createGenericDateValues("M", 3); } function getMonthInYearElements(): string[] { return ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]; } function getQuarterInYearElements(): string[] { return createGenericDateValues("Q", 4); } function getWeekUsInQuarterElements(): string[] { return createGenericDateValues("W", 14); } function getWeekUsInYearElements(): string[] { return createGenericDateValues("W", 53); } function getDayInWeekElements(): string[] { return ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]; } function getDayInMonthElements(): string[] { return createGenericDateValues("D", 31); } function getDayInQuarterElements(): string[] { return createGenericDateValues("D", 92); } function getDayInYearElements(): string[] { return createGenericDateValues("D", 366); } export function generateDateAttributeElementValues(type: string, dateRange: DateRange): string[] { if (type === "GDC.time.year") { return getYearElements(dateRange); } if (type === "GDC.time.month") { return getMonthElements(dateRange); } if (type === "GDC.time.month_in_quarter") { return getMonthInQuarterElements(); } if (type === "GDC.time.month_in_year") { return getMonthInYearElements(); } if (type === "GDC.time.quarter") { return getQuarterElements(dateRange); } if (type === "GDC.time.quarter_in_year") { return getQuarterInYearElements(); } if (type === "GDC.time.week_us") { return getWeekUsElements(dateRange); } if (type === "GDC.time.week_in_quarter") { return getWeekUsInQuarterElements(); } if (type === "GDC.time.week_in_year") { return getWeekUsInYearElements(); } if (type === "GDC.time.date") { return getDateElements(dateRange); } if (type === "GDC.time.date") { return getDateElements(dateRange); } if (type === "GDC.time.day_in_week") { return getDayInWeekElements(); } if (type === "GDC.time.day_in_month") { return getDayInMonthElements(); } if (type === "GDC.time.day_in_quarter") { return getDayInQuarterElements(); } if (type === "GDC.time.day_in_year") { return getDayInYearElements(); } return []; } function createDateAttributeElements(schema: ISchema): ElementMap { const project = createProject(schema); const groups = ensureItems(schema.groups); const dateDataSets = flatMap(groups, group => ensureItems(group.dateDataSets)); const map = new Map(); for (const dateDataSetSchema of dateDataSets) { const dateDataSet = createDateDataSet(project, dateDataSetSchema); const { startDate, finalDate } = dateDataSetSchema; for (const fragment of dateDataSet.availableDateAttributes) { const elementValues = generateDateAttributeElementValues( fragment.type, new DateRange(startDate, finalDate), ); const elements = elementValues.map( (value: string, i: number): IElement => ({ element: { title: value, uri: elementUri(getProjectId(project), fragment.meta.identifier, `${i + 1}`), }, }), ); map.set(fragment.meta.identifier, elements); } } return map; } export function createElementsMap(schema: ISchema): ElementMap { const attributeMap = createAttributeElements(schema); const dateMap = createDateAttributeElements(schema); return merge(attributeMap, dateMap); }