{ "version": 3, "sources": ["libs/integrated-search/tactics/shared/utils/src/enums/is-channel-overlap-recommendation.enum.ts", "libs/integrated-search/tactics/shared/utils/src/enums/is-optimisation-recommendation.enum.ts", "libs/integrated-search/tactics/shared/utils/src/enums/is-gaps-recommendation.enum.ts", "libs/integrated-search/tactics/shared/utils/src/configs/is-tactics-chart-defs.config.ts", "libs/integrated-search/tactics/shared/utils/src/consts/is-tactics-resource-path.const.ts", "libs/integrated-search/tactics/shared/utils/src/enums/is-tactics.enum.ts", "libs/integrated-search/tactics/shared/utils/src/enums/is-tactic-action.enum.ts", "libs/integrated-search/tactics/shared/utils/src/consts/is-tactics-chart-missing-data-message.const.ts", "libs/integrated-search/tactics/shared/utils/src/helpers/is-tactics-approvals.helper.ts", "libs/integrated-search/tactics/shared/utils/src/consts/is-tactic-performance-dictionary.const.ts", "libs/integrated-search/tactics/shared/utils/src/consts/is-tactics-tooltip-dictionary.const.ts", "libs/integrated-search/tactics/shared/utils/src/consts/is-tactics-recommendation-labels.const.ts", "libs/integrated-search/tactics/shared/utils/src/consts/is-tactics-approved-recommendations.const.ts", "libs/integrated-search/tactics/shared/utils/src/consts/is-tactic-action-message.const.ts", "libs/integrated-search/tactics/shared/utils/src/consts/is-tactics-chart-series.const.ts", "libs/integrated-search/tactics/shared/utils/src/consts/is-tactics-recommendations.const.ts", "libs/integrated-search/tactics/shared/utils/src/consts/is-competition-types-labels.const.ts", "libs/integrated-search/tactics/shared/utils/src/consts/is-search-term-difficulty-labels.const.ts", "libs/integrated-search/tactics/shared/utils/src/consts/is-tactics-keys.const.ts", "libs/integrated-search/tactics/shared/utils/src/helpers/is-tactics-chart-data.helper.ts", "libs/integrated-search/tactics/shared/utils/src/helpers/is-tactics-initial-chart-defs.helper.ts", "libs/integrated-search/tactics/shared/utils/src/helpers/is-tactics-campaign-tooltip.helper.ts"], "sourcesContent": ["export enum ISChannelOverlapRecommendationEnum {\n ADD_TO_NEGATIVES = 'ADD_TO_NEGATIVES',\n NONE = 'NO_RECOMMENDATION',\n ADDED_TO_NEGATIVES = 'ADDED_TO_NEGATIVES',\n}\n", "export enum ISOptimisationRecommendationEnum {\n CRITICAL = 'CRITICAL',\n IMPORTANT = 'IMPORTANT',\n MEDIUM = 'MEDIUM',\n NONE = 'NO_RECOMMENDATION',\n OPTIMISED = 'OPTIMISED',\n}\n", "export enum ISGapsRecommendationEnum {\n IMPROVE_SEO = 'IMPROVE_SEO',\n IMPROVE_PPC = 'IMPROVE_PPC',\n NONE = 'NO_RECOMMENDATION',\n OPTIMISED_SEO = 'OPTIMISED_SEO',\n OPTIMISED_PPC = 'OPTIMISED_PPC',\n}\n", "import { YAXisOption } from 'echarts/types/dist/shared';\n\nimport {\n IS_METRICS_LABELS,\n IS_METRICS_UNITS,\n ISMetricUnitEnum,\n ISNumericMetricEnum,\n} from '@ess/integrated-search/shared/utils';\nimport { SHARED_COLORS } from '@ess/shared/utils/consts';\nimport { essFormatDateHelper, essFormatNumber } from '@ess/shared/utils/helpers';\nimport { SharedChartOptions } from '@ess/shared/utils/models';\n\nimport { ISTacticChartSeries } from '../models';\n\nexport class ISTacticsChartDefsConfig {\n static readonly axesColors: string[] = [SHARED_COLORS.chart['50'], SHARED_COLORS.chart['400']];\n static readonly symbols = ['circle', 'diamond'];\n static readonly shapes: { [key: string]: string } = {\n circle: 'rounded-full',\n diamond: 'rotate-45',\n };\n\n static getTacticChartOptions(\n metrics: (ISTacticChartSeries | null)[],\n alignScales = true,\n currency?: string | null,\n missingDataWarning?: string | null,\n showTooltip?: boolean,\n ): SharedChartOptions {\n const yAxis = metrics\n .filter((_, index) => !(alignScales && this.isScaleAlignmentApplicable(metrics)) || index === 0)\n .map((metric, index) => {\n return this.__createYAxis(\n this.axesColors[index],\n metric ? IS_METRICS_UNITS[metric] : ISMetricUnitEnum.INTEGER,\n currency ?? undefined,\n !!metric,\n );\n });\n\n return {\n xAxis: {\n axisLabel: {\n formatter: (label: string) => essFormatDateHelper(label),\n },\n },\n yAxis,\n ...(showTooltip\n ? this.__getChartTooltip(currency ?? undefined, missingDataWarning)\n : { tooltip: { show: false } }),\n };\n }\n\n static isScaleAlignmentApplicable(metrics: (ISTacticChartSeries | null)[]): boolean {\n return !!metrics[0] && !!metrics[1] && IS_METRICS_UNITS[metrics[0]] === IS_METRICS_UNITS[metrics[1]];\n }\n\n private static __createYAxis(\n color: string,\n format: ISMetricUnitEnum = ISMetricUnitEnum.INTEGER,\n currency?: string,\n show = true,\n ): YAXisOption {\n return {\n type: 'value' as const,\n axisLabel: { color, formatter: this.__getValueFormatter(format, currency) },\n axisLine: { lineStyle: { color } },\n show,\n offset: 16,\n min: 0,\n max: (value: { min: number; max: number }) => {\n return value.max > 1 ? Math.ceil(value.max) : value.max;\n },\n };\n }\n\n private static __getValueFormatter(\n format: ISMetricUnitEnum = ISMetricUnitEnum.INTEGER,\n currencyCode?: string,\n ): (value: number) => string {\n switch (format) {\n case ISMetricUnitEnum.PERCENTAGE:\n return (value: number) =>\n essFormatNumber(value, {\n minimumIntegerDigits: 1,\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n style: 'percent',\n });\n case ISMetricUnitEnum.CURRENCY:\n return (value: number) =>\n essFormatNumber(value, {\n minimumIntegerDigits: 1,\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n style: 'currency',\n currencyDisplay: 'narrowSymbol',\n currency: currencyCode,\n });\n default:\n return (value: number) =>\n essFormatNumber(value, {\n minimumIntegerDigits: 1,\n minimumFractionDigits: 0,\n maximumFractionDigits: 2,\n });\n }\n }\n\n private static __getChartTooltip(currency?: string, missingDataWarning?: string | null): Partial {\n return {\n tooltip: {\n formatter: (params: any) => {\n let missingData = false;\n const series: TooltipSerie[] = (params as any[]).reduce((arr, serie) => {\n const metric: ISNumericMetricEnum = serie.seriesName;\n const unit: ISMetricUnitEnum = IS_METRICS_UNITS[metric] ?? ISMetricUnitEnum.INTEGER;\n const valueFn: (value: number | null) => string | null = (value: number | null) =>\n value !== null && value !== undefined ? this.__getValueFormatter(unit, currency)(value) : null;\n const name: string = IS_METRICS_LABELS[metric] ?? serie.seriesName;\n\n const marker: string =\n '
';\n\n missingData = missingData || serie.value === null || serie.value === undefined;\n\n return arr.concat({\n valueFn,\n name,\n marker,\n value: serie.value,\n });\n }, []);\n\n const date = essFormatDateHelper(params.name ?? params[0]?.name ?? '', {\n month: 'numeric',\n day: 'numeric',\n year: 'numeric',\n });\n\n return params.componentType === 'series' || params[0]?.componentType === 'series'\n ? `\n
\n

${date}

\n
`.concat(\n ...series.map(\n ({ name, value, valueFn, marker }) => `\n
\n
${marker}${name}
\n
${valueFn(value) ?? 'NO DATA'}
\n
\n `,\n ),\n '
',\n missingData && missingDataWarning\n ? `
\n ${missingDataWarning}\n
\n `\n : '',\n '
',\n )\n : '';\n },\n },\n };\n }\n}\n\ntype TooltipSerie = {\n valueFn: (value: number | null) => string | null;\n name: string;\n marker: string;\n value: number | null;\n};\n", "import { InjectionToken } from '@angular/core';\n\nimport { ISTacticsEnum } from '../enums';\n\nexport const IS_TACTICS_RESOURCE_PATH = new InjectionToken('ResourcePath');\n", "export enum ISTacticsEnum {\n CHANNEL_OVERLAP = 'channel-overlap',\n LANDING_PAGE_OPTIMISATION = 'landing-page-optimisation',\n SEARCH_GAPS = 'search-gaps',\n}\n", "export enum ISTacticActionEnum {\n IMPROVE_SEO = 'IMPROVE_SEO',\n IMPROVE_PPC = 'IMPROVE_PPC',\n ADD_TO_NEGATIVES = 'ADD_TO_NEGATIVES',\n REMOVE_FROM_NEGATIVES = 'REMOVE_FROM_NEGATIVES',\n}\n", "import { ISTacticsEnum } from '../enums';\n\nexport const IS_TACTICS_CHART_MISSING_DATA_MESSAGE: { [key in ISTacticsEnum]: string } = {\n [ISTacticsEnum.CHANNEL_OVERLAP]:\n 'The missing data is caused by extended processing times by Google or by lack of overlap to calculate. This is a common occurrence. Please select date ranges with complete data.',\n [ISTacticsEnum.SEARCH_GAPS]:\n 'The missing data is caused by extended processing times by Google. This is a common occurrence. Please select date ranges with complete data.',\n [ISTacticsEnum.LANDING_PAGE_OPTIMISATION]:\n 'The missing data is caused by extended processing times by Google. This is a common occurrence. Please select date ranges with complete data.',\n};\n", "import { SHARED_COLORS } from '@ess/shared/utils/consts';\nimport { essDaysDifference, essFormatDateToISO } from '@ess/shared/utils/helpers';\nimport {\n SharedChartInterval,\n SharedLineChartMarkPoint,\n SharedLineChartMarkPointData,\n SharedTimespan,\n} from '@ess/shared/utils/models';\n\nimport { ISApproval, ISApprovals, ISRecommendation } from '../models';\n\ninterface IntervalWithApprovals extends SharedChartInterval {\n approvals: ISApproval[];\n}\n\nexport class ISTacticsApprovalsHelper {\n static mapApprovalsToChartMarkPoint(\n approvals: ISApprovals[],\n timespan: SharedTimespan,\n ): SharedLineChartMarkPoint {\n const intervals: SharedChartInterval[] = this.__getIntervals(timespan);\n const sortedApprovals = approvals\n .filter((series) => series.recommendations.length > 0)\n .sort((a, b) => (a.date < b.date ? -1 : 1));\n sortedApprovals.forEach((a) => a.recommendations.forEach((r) => (r.date = a.date)));\n const intervalsWithApprovals: IntervalWithApprovals[] = intervals.map((interval) => {\n const lastFromInterval = sortedApprovals.findIndex((approval) => approval.date > interval.end);\n return {\n ...interval,\n approvals: sortedApprovals\n .splice(0, lastFromInterval >= 0 ? lastFromInterval : sortedApprovals.length)\n .flatMap((a) => a.recommendations)\n .map((r) => ({ ...r, interval })),\n };\n });\n\n return {\n data: intervalsWithApprovals\n .filter((i) => i.approvals.length > 0)\n .map((interval: IntervalWithApprovals) => ({\n value: interval.approvals.length,\n symbol: 'roundRect',\n symbolSize: 20,\n coord: [interval.approvals.length === 1 ? interval.approvals[0].date : interval.pointer, '0'],\n name: 'Recommendations approved',\n markPointData: interval.approvals,\n label: {\n color: SHARED_COLORS['neutral-variant']['900'],\n },\n itemStyle: {\n color: 'white',\n borderColor: SHARED_COLORS.priority.paused,\n borderWidth: 1,\n },\n emphasis: {\n itemStyle: {\n color: SHARED_COLORS.paused['50'],\n },\n label: {\n color: SHARED_COLORS['neutral-variant']['900'],\n },\n },\n })),\n };\n }\n\n private static __getIntervalLength(timespan: SharedTimespan): number {\n const range: number = essDaysDifference(new Date(timespan.start_date), new Date(timespan.end_date)) + 1;\n if (range <= 7) {\n return 1;\n } else if (range <= 31) {\n return 7;\n } else if (range <= 90) {\n return 14;\n } else if (range <= 180) {\n return 30;\n } else {\n return 60;\n }\n }\n\n private static __getIntervals(timespan: SharedTimespan): SharedChartInterval[] {\n const interval: number = this.__getIntervalLength(timespan);\n const pointerDate: Date = new Date(timespan.start_date);\n const endDate: Date = new Date(timespan.end_date);\n const intervals: SharedChartInterval[] = [];\n while (pointerDate.getTime() <= endDate.getTime()) {\n let end = new Date(pointerDate);\n end.setDate(end.getDate() + interval - 1);\n end = end.getTime() < endDate.getTime() ? end : new Date(endDate);\n const pointer = new Date(pointerDate);\n const middle = Math.floor(essDaysDifference(pointerDate, end) / 2);\n pointer.setDate(pointer.getDate() + middle);\n intervals.push({\n start: essFormatDateToISO(pointerDate),\n end: essFormatDateToISO(end),\n pointer: essFormatDateToISO(pointer),\n });\n pointerDate.setDate(pointerDate.getDate() + interval);\n }\n return intervals;\n }\n}\n", "import {\n ISChannelOverlapRecommendationEnum,\n ISGapsRecommendationEnum,\n ISOptimisationRecommendationEnum,\n ISTacticActionEnum,\n ISTacticsEnum,\n} from '../enums';\nimport { ISTacticPerformanceDictionary } from '../models';\n\nexport const IS_TACTIC_PERFORMANCE_DICTIONARY: ISTacticPerformanceDictionary = {\n [ISTacticsEnum.CHANNEL_OVERLAP]: {\n title: 'Search term performance',\n entityMetrics: 'Search term details',\n entitiesName: 'Search terms',\n button: {\n [ISTacticActionEnum.REMOVE_FROM_NEGATIVES]: 'Undo',\n default: 'Mark as added to negatives',\n },\n recommendation: {\n [ISChannelOverlapRecommendationEnum.ADD_TO_NEGATIVES]:\n 'SEO performance of this search term is good enough and PPC performance is costly or ineffective. It makes sense to consider adding this search term to negative keywords in Google Ads platform.\\n\\nThis recommendation is being done based on Channel Overlap tactic.',\n [ISChannelOverlapRecommendationEnum.NONE]:\n 'Both SEO and PPC performances of this search term are good enough and effective. There’s no need to add this search term to negative keywords, although you may still do it.\\n\\nThis recommendation is being done based on Channel Overlap tactic.',\n [ISChannelOverlapRecommendationEnum.ADDED_TO_NEGATIVES]:\n 'You have already added this search term to negative keywords.',\n },\n confirmation: {\n [ISTacticActionEnum.REMOVE_FROM_NEGATIVES]:\n \"Undo if you marked certain search term as added to negatives by mistake and/or haven't performed this action in Google Ads.\\n\\nNo record will be left in Integrated Search Dashboard afterwards. A recommendation will be displayed again for this search term.\",\n default:\n 'Approving this recommendation means that you agree to perform the action. You need to go to Google Ads platform in order to add this search term to negative keywords (we recommend to add it on account level as exact match).\\n\\nIn Integrated Search this moment will be marked and you will be able to track it.',\n },\n confirmationTitle: {\n [ISTacticActionEnum.REMOVE_FROM_NEGATIVES]: 'Are you sure you want to undo marking as added to negatives?',\n },\n tooltip: {\n [ISTacticActionEnum.REMOVE_FROM_NEGATIVES]: true,\n },\n action: {\n [ISChannelOverlapRecommendationEnum.ADD_TO_NEGATIVES]: ISTacticActionEnum.ADD_TO_NEGATIVES,\n [ISChannelOverlapRecommendationEnum.ADDED_TO_NEGATIVES]: ISTacticActionEnum.REMOVE_FROM_NEGATIVES,\n },\n primaryAction: ISTacticActionEnum.ADD_TO_NEGATIVES,\n entityActionPath: 'search-terms:action',\n },\n [ISTacticsEnum.LANDING_PAGE_OPTIMISATION]: {\n title: 'Keyword performance',\n entityMetrics: 'Keyword details',\n entitiesName: 'Keywords',\n button: {\n default: 'Mark as optimised',\n },\n recommendation: {\n [ISOptimisationRecommendationEnum.NONE]:\n 'Landing page experience for this keyword is above average or it was not specified in Google Ads. It does not make sense to consider optimising this keyword, although you may still do it.\\n\\nThis recommendation is being done based on Landing Page Optimisation tactic.',\n [ISOptimisationRecommendationEnum.OPTIMISED]: 'Landing page has been optimised for this keyword.',\n default:\n 'Landing page experience for this keyword is below average or average and ad cost share is meaningful. It makes sense to consider optimising landing page for this keyword.\\n\\nThis recommendation is being done based on Landing Page Optimisation tactic.',\n },\n confirmation: {\n default:\n 'Approving this recommendation means that this landing page has been already optimised for this keyword.\\n\\nIn Integrated Search this moment will be marked and you will be able to track it.',\n },\n entityActionPath: 'keywords:approve',\n },\n [ISTacticsEnum.SEARCH_GAPS]: {\n title: 'Search term performance',\n entityMetrics: 'Search term details',\n entitiesName: 'Search terms',\n button: {\n [ISTacticActionEnum.IMPROVE_PPC]: 'Mark as PPC improved',\n [ISTacticActionEnum.IMPROVE_SEO]: 'Mark as SEO improved',\n },\n recommendation: {\n [ISGapsRecommendationEnum.NONE]:\n \"Paid impressions share for this search term is above 5% and there's no need to consider improving SEO/PPC for this search term, although you may still do it.\\n\\nThis recommendation is being done based on Search Gaps tactic.\",\n [ISGapsRecommendationEnum.IMPROVE_PPC]:\n 'Combined impressions share is 5% or below and search term difficulty is high. It makes sense to consider PPC optimisation of this search term.\\n\\nThis recommendation is being done based on Search Gaps tactic.',\n [ISGapsRecommendationEnum.IMPROVE_SEO]:\n 'Combined impressions share is 5% or below and search term difficulty is low. It makes sense to consider SEO optimisation of this search term.\\n\\nThis recommendation is being done based on Search Gaps tactic.',\n [ISGapsRecommendationEnum.OPTIMISED_PPC]: 'You have already improved PPC of this search term.',\n [ISGapsRecommendationEnum.OPTIMISED_SEO]: 'You have already improved SEO of this search term.',\n },\n confirmation: {\n [ISTacticActionEnum.IMPROVE_PPC]:\n 'Approving this recommendation means that you agree to perform the action. You need to go to Google Ads platform in order to make proper changes.\\n\\nIn Integrated Search this moment will be marked and you will be able to track it.',\n [ISTacticActionEnum.IMPROVE_SEO]:\n 'Approving this recommendation means that you have already optimised SEO for this search term.\\n\\nIn Integrated Search this moment will be marked and you will be able to track it.',\n },\n action: {\n [ISGapsRecommendationEnum.IMPROVE_SEO]: ISTacticActionEnum.IMPROVE_SEO,\n [ISGapsRecommendationEnum.IMPROVE_PPC]: ISTacticActionEnum.IMPROVE_PPC,\n },\n primaryAction: ISTacticActionEnum.IMPROVE_SEO,\n secondaryAction: ISTacticActionEnum.IMPROVE_PPC,\n entityActionPath: 'search-terms:action',\n },\n};\n", "import { ISTacticsEnum } from '../enums';\nimport { ISTacticsTooltipDictionary } from '../models';\n\nexport const IS_TACTICS_TOOLTIP_DICTIONARY: ISTacticsTooltipDictionary = {\n [ISTacticsEnum.CHANNEL_OVERLAP]: {\n tactic:\n 'Channel Overlap tactic provides recommendations regarding adding search terms to negative keywords with high organic position and costly or ineffecive PPC performance.',\n timeFilter:\n 'By applying time filter, you’ll see only those search terms that existed in selected time range. This affects results in recommendation cards, charts and table.',\n },\n [ISTacticsEnum.LANDING_PAGE_OPTIMISATION]: {\n tactic:\n 'Landing Page Optimisation tactic provides recommendations regarding optimising pages for the keywords which 1. LP experience is below average or 2. LP experience is average and ad cost share is meaningful.',\n timeFilter:\n 'By applying time filter, you’ll see only those keywords that existed in selected time range. This affects results in recommendation cards, charts and table.',\n },\n [ISTacticsEnum.SEARCH_GAPS]: {\n tactic:\n 'Search Gaps tactic provides recommendations regarding optimising (SEO) or bidding (PPC) on certain search terms. Integrated search indicates the gap if Paid impressions share for given search term is 5% or lower.',\n timeFilter:\n 'By applying time filter, you’ll see only those search terms that existed in selected time range. This affects results in recommendation cards, charts and table.',\n },\n};\n", "import {\n ISChannelOverlapRecommendationEnum,\n ISGapsRecommendationEnum,\n ISOptimisationRecommendationEnum,\n} from '../enums';\n\nexport const IS_TACTICS_RECOMMENDATION_LABELS: { [key: string]: string } = {\n [ISChannelOverlapRecommendationEnum.ADD_TO_NEGATIVES]: 'Add to negatives',\n [ISChannelOverlapRecommendationEnum.ADDED_TO_NEGATIVES]: 'Added to negatives',\n [ISOptimisationRecommendationEnum.CRITICAL]: 'Critical to optimise',\n [ISOptimisationRecommendationEnum.IMPORTANT]: 'Important to optimise',\n [ISOptimisationRecommendationEnum.MEDIUM]: 'Medium need to optimise',\n [ISOptimisationRecommendationEnum.OPTIMISED]: 'Optimised',\n [ISGapsRecommendationEnum.IMPROVE_SEO]: 'Improve SEO',\n [ISGapsRecommendationEnum.IMPROVE_PPC]: 'Improve PPC',\n [ISGapsRecommendationEnum.OPTIMISED_SEO]: 'SEO improved',\n [ISGapsRecommendationEnum.OPTIMISED_PPC]: 'PPC improved',\n};\n", "import {\n ISChannelOverlapRecommendationEnum,\n ISGapsRecommendationEnum,\n ISOptimisationRecommendationEnum,\n} from '../enums';\nimport { ISRecommendation } from '../models';\n\nexport const IS_TACTICS_APPROVED_RECOMMENDATIONS: ISRecommendation[] = [\n ISChannelOverlapRecommendationEnum.ADDED_TO_NEGATIVES,\n ISOptimisationRecommendationEnum.OPTIMISED,\n ISGapsRecommendationEnum.OPTIMISED_PPC,\n ISGapsRecommendationEnum.OPTIMISED_SEO,\n];\n", "import { ISTacticActionEnum } from '../enums';\nimport { ISTacticActionMessage } from '../models';\n\nexport const IS_TACTIC_ACTION_MESSAGE: ISTacticActionMessage = {\n success: {\n [ISTacticActionEnum.REMOVE_FROM_NEGATIVES]: 'Action undone successfully.',\n },\n error: {\n [ISTacticActionEnum.REMOVE_FROM_NEGATIVES]: 'There were some problems. Please try again later.',\n },\n};\n", "import { ISMetricEnum } from '@ess/integrated-search/shared/utils';\n\nimport { ISTacticsEnum } from '../enums';\nimport { ISTacticChartSeries } from '../models';\n\nexport const IS_TACTICS_CHART_SERIES: { [key in ISTacticsEnum]: ISTacticChartSeries[] } = {\n [ISTacticsEnum.CHANNEL_OVERLAP]: [\n ISMetricEnum.COMBINED_IMPRESSIONS,\n ISMetricEnum.PPC_CONVERSION_RATE,\n ISMetricEnum.CONVERSIONS_VALUE,\n ISMetricEnum.PAID_IMPRESSIONS_SHARE,\n ISMetricEnum.PPC_CLICKS,\n ISMetricEnum.PPC_CONVERSIONS,\n ISMetricEnum.PPC_CPA,\n ISMetricEnum.PPC_CPC,\n ISMetricEnum.PPC_CTR,\n ISMetricEnum.PPC_IMPRESSIONS,\n ISMetricEnum.PPC_SPEND,\n ISMetricEnum.PPC_ROAS,\n ISMetricEnum.SEO_CLICKS,\n ISMetricEnum.SEO_CTR,\n ISMetricEnum.SEO_IMPRESSIONS,\n ISMetricEnum.SEO_POSITION,\n ISMetricEnum.MAX_IMPRESSIONS,\n ISMetricEnum.MAX_PAID_IMPRESSIONS_SHARE,\n ],\n [ISTacticsEnum.SEARCH_GAPS]: [\n // TODO - add when available\n // ISMetricEnum.CLICKS_COVERAGE,\n ISMetricEnum.COMBINED_IMPRESSIONS,\n ISMetricEnum.CONVERSIONS_VALUE,\n ISMetricEnum.PAID_IMPRESSIONS_SHARE,\n ISMetricEnum.PPC_IMPRESSIONS,\n ISMetricEnum.SEO_IMPRESSIONS,\n ISMetricEnum.SEO_POSITION,\n ISMetricEnum.MAX_IMPRESSIONS,\n ISMetricEnum.MAX_PAID_IMPRESSIONS_SHARE,\n ],\n [ISTacticsEnum.LANDING_PAGE_OPTIMISATION]: [\n // TODO: Uncomment when PPC_COST_SHARE metric is added\n // ISMetricEnum.PPC_COST_SHARE,\n ISMetricEnum.COMBINED_IMPRESSIONS,\n ISMetricEnum.PPC_CONVERSIONS,\n ISMetricEnum.CONVERSIONS_VALUE,\n ISMetricEnum.PPC_CTR,\n ISMetricEnum.PPC_IMPRESSIONS,\n ISMetricEnum.SEO_IMPRESSIONS,\n ISMetricEnum.PAID_IMPRESSIONS_SHARE,\n ISMetricEnum.PPC_CLICKS,\n ISMetricEnum.SEO_CLICKS,\n ISMetricEnum.PPC_CPC,\n ISMetricEnum.PPC_ROAS,\n ISMetricEnum.PPC_SPEND,\n ISMetricEnum.MAX_IMPRESSIONS,\n ISMetricEnum.MAX_PAID_IMPRESSIONS_SHARE,\n ],\n};\n", "import {\n ISChannelOverlapRecommendationEnum,\n ISGapsRecommendationEnum,\n ISOptimisationRecommendationEnum,\n ISTacticsEnum,\n} from '../enums';\nimport { ISRecommendation } from '../models';\n\nexport const IS_TACTICS_RECOMMENDATIONS: { [key in ISTacticsEnum]: ISRecommendation[] } = {\n [ISTacticsEnum.CHANNEL_OVERLAP]: Object.values(ISChannelOverlapRecommendationEnum),\n [ISTacticsEnum.SEARCH_GAPS]: Object.values(ISGapsRecommendationEnum),\n [ISTacticsEnum.LANDING_PAGE_OPTIMISATION]: Object.values(ISOptimisationRecommendationEnum),\n};\n", "import { ISCompetitionTypesEnum } from '@ess/integrated-search/shared/utils';\n\nexport const IS_COMPETITION_TYPES_LABELS: { [key in ISCompetitionTypesEnum]: string } = {\n [ISCompetitionTypesEnum.LOW]: 'Low',\n [ISCompetitionTypesEnum.MEDIUM]: 'Medium',\n [ISCompetitionTypesEnum.HIGH]: 'High',\n [ISCompetitionTypesEnum.UNSPECIFIED]: 'Unspecified',\n};\n", "import { ISSearchTermDifficultyTypesEnum } from '@ess/integrated-search/shared/utils';\n\nexport const IS_SEARCH_TERM_DIFFICULTY_LABELS: { [key in ISSearchTermDifficultyTypesEnum]: string } = {\n [ISSearchTermDifficultyTypesEnum.LOW]: 'Low',\n [ISSearchTermDifficultyTypesEnum.MEDIUM]: 'Medium',\n [ISSearchTermDifficultyTypesEnum.HIGH]: 'High',\n};\n", "import { ISTacticKey } from '@ess/integrated-search/shared/utils';\n\nimport { ISTacticsEnum } from '../enums';\n\nexport const IS_TACTICS_KEYS: { [key in ISTacticsEnum]: ISTacticKey } = {\n [ISTacticsEnum.CHANNEL_OVERLAP]: 'channelOverlap',\n [ISTacticsEnum.LANDING_PAGE_OPTIMISATION]: 'landingPageOptimisation',\n [ISTacticsEnum.SEARCH_GAPS]: 'searchGaps',\n};\n", "import { SharedChartTypeEnum } from '@ess/shared/utils/enums';\nimport { SharedChartData, SharedLineChartData, SharedLineChartSeries, SharedTimespan } from '@ess/shared/utils/models';\n\nimport { ISTacticsApprovalsHelper } from './is-tactics-approvals.helper';\n\nimport { ISTacticsChartDefsConfig } from '../configs';\nimport { IS_TACTICS_CHART_SERIES } from '../consts';\nimport { ISTacticsEnum } from '../enums';\nimport { ISApprovals, ISRecommendation, ISTacticChartSeries } from '../models';\n\nexport class ISTacticsChartDataHelper {\n static getChartSeriesForMetrics(\n alignScales = true,\n data?: SharedChartData | null,\n metrics?: (ISTacticChartSeries | null)[],\n ): SharedChartData | null {\n return data && metrics?.length\n ? {\n ...data,\n data: {\n ...data.data,\n series: this.__prepareChartSeries(data.data, metrics, alignScales),\n },\n }\n : (data ?? null);\n }\n\n static formatChartSeries(\n source: ISTacticsEnum,\n data: SharedLineChartData,\n approvals?: ISApprovals[],\n timespan?: SharedTimespan,\n ): SharedChartData {\n const chartData = {\n type: SharedChartTypeEnum.LINE,\n data: {\n series: IS_TACTICS_CHART_SERIES[source].reduce((acc, serie) => {\n const dataSerie = data.series.find((s) => s.name === serie);\n !!dataSerie && acc.push(dataSerie);\n return acc;\n }, []),\n categories: data.categories,\n },\n };\n\n if (approvals?.length && timespan) {\n const {\n data: { series },\n } = chartData;\n\n series.push({\n data: [],\n color: '',\n markPoint: ISTacticsApprovalsHelper.mapApprovalsToChartMarkPoint(approvals, timespan),\n });\n }\n return chartData;\n }\n\n private static __prepareChartSeries(\n data: SharedLineChartData,\n metrics: (ISTacticChartSeries | null)[],\n alignScales = true,\n ): SharedLineChartSeries[] {\n const series = data.series.filter((serie) => !serie.name || metrics.includes(serie.name as ISTacticChartSeries));\n\n series.sort((a, b) => {\n const indexA = metrics.indexOf(a.name as ISTacticChartSeries) ?? 0;\n const indexB = metrics.indexOf(b.name as ISTacticChartSeries) ?? 0;\n return indexA - indexB;\n });\n\n return series.map((serie) => {\n const metricIndex = metrics.indexOf(serie.name as ISTacticChartSeries) ?? 0;\n return {\n ...serie,\n ...(serie.name && {\n symbol: ISTacticsChartDefsConfig.symbols[metricIndex],\n yAxisIndex: alignScales && ISTacticsChartDefsConfig.isScaleAlignmentApplicable(metrics) ? 0 : metricIndex,\n itemStyle: { color: ISTacticsChartDefsConfig.axesColors[metricIndex] },\n lineStyle: { color: ISTacticsChartDefsConfig.axesColors[metricIndex] },\n id: ISTacticsChartDefsConfig.symbols[metricIndex] ?? serie.name,\n }),\n };\n });\n }\n}\n", "import { ISMetricEnum } from '@ess/integrated-search/shared/utils';\n\nimport { ISTacticMetricTabConfig, ISTacticMetricTabs } from '../models';\n\nexport class ISTacticsInitialChartDefsHelper {\n static getInitialState(projectId?: number): ISTacticMetricTabs {\n return {\n projectId: projectId ?? -1,\n channelOverlap: {\n tabs: ISTacticsInitialChartDefsHelper.getChannelOverlapTabs(),\n },\n landingPageOptimisation: {\n tabs: ISTacticsInitialChartDefsHelper.getLandingPageOptimisationTabs(),\n },\n searchGaps: {\n tabs: ISTacticsInitialChartDefsHelper.getSearchGapsTabs(),\n },\n };\n }\n\n static getChannelOverlapTabs(): ISTacticMetricTabConfig[] {\n return [\n {\n title: 'Traffic-focused',\n charts: [\n {\n title: 'Impressions',\n metric_1: ISMetricEnum.COMBINED_IMPRESSIONS,\n metric_2: ISMetricEnum.PAID_IMPRESSIONS_SHARE,\n alignScales: false,\n },\n {\n title: 'SEO Clicks',\n metric_1: ISMetricEnum.SEO_CLICKS,\n metric_2: ISMetricEnum.SEO_CTR,\n alignScales: false,\n },\n {\n title: 'PPC Clicks',\n metric_1: ISMetricEnum.PPC_CLICKS,\n metric_2: ISMetricEnum.PPC_CTR,\n alignScales: false,\n },\n ],\n },\n {\n title: 'Conversion-focused',\n charts: [\n {\n title: 'Chart 1',\n metric_1: ISMetricEnum.PPC_CONVERSIONS,\n metric_2: null,\n alignScales: true,\n },\n {\n title: 'Chart 2',\n metric_1: ISMetricEnum.CONVERSIONS_VALUE,\n metric_2: null,\n alignScales: true,\n },\n {\n title: 'Chart 3',\n metric_1: ISMetricEnum.PPC_CONVERSION_RATE,\n metric_2: null,\n alignScales: true,\n },\n ],\n },\n {\n title: 'Revenue-focused',\n charts: [\n {\n title: 'Chart 1',\n metric_1: ISMetricEnum.PPC_ROAS,\n metric_2: null,\n alignScales: true,\n },\n {\n title: 'Chart 2',\n metric_1: ISMetricEnum.PPC_CPC,\n metric_2: null,\n alignScales: true,\n },\n {\n title: 'Chart 3',\n metric_1: ISMetricEnum.PPC_CPA,\n metric_2: null,\n alignScales: true,\n },\n ],\n },\n {\n title: 'Other',\n charts: [],\n },\n ];\n }\n\n static getSearchGapsTabs(): ISTacticMetricTabConfig[] {\n return [\n {\n title: 'Traffic-focused',\n charts: [\n {\n title: 'Overall Impressions',\n metric_1: ISMetricEnum.COMBINED_IMPRESSIONS,\n metric_2: ISMetricEnum.PAID_IMPRESSIONS_SHARE,\n alignScales: false,\n },\n {\n title: 'SEO Impressions',\n metric_1: ISMetricEnum.SEO_IMPRESSIONS,\n metric_2: ISMetricEnum.PPC_IMPRESSIONS,\n alignScales: true,\n },\n {\n title: 'SEO',\n metric_1: ISMetricEnum.SEO_POSITION,\n metric_2: null,\n alignScales: false,\n },\n ],\n },\n {\n title: 'Conversion-focused',\n charts: [\n {\n title: 'Chart 1',\n metric_1: ISMetricEnum.CONVERSIONS_VALUE,\n metric_2: null,\n alignScales: true,\n },\n ],\n },\n {\n title: 'Other',\n charts: [],\n },\n ];\n }\n\n static getLandingPageOptimisationTabs(): ISTacticMetricTabConfig[] {\n return [\n {\n title: 'Traffic-focused',\n charts: [\n {\n title: 'Impressions 1',\n metric_1: ISMetricEnum.SEO_IMPRESSIONS,\n metric_2: ISMetricEnum.PPC_IMPRESSIONS,\n alignScales: true,\n },\n {\n title: 'Impressions 2',\n metric_1: ISMetricEnum.COMBINED_IMPRESSIONS,\n metric_2: ISMetricEnum.PAID_IMPRESSIONS_SHARE,\n alignScales: false,\n },\n {\n title: 'Clicks',\n metric_1: ISMetricEnum.PPC_CLICKS,\n metric_2: ISMetricEnum.PPC_CTR,\n alignScales: false,\n },\n ],\n },\n {\n title: 'Conversion-focused',\n charts: [\n {\n title: 'Chart 1',\n metric_1: ISMetricEnum.PPC_CONVERSIONS,\n metric_2: null,\n alignScales: true,\n },\n {\n title: 'Chart 2',\n metric_1: ISMetricEnum.CONVERSIONS_VALUE,\n metric_2: null,\n alignScales: true,\n },\n ],\n },\n {\n title: 'Revenue-focused',\n charts: [\n {\n title: 'Chart 1',\n metric_1: ISMetricEnum.PPC_CPC,\n metric_2: null,\n alignScales: true,\n },\n {\n title: 'Chart 2',\n metric_1: ISMetricEnum.PPC_ROAS,\n metric_2: null,\n alignScales: true,\n },\n ],\n },\n {\n title: 'Other',\n charts: [\n {\n title: 'Chart 1',\n metric_1: ISMetricEnum.PPC_SPEND,\n metric_2: null,\n alignScales: true,\n },\n // TODO: Uncomment when AD_COST_SHARE is added to the enum\n // {\n // title: 'Chart 2',\n // metric_1: ISMetricEnum.AD_COST_SHARE,\n // metric_2: null,\n // alignScales: true,\n // },\n ],\n },\n ];\n }\n}\n", "import { ISAdGroup, ISCampaign } from '@ess/integrated-search/shared/utils';\n\nexport class ISTacticsCampaignTooltipHelper {\n static adGroupTooltips(adGroups: ISAdGroup[]): string[] {\n return adGroups.map((adGroup) => `Ad group: ${adGroup.ad_group_name}\\nID: ${adGroup.ad_group_id}`);\n }\n\n static campaignTooltips(campaigns: ISCampaign[]): string[] {\n return campaigns.map((campaign) => `Campaign: ${campaign?.campaign_name}\\nID: ${campaign?.campaign_id}`);\n }\n}\n"], "mappings": "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", "names": ["ISChannelOverlapRecommendationEnum", "ISOptimisationRecommendationEnum", "ISGapsRecommendationEnum", "ISTacticsChartDefsConfig", "getTacticChartOptions", "metrics", "alignScales", "currency", "missingDataWarning", "showTooltip", "yAxis", "filter", "_", "index", "isScaleAlignmentApplicable", "map", "metric", "__createYAxis", "axesColors", "IS_METRICS_UNITS", "ISMetricUnitEnum", "INTEGER", "undefined", "__spreadValues", "xAxis", "axisLabel", "formatter", "label", "essFormatDateHelper", "__getChartTooltip", "tooltip", "show", "color", "format", "type", "__getValueFormatter", "axisLine", "lineStyle", "offset", "min", "max", "value", "Math", "ceil", "currencyCode", "PERCENTAGE", "essFormatNumber", "minimumIntegerDigits", "minimumFractionDigits", "maximumFractionDigits", "style", "CURRENCY", "currencyDisplay", "params", "missingData", "series", "reduce", "arr", "serie", "seriesName", "unit", "valueFn", "name", "IS_METRICS_LABELS", "marker", "shapes", "seriesId", "concat", "date", "month", "day", "year", "componentType", "_ISTacticsChartDefsConfig", "SHARED_COLORS", "chart", "symbols", "circle", "diamond", "IS_TACTICS_RESOURCE_PATH", "InjectionToken", "ISTacticsEnum", "ISTacticActionEnum", "IS_TACTICS_CHART_MISSING_DATA_MESSAGE", "ISTacticsEnum", "CHANNEL_OVERLAP", "SEARCH_GAPS", "LANDING_PAGE_OPTIMISATION", "ISTacticsApprovalsHelper", "mapApprovalsToChartMarkPoint", "approvals", "timespan", "intervals", "__getIntervals", "sortedApprovals", "filter", "series", "recommendations", "length", "sort", "a", "b", "date", "forEach", "r", "data", "map", "interval", "lastFromInterval", "findIndex", "approval", "end", "__spreadProps", "__spreadValues", "splice", "flatMap", "i", "value", "symbol", "symbolSize", "coord", "pointer", "name", "markPointData", "label", "color", "SHARED_COLORS", "itemStyle", "borderColor", "priority", "paused", "borderWidth", "emphasis", "__getIntervalLength", "range", "essDaysDifference", "Date", "start_date", "end_date", "pointerDate", "endDate", "getTime", "setDate", "getDate", "middle", "Math", "floor", "push", "start", "essFormatDateToISO", "IS_TACTIC_PERFORMANCE_DICTIONARY", "ISTacticsEnum", "CHANNEL_OVERLAP", "title", "entityMetrics", "entitiesName", "button", "ISTacticActionEnum", "REMOVE_FROM_NEGATIVES", "default", "recommendation", "ISChannelOverlapRecommendationEnum", "ADD_TO_NEGATIVES", "NONE", "ADDED_TO_NEGATIVES", "confirmation", "confirmationTitle", "tooltip", "action", "primaryAction", "entityActionPath", "LANDING_PAGE_OPTIMISATION", "ISOptimisationRecommendationEnum", "OPTIMISED", "SEARCH_GAPS", "IMPROVE_PPC", "IMPROVE_SEO", "ISGapsRecommendationEnum", "OPTIMISED_PPC", "OPTIMISED_SEO", "secondaryAction", "IS_TACTICS_TOOLTIP_DICTIONARY", "ISTacticsEnum", "CHANNEL_OVERLAP", "tactic", "timeFilter", "LANDING_PAGE_OPTIMISATION", "SEARCH_GAPS", "IS_TACTICS_RECOMMENDATION_LABELS", "ISChannelOverlapRecommendationEnum", "ADD_TO_NEGATIVES", "ADDED_TO_NEGATIVES", "ISOptimisationRecommendationEnum", "CRITICAL", "IMPORTANT", "MEDIUM", "OPTIMISED", "ISGapsRecommendationEnum", "IMPROVE_SEO", "IMPROVE_PPC", "OPTIMISED_SEO", "OPTIMISED_PPC", "IS_TACTICS_APPROVED_RECOMMENDATIONS", "ISChannelOverlapRecommendationEnum", "ADDED_TO_NEGATIVES", "ISOptimisationRecommendationEnum", "OPTIMISED", "ISGapsRecommendationEnum", "OPTIMISED_PPC", "OPTIMISED_SEO", "IS_TACTIC_ACTION_MESSAGE", "success", "ISTacticActionEnum", "REMOVE_FROM_NEGATIVES", "error", "IS_TACTICS_CHART_SERIES", "ISTacticsEnum", "CHANNEL_OVERLAP", "ISMetricEnum", "COMBINED_IMPRESSIONS", "PPC_CONVERSION_RATE", "CONVERSIONS_VALUE", "PAID_IMPRESSIONS_SHARE", "PPC_CLICKS", "PPC_CONVERSIONS", "PPC_CPA", "PPC_CPC", "PPC_CTR", "PPC_IMPRESSIONS", "PPC_SPEND", "PPC_ROAS", "SEO_CLICKS", "SEO_CTR", "SEO_IMPRESSIONS", "SEO_POSITION", "MAX_IMPRESSIONS", "MAX_PAID_IMPRESSIONS_SHARE", "SEARCH_GAPS", "LANDING_PAGE_OPTIMISATION", "IS_TACTICS_RECOMMENDATIONS", "ISTacticsEnum", "CHANNEL_OVERLAP", "Object", "values", "ISChannelOverlapRecommendationEnum", "SEARCH_GAPS", "ISGapsRecommendationEnum", "LANDING_PAGE_OPTIMISATION", "ISOptimisationRecommendationEnum", "IS_COMPETITION_TYPES_LABELS", "ISCompetitionTypesEnum", "LOW", "MEDIUM", "HIGH", "UNSPECIFIED", "IS_SEARCH_TERM_DIFFICULTY_LABELS", "ISSearchTermDifficultyTypesEnum", "LOW", "MEDIUM", "HIGH", "IS_TACTICS_KEYS", "ISTacticsEnum", "CHANNEL_OVERLAP", "LANDING_PAGE_OPTIMISATION", "SEARCH_GAPS", "ISTacticsChartDataHelper", "getChartSeriesForMetrics", "alignScales", "data", "metrics", "length", "__spreadProps", "__spreadValues", "series", "__prepareChartSeries", "formatChartSeries", "source", "approvals", "timespan", "chartData", "type", "SharedChartTypeEnum", "LINE", "IS_TACTICS_CHART_SERIES", "reduce", "acc", "serie", "dataSerie", "find", "s", "name", "push", "categories", "color", "markPoint", "ISTacticsApprovalsHelper", "mapApprovalsToChartMarkPoint", "filter", "includes", "sort", "a", "b", "indexA", "indexOf", "indexB", "map", "metricIndex", "symbol", "ISTacticsChartDefsConfig", "symbols", "yAxisIndex", "isScaleAlignmentApplicable", "itemStyle", "axesColors", "lineStyle", "id", "ISTacticsInitialChartDefsHelper", "getInitialState", "projectId", "channelOverlap", "tabs", "getChannelOverlapTabs", "landingPageOptimisation", "getLandingPageOptimisationTabs", "searchGaps", "getSearchGapsTabs", "title", "charts", "metric_1", "ISMetricEnum", "COMBINED_IMPRESSIONS", "metric_2", "PAID_IMPRESSIONS_SHARE", "alignScales", "SEO_CLICKS", "SEO_CTR", "PPC_CLICKS", "PPC_CTR", "PPC_CONVERSIONS", "CONVERSIONS_VALUE", "PPC_CONVERSION_RATE", "PPC_ROAS", "PPC_CPC", "PPC_CPA", "SEO_IMPRESSIONS", "PPC_IMPRESSIONS", "SEO_POSITION", "PPC_SPEND", "ISTacticsCampaignTooltipHelper", "adGroupTooltips", "adGroups", "map", "adGroup", "ad_group_name", "ad_group_id", "campaignTooltips", "campaigns", "campaign", "campaign_name", "campaign_id"] }