From ac1d5b4334ff9e115e402138b3869720e53bf21b Mon Sep 17 00:00:00 2001 From: estelafs Date: Mon, 11 Dec 2023 17:55:57 -0300 Subject: [PATCH 1/3] fix: applyOperations when style is present --- libs/shared/src/lib/utils/parser/utils.ts | 34 +++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/libs/shared/src/lib/utils/parser/utils.ts b/libs/shared/src/lib/utils/parser/utils.ts index b0e46228dc..2a181508c6 100644 --- a/libs/shared/src/lib/utils/parser/utils.ts +++ b/libs/shared/src/lib/utils/parser/utils.ts @@ -411,7 +411,6 @@ const replaceRecordFields = ( } // replace all /n, removing it since we don't need because tailwind already styles it formattedHtml = formattedHtml.replace(/\n/g, ''); - return formattedHtml; }; @@ -450,8 +449,22 @@ const applyOperations = (html: string): string => { `${CALC_PREFIX}(\\w+)\\(([^\\)]+)\\)${PLACEHOLDER_SUFFIX}`, 'gm' ); - let parsedHtml = html; - let result = regex.exec(html); + + // To identify and remove span with style elements to avoid breaking calc functions + const spanRegex = /]*>([^<]+)<\/span>/g; + const spanElements: string[] = []; + // Clean HTML don't have span and styles + const cleanHtml = html.replace(spanRegex, (match, spanContent) => { + // Save the removed span element + spanElements.push(match); + // Replace the span element with its content + return spanContent; + }); + + let parsedHtml = cleanHtml; + let result = regex.exec(cleanHtml); + // Track the index of the saved span elements + let spanIndex = 0; while (result !== null) { // get the function const calcFunc = get(calcFunctions, result[1]); @@ -467,9 +480,20 @@ const applyOperations = (html: string): string => { } catch (err: any) { resultText = ` ${err.name}`; } - parsedHtml = parsedHtml.replace(result[0], resultText); + if (spanElements.length > spanIndex) { + // Retrieve the saved span element + const spanElement = spanElements[spanIndex]; + // Replace the html with the calculated result inside the saved span element with the style + parsedHtml = parsedHtml.replace( + result[0], + spanElement.replace(`'>.*()`, `'>${resultText}$1`) + ); + } else { + parsedHtml = parsedHtml.replace(result[0], resultText); + } + spanIndex++; } - result = regex.exec(html); + result = regex.exec(cleanHtml); } return parsedHtml; }; From a27fe5667605f05f253d3dd425c82a8e421e6d99 Mon Sep 17 00:00:00 2001 From: estelafs Date: Tue, 12 Dec 2023 10:14:50 -0300 Subject: [PATCH 2/3] update regex --- libs/shared/src/lib/utils/parser/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libs/shared/src/lib/utils/parser/utils.ts b/libs/shared/src/lib/utils/parser/utils.ts index 2a181508c6..0595d4294e 100644 --- a/libs/shared/src/lib/utils/parser/utils.ts +++ b/libs/shared/src/lib/utils/parser/utils.ts @@ -451,7 +451,7 @@ const applyOperations = (html: string): string => { ); // To identify and remove span with style elements to avoid breaking calc functions - const spanRegex = /]*>([^<]+)<\/span>/g; + const spanRegex = /]*>([\s\S]*?)<\/span>/g; const spanElements: string[] = []; // Clean HTML don't have span and styles const cleanHtml = html.replace(spanRegex, (match, spanContent) => { From fefb39159482a70149acddc1a3945ecf41b4a995 Mon Sep 17 00:00:00 2001 From: Tai Kamilla Date: Tue, 12 Dec 2023 17:54:02 +0100 Subject: [PATCH 3/3] Add formatDate function to calcFunctions --- .../src/lib/utils/parser/calcFunctions.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/libs/shared/src/lib/utils/parser/calcFunctions.ts b/libs/shared/src/lib/utils/parser/calcFunctions.ts index 21d50e2e2c..6502a5d6ae 100644 --- a/libs/shared/src/lib/utils/parser/calcFunctions.ts +++ b/libs/shared/src/lib/utils/parser/calcFunctions.ts @@ -1,3 +1,4 @@ +import { formatDate } from '@angular/common'; import { ceil, floor, round } from 'lodash'; /** @@ -90,6 +91,26 @@ const calcFunctions: Record< return percent.toFixed(parsedPrecision) + '%'; }, }, + formatDate: { + signature: 'formatDate( value ; format)', + /** + * Format a date + * + * @param value The date to format + * @param format The format to use (optional, default to 'mediumDate') + * @param locale The locale to use (optional, default to the user browser locale) + * @param timezone The timezone to use (optional, default to the user browser timezone) + * @returns The formatted date + */ + call: ( + value, + format = 'mediumDate', + locale = Intl.DateTimeFormat().resolvedOptions().locale, // could also be navigator.language + timezone = Intl.DateTimeFormat().resolvedOptions().timeZone + ) => { + return formatDate(value, format, locale, timezone); + }, + }, }; export default calcFunctions;