@servicetitan/dte-pdf-editor 1.35.0 → 1.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/README.md +28 -12
  2. package/dist/components/field-config-panel/advanced-settings.d.ts.map +1 -1
  3. package/dist/components/field-config-panel/advanced-settings.js +20 -10
  4. package/dist/components/field-config-panel/advanced-settings.js.map +1 -1
  5. package/dist/components/field-config-panel/formula-generator.d.ts.map +1 -1
  6. package/dist/components/field-config-panel/formula-generator.js +2 -1
  7. package/dist/components/field-config-panel/formula-generator.js.map +1 -1
  8. package/dist/components/field-config-panel/formula-modal.d.ts.map +1 -1
  9. package/dist/components/field-config-panel/formula-modal.js +48 -7
  10. package/dist/components/field-config-panel/formula-modal.js.map +1 -1
  11. package/dist/components/field-config-panel/formula-workspace.d.ts +1 -0
  12. package/dist/components/field-config-panel/formula-workspace.d.ts.map +1 -1
  13. package/dist/components/field-config-panel/formula-workspace.js +10 -4
  14. package/dist/components/field-config-panel/formula-workspace.js.map +1 -1
  15. package/dist/components/field-config-panel/result-type-selector.d.ts.map +1 -1
  16. package/dist/components/field-config-panel/result-type-selector.js +1 -0
  17. package/dist/components/field-config-panel/result-type-selector.js.map +1 -1
  18. package/dist/components/pdf-view/pdf-view-calculated.d.ts +1 -0
  19. package/dist/components/pdf-view/pdf-view-calculated.d.ts.map +1 -1
  20. package/dist/components/pdf-view/pdf-view-calculated.js +20 -3
  21. package/dist/components/pdf-view/pdf-view-calculated.js.map +1 -1
  22. package/dist/components/pdf-view/pdf-view-fillable.d.ts.map +1 -1
  23. package/dist/components/pdf-view/pdf-view-fillable.js +5 -2
  24. package/dist/components/pdf-view/pdf-view-fillable.js.map +1 -1
  25. package/dist/components/pdf-view/pdf-view.d.ts +6 -0
  26. package/dist/components/pdf-view/pdf-view.d.ts.map +1 -1
  27. package/dist/components/pdf-view/pdf-view.js +2 -2
  28. package/dist/components/pdf-view/pdf-view.js.map +1 -1
  29. package/dist/constants/calculated.constants.d.ts +2 -0
  30. package/dist/constants/calculated.constants.d.ts.map +1 -1
  31. package/dist/constants/calculated.constants.js +2 -0
  32. package/dist/constants/calculated.constants.js.map +1 -1
  33. package/dist/hooks/useFormulaEditor.d.ts +3 -0
  34. package/dist/hooks/useFormulaEditor.d.ts.map +1 -1
  35. package/dist/hooks/useFormulaEditor.js +24 -1
  36. package/dist/hooks/useFormulaEditor.js.map +1 -1
  37. package/dist/interface/types.d.ts +6 -2
  38. package/dist/interface/types.d.ts.map +1 -1
  39. package/dist/interface/types.js.map +1 -1
  40. package/dist/utils/data-model/extract-fields.utils.d.ts.map +1 -1
  41. package/dist/utils/data-model/extract-fields.utils.js +11 -1
  42. package/dist/utils/data-model/extract-fields.utils.js.map +1 -1
  43. package/dist/utils/formula/evaluate-formula.utils.d.ts +10 -2
  44. package/dist/utils/formula/evaluate-formula.utils.d.ts.map +1 -1
  45. package/dist/utils/formula/evaluate-formula.utils.js +205 -4
  46. package/dist/utils/formula/evaluate-formula.utils.js.map +1 -1
  47. package/dist/utils/formula/expression.utils.d.ts +3 -3
  48. package/dist/utils/formula/expression.utils.d.ts.map +1 -1
  49. package/dist/utils/formula/expression.utils.js +3 -5
  50. package/dist/utils/formula/expression.utils.js.map +1 -1
  51. package/dist/utils/formula/format-calculated-result.utils.d.ts +1 -1
  52. package/dist/utils/formula/format-calculated-result.utils.d.ts.map +1 -1
  53. package/dist/utils/formula/format-calculated-result.utils.js +29 -8
  54. package/dist/utils/formula/format-calculated-result.utils.js.map +1 -1
  55. package/dist/utils/formula/validate-formula.utils.d.ts +1 -1
  56. package/dist/utils/formula/validate-formula.utils.d.ts.map +1 -1
  57. package/dist/utils/formula/validate-formula.utils.js +18 -3
  58. package/dist/utils/formula/validate-formula.utils.js.map +1 -1
  59. package/dist/utils/shared/date.utils.d.ts +2 -0
  60. package/dist/utils/shared/date.utils.d.ts.map +1 -0
  61. package/dist/utils/shared/date.utils.js +6 -0
  62. package/dist/utils/shared/date.utils.js.map +1 -0
  63. package/dist/utils/shared/index.d.ts +1 -0
  64. package/dist/utils/shared/index.d.ts.map +1 -1
  65. package/dist/utils/shared/index.js +1 -0
  66. package/dist/utils/shared/index.js.map +1 -1
  67. package/package.json +1 -1
  68. package/src/components/field-config-panel/advanced-settings.tsx +103 -77
  69. package/src/components/field-config-panel/formula-generator.tsx +2 -1
  70. package/src/components/field-config-panel/formula-modal.tsx +48 -8
  71. package/src/components/field-config-panel/formula-workspace.tsx +21 -7
  72. package/src/components/field-config-panel/result-type-selector.tsx +1 -0
  73. package/src/components/pdf-view/pdf-view-calculated.tsx +20 -3
  74. package/src/components/pdf-view/pdf-view-fillable.tsx +6 -3
  75. package/src/components/pdf-view/pdf-view.tsx +8 -0
  76. package/src/constants/calculated.constants.ts +4 -0
  77. package/src/hooks/useFormulaEditor.ts +32 -1
  78. package/src/interface/types.ts +8 -2
  79. package/src/utils/data-model/extract-fields.utils.ts +13 -1
  80. package/src/utils/formula/evaluate-formula.utils.ts +271 -5
  81. package/src/utils/formula/expression.utils.ts +3 -8
  82. package/src/utils/formula/format-calculated-result.utils.ts +32 -10
  83. package/src/utils/formula/validate-formula.utils.ts +27 -1
  84. package/src/utils/shared/date.utils.ts +6 -0
  85. package/src/utils/shared/index.ts +1 -0
@@ -11,10 +11,10 @@ export interface ExpressionPart {
11
11
  }
12
12
  export declare function tokenizeExpression(expression: string): ExpressionPart[];
13
13
  /**
14
- * Parse an expression string into FormulaToken[] using valid paths and path->label map.
15
- * Invalid or unknown identifiers are skipped (or could be left as placeholder); only known paths become field tokens.
14
+ * Parse an expression string into FormulaToken[] using valid paths.
15
+ * Invalid or unknown identifiers are skipped; only known paths become field tokens.
16
16
  */
17
- export declare function parseExpression(expression: string, validPaths: Set<string>, pathToLabel: Map<string, string>): FormulaToken[];
17
+ export declare function parseExpression(expression: string, validPaths: Set<string>): FormulaToken[];
18
18
  export interface NormalizeMergeTagsResult {
19
19
  normalized: string;
20
20
  removed: {
@@ -1 +1 @@
1
- {"version":3,"file":"expression.utils.d.ts","sourceRoot":"","sources":["../../../src/utils/formula/expression.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAExE;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,GAAG,SAAS,GAAG,MAAM,CAcjF;AAED,oFAAoF;AACpF,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;IACzD,KAAK,EAAE,MAAM,CAAC;CACjB;AAKD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,EAAE,CAgBvE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC3B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,EACvB,WAAW,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GACjC,YAAY,EAAE,CAyChB;AAED,MAAM,WAAW,wBAAwB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAClD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAC9B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,GACxB,wBAAwB,CAqC1B"}
1
+ {"version":3,"file":"expression.utils.d.ts","sourceRoot":"","sources":["../../../src/utils/formula/expression.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAExE;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,iBAAiB,GAAG,SAAS,GAAG,MAAM,CAcjF;AAED,oFAAoF;AACpF,MAAM,WAAW,cAAc;IAC3B,IAAI,EAAE,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;IACzD,KAAK,EAAE,MAAM,CAAC;CACjB;AAKD,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,cAAc,EAAE,CAgBvE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,YAAY,EAAE,CAwC3F;AAED,MAAM,WAAW,wBAAwB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAClD;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAC9B,UAAU,EAAE,MAAM,EAClB,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,GACxB,wBAAwB,CAqC1B"}
@@ -41,11 +41,10 @@ export function tokenizeExpression(expression) {
41
41
  return tokens;
42
42
  }
43
43
  /**
44
- * Parse an expression string into FormulaToken[] using valid paths and path->label map.
45
- * Invalid or unknown identifiers are skipped (or could be left as placeholder); only known paths become field tokens.
44
+ * Parse an expression string into FormulaToken[] using valid paths.
45
+ * Invalid or unknown identifiers are skipped; only known paths become field tokens.
46
46
  */
47
- export function parseExpression(expression, validPaths, pathToLabel) {
48
- var _a;
47
+ export function parseExpression(expression, validPaths) {
49
48
  const parts = tokenizeExpression(expression).filter(p => p.type !== 'text' || p.value.trim() !== '');
50
49
  const tokens = [];
51
50
  for (const part of parts) {
@@ -57,7 +56,6 @@ export function parseExpression(expression, validPaths, pathToLabel) {
57
56
  tokens.push({
58
57
  type: 'field',
59
58
  path: part.value,
60
- label: (_a = pathToLabel.get(part.value)) !== null && _a !== void 0 ? _a : part.value,
61
59
  });
62
60
  }
63
61
  continue;
@@ -1 +1 @@
1
- {"version":3,"file":"expression.utils.js","sourceRoot":"","sources":["../../../src/utils/formula/expression.utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"expression.utils.js","sourceRoot":"","sources":["../../../src/utils/formula/expression.utils.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { CalculatedFieldFormat } from '../../interface/types';
2
2
  /**
3
3
  * Format a calculated formula result for display using advanced settings.
4
- * Applies rounding, decimal places, thousands/decimal separators, result type (number/currency/percent), and prefix/postfix.
4
+ * Applies rounding, decimal places, thousands/decimal separators, result type (number/currency/percent/date), and prefix/postfix.
5
5
  */
6
6
  export declare function formatCalculatedResult(value: number, format: CalculatedFieldFormat | undefined): string;
7
7
  //# sourceMappingURL=format-calculated-result.utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"format-calculated-result.utils.d.ts","sourceRoot":"","sources":["../../../src/utils/formula/format-calculated-result.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAsC9D;;;GAGG;AACH,wBAAgB,sBAAsB,CAClC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,qBAAqB,GAAG,SAAS,GAC1C,MAAM,CAiCR"}
1
+ {"version":3,"file":"format-calculated-result.utils.d.ts","sourceRoot":"","sources":["../../../src/utils/formula/format-calculated-result.utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AA8D9D;;;GAGG;AACH,wBAAgB,sBAAsB,CAClC,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,qBAAqB,GAAG,SAAS,GAC1C,MAAM,CA8BR"}
@@ -1,3 +1,4 @@
1
+ import { DEFAULT_DATE_FORMAT } from '../../constants';
1
2
  function roundValue(value, decimals, mode) {
2
3
  const factor = 10 ** decimals;
3
4
  const scaled = value * factor;
@@ -24,27 +25,47 @@ function formatIntegerPart(s, thousandsSeparator, decimalSeparator) {
24
25
  }
25
26
  return parts.join(sep);
26
27
  }
28
+ const DATE_FORMAT_TOKENS = {
29
+ YYYY: d => String(d.getFullYear()),
30
+ YY: d => String(d.getFullYear()).slice(-2),
31
+ MMMM: d => d.toLocaleString('en-US', { month: 'long' }),
32
+ MMM: d => d.toLocaleString('en-US', { month: 'short' }),
33
+ MM: d => String(d.getMonth() + 1).padStart(2, '0'),
34
+ M: d => String(d.getMonth() + 1),
35
+ DD: d => String(d.getDate()).padStart(2, '0'),
36
+ D: d => String(d.getDate()),
37
+ };
38
+ const DATE_TOKEN_PATTERN = new RegExp(Object.keys(DATE_FORMAT_TOKENS).join('|'), 'g');
39
+ function formatDateValue(epochMs, dateFormat) {
40
+ const date = new Date(epochMs);
41
+ if (isNaN(date.getTime())) {
42
+ return '';
43
+ }
44
+ return dateFormat.replace(DATE_TOKEN_PATTERN, match => {
45
+ const fn = DATE_FORMAT_TOKENS[match];
46
+ return fn ? fn(date) : match;
47
+ });
48
+ }
27
49
  /**
28
50
  * Format a calculated formula result for display using advanced settings.
29
- * Applies rounding, decimal places, thousands/decimal separators, result type (number/currency/percent), and prefix/postfix.
51
+ * Applies rounding, decimal places, thousands/decimal separators, result type (number/currency/percent/date), and prefix/postfix.
30
52
  */
31
53
  export function formatCalculatedResult(value, format) {
54
+ var _a;
32
55
  if (format == null) {
33
56
  return String(value);
34
57
  }
35
- const { decimalSeparator, decimalSeparatorEnabled, decimals, postfixText, prefixText, resultType, roundingMode, thousandsSeparator, } = format;
36
- let num = value;
37
- if (resultType === 'percent') {
38
- num = value * 100;
58
+ if (format.resultType === 'date') {
59
+ return formatDateValue(value, (_a = format.dateFormat) !== null && _a !== void 0 ? _a : DEFAULT_DATE_FORMAT);
39
60
  }
40
- const rounded = roundValue(num, decimals, roundingMode);
61
+ const { decimalSeparator, decimalSeparatorEnabled, decimals, postfixText, prefixText, roundingMode, thousandsSeparator, } = format;
62
+ const rounded = roundValue(value, decimals, roundingMode);
41
63
  const fixed = rounded.toFixed(decimals);
42
64
  const [intPart, decPart] = fixed.split('.');
43
65
  const decimalSep = decimalSeparatorEnabled ? decimalSeparator : '.';
44
66
  const intFormatted = formatIntegerPart(intPart, thousandsSeparator, decimalSep);
45
67
  const decSuffix = decimals > 0 ? decimalSep + (decPart !== null && decPart !== void 0 ? decPart : '') : '';
46
68
  const numberStr = intFormatted + decSuffix;
47
- const suffix = resultType === 'percent' ? '%' : '';
48
- return `${prefixText}${numberStr}${suffix}${postfixText}`;
69
+ return `${prefixText}${numberStr}${postfixText}`;
49
70
  }
50
71
  //# sourceMappingURL=format-calculated-result.utils.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"format-calculated-result.utils.js","sourceRoot":"","sources":["../../../src/utils/formula/format-calculated-result.utils.ts"],"names":[],"mappings":"AAEA,SAAS,UAAU,CACf,KAAa,EACb,QAAgB,EAChB,IAA2C;IAE3C,MAAM,MAAM,GAAG,EAAE,IAAI,QAAQ,CAAC;IAC9B,MAAM,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;IAC9B,QAAQ,IAAI,EAAE,CAAC;QACX,KAAK,OAAO;YACR,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;QACvC,KAAK,MAAM;YACP,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;QACtC;YACI,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC;IAC3C,CAAC;AACL,CAAC;AAED,SAAS,iBAAiB,CACtB,CAAS,EACT,kBAA2B,EAC3B,gBAA2B;IAE3B,IAAI,CAAC,kBAAkB,EAAE,CAAC;QACtB,OAAO,CAAC,CAAC;IACb,CAAC;IACD,MAAM,GAAG,GAAG,gBAAgB,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,yBAAyB;IAC3E,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;IACjB,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACX,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;QACjC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;QACjC,CAAC,GAAG,KAAK,CAAC;IACd,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC3B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,sBAAsB,CAClC,KAAa,EACb,MAAyC;IAEzC,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACjB,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;IACzB,CAAC;IAED,MAAM,EACF,gBAAgB,EAChB,uBAAuB,EACvB,QAAQ,EACR,WAAW,EACX,UAAU,EACV,UAAU,EACV,YAAY,EACZ,kBAAkB,GACrB,GAAG,MAAM,CAAC;IAEX,IAAI,GAAG,GAAG,KAAK,CAAC;IAChB,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;QAC3B,GAAG,GAAG,KAAK,GAAG,GAAG,CAAC;IACtB,CAAC;IAED,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IACxD,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,CAAC,OAAO,EAAE,OAAO,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAE5C,MAAM,UAAU,GAAG,uBAAuB,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,GAAG,CAAC;IACpE,MAAM,YAAY,GAAG,iBAAiB,CAAC,OAAO,EAAE,kBAAkB,EAAE,UAAU,CAAC,CAAC;IAChF,MAAM,SAAS,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,OAAO,aAAP,OAAO,cAAP,OAAO,GAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAEnE,MAAM,SAAS,GAAG,YAAY,GAAG,SAAS,CAAC;IAC3C,MAAM,MAAM,GAAG,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;IAEnD,OAAO,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,WAAW,EAAE,CAAC;AAC9D,CAAC"}
1
+ {"version":3,"file":"format-calculated-result.utils.js","sourceRoot":"","sources":["../../../src/utils/formula/format-calculated-result.utils.ts"],"names":[],"mappings":"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"}
@@ -7,5 +7,5 @@ export interface FormulaValidationResult {
7
7
  * Validates a structured formula.
8
8
  * Rules: not empty, valid operator placement, balanced parentheses, supported operators only, all field paths exist.
9
9
  */
10
- export declare function validateFormula(formula: StructuredFormula | undefined | null, validPaths: Set<string>): FormulaValidationResult;
10
+ export declare function validateFormula(formula: StructuredFormula | undefined | null, validPaths: Set<string>, knownDateFields?: Set<string>, pathToLabel?: Map<string, string>): FormulaValidationResult;
11
11
  //# sourceMappingURL=validate-formula.utils.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"validate-formula.utils.d.ts","sourceRoot":"","sources":["../../../src/utils/formula/validate-formula.utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAExE,MAAM,WAAW,uBAAuB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CACpB;AAUD;;;GAGG;AACH,wBAAgB,eAAe,CAC3B,OAAO,EAAE,iBAAiB,GAAG,SAAS,GAAG,IAAI,EAC7C,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,GACxB,uBAAuB,CA0EzB"}
1
+ {"version":3,"file":"validate-formula.utils.d.ts","sourceRoot":"","sources":["../../../src/utils/formula/validate-formula.utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAgB,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAExE,MAAM,WAAW,uBAAuB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CACpB;AAUD;;;GAGG;AACH,wBAAgB,eAAe,CAC3B,OAAO,EAAE,iBAAiB,GAAG,SAAS,GAAG,IAAI,EAC7C,UAAU,EAAE,GAAG,CAAC,MAAM,CAAC,EACvB,eAAe,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,EAC7B,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAClC,uBAAuB,CAiGzB"}
@@ -1,3 +1,4 @@
1
+ import { MAX_DATE_CALC_DAYS } from '../../constants';
1
2
  function isOperatorToken(t) {
2
3
  return t.type === 'operator';
3
4
  }
@@ -8,8 +9,8 @@ function isOperandToken(t) {
8
9
  * Validates a structured formula.
9
10
  * Rules: not empty, valid operator placement, balanced parentheses, supported operators only, all field paths exist.
10
11
  */
11
- export function validateFormula(formula, validPaths) {
12
- var _a;
12
+ export function validateFormula(formula, validPaths, knownDateFields, pathToLabel) {
13
+ var _a, _b;
13
14
  const errors = [];
14
15
  if (!((_a = formula === null || formula === void 0 ? void 0 : formula.tokens) === null || _a === void 0 ? void 0 : _a.length)) {
15
16
  return { valid: false, errors: ['Formula cannot be empty'] };
@@ -51,7 +52,8 @@ export function validateFormula(formula, validPaths) {
51
52
  }
52
53
  else if (t.type === 'field') {
53
54
  if (!validPaths.has(t.path)) {
54
- errors.push(`Unknown field: "${t.label}" (path: ${t.path})`);
55
+ const label = (_b = pathToLabel === null || pathToLabel === void 0 ? void 0 : pathToLabel.get(t.path)) !== null && _b !== void 0 ? _b : t.path;
56
+ errors.push(`Unknown field: "${label}" (path: ${t.path})`);
55
57
  }
56
58
  if (next != null && isOperandToken(next)) {
57
59
  errors.push('Operator required between two fields or values');
@@ -78,6 +80,19 @@ export function validateFormula(formula, validPaths) {
78
80
  if (last && (last.type === 'operator' || last.type === 'lparen')) {
79
81
  errors.push('Formula must end with an operand or closing parenthesis');
80
82
  }
83
+ if (knownDateFields === null || knownDateFields === void 0 ? void 0 : knownDateFields.size) {
84
+ const hasDateField = tokens.some(t => t.type === 'field' && knownDateFields.has(t.path));
85
+ if (hasDateField) {
86
+ const hasMultiplyOrDivide = tokens.some(t => t.type === 'operator' && (t.value === '*' || t.value === '/'));
87
+ if (hasMultiplyOrDivide) {
88
+ errors.push('Multiply (*) and divide (/) operators cannot be used with date fields. Only +, -, and parentheses are allowed.');
89
+ }
90
+ const hasLargeNumber = tokens.some(t => t.type === 'number' && Math.abs(Number(t.value)) > MAX_DATE_CALC_DAYS);
91
+ if (hasLargeNumber) {
92
+ errors.push(`Number of days cannot exceed ${MAX_DATE_CALC_DAYS} in date calculations.`);
93
+ }
94
+ }
95
+ }
81
96
  return {
82
97
  valid: errors.length === 0,
83
98
  errors,
@@ -1 +1 @@
1
- {"version":3,"file":"validate-formula.utils.js","sourceRoot":"","sources":["../../../src/utils/formula/validate-formula.utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"validate-formula.utils.js","sourceRoot":"","sources":["../../../src/utils/formula/validate-formula.utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const dateToUtcZero: (dateString: string) => string;
2
+ //# sourceMappingURL=date.utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date.utils.d.ts","sourceRoot":"","sources":["../../../src/utils/shared/date.utils.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,aAAa,GAAI,YAAY,MAAM,KAAG,MAKlD,CAAC"}
@@ -0,0 +1,6 @@
1
+ export const dateToUtcZero = (dateString) => {
2
+ const [year, month, day] = dateString.split('-').map(Number);
3
+ const utcDate = new Date(Date.UTC(year, month - 1, day));
4
+ return utcDate.toISOString();
5
+ };
6
+ //# sourceMappingURL=date.utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"date.utils.js","sourceRoot":"","sources":["../../../src/utils/shared/date.utils.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,UAAkB,EAAU,EAAE;IACxD,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7D,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAEzD,OAAO,OAAO,CAAC,WAAW,EAAE,CAAC;AACjC,CAAC,CAAC"}
@@ -1,2 +1,3 @@
1
+ export * from './date.utils';
1
2
  export * from './number.utils';
2
3
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
@@ -1,2 +1,3 @@
1
+ export * from './date.utils';
1
2
  export * from './number.utils';
2
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/utils/shared/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@servicetitan/dte-pdf-editor",
3
- "version": "1.35.0",
3
+ "version": "1.37.0",
4
4
  "description": "",
5
5
  "main": "./dist/index.js",
6
6
  "typings": "./dist/index.d.ts",
@@ -1,5 +1,6 @@
1
1
  import { Flex, SegmentedControl, Switch, Text } from '@servicetitan/anvil2';
2
2
  import { Dispatch, FC, SetStateAction } from 'react';
3
+ import { DEFAULT_DATE_FORMAT } from '../../constants';
3
4
  import { CalculatedFieldFormat } from '../../interface/types';
4
5
 
5
6
  interface AdvancedSettingsProps {
@@ -13,97 +14,122 @@ const ROUNDING_OPTIONS: { label: string; value: CalculatedFieldFormat['roundingM
13
14
  { label: 'Ceil', value: 'ceil' },
14
15
  ];
15
16
 
16
- export const AdvancedSettings: FC<AdvancedSettingsProps> = ({ format, setFormat }) => (
17
+ const DateFormatSettings: FC<AdvancedSettingsProps> = ({ format, setFormat }) => (
17
18
  <div className="dte-formula-advanced">
18
19
  <Text variant="body" size="small">
19
- Rounding mode
20
+ Date format
20
21
  </Text>
21
- <SegmentedControl
22
- size="medium"
23
- selected={format.roundingMode}
24
- onChange={(roundingMode: CalculatedFieldFormat['roundingMode']) =>
25
- setFormat(prev => ({ ...prev, roundingMode }))
26
- }
27
- fill
28
- >
29
- {ROUNDING_OPTIONS.map(opt => (
30
- <SegmentedControl.Segment key={opt.value} value={opt.value}>
31
- {opt.label}
32
- </SegmentedControl.Segment>
33
- ))}
34
- </SegmentedControl>
35
- <Flex alignItems="center" justifyContent="space-between">
36
- <Text variant="body" size="small">
37
- Decimal places
38
- </Text>
39
- <Text variant="body" size="small" className="dte-formula-advanced-value">
40
- {format.decimals}
41
- </Text>
42
- </Flex>
43
22
  <input
44
- type="range"
45
- min={0}
46
- max={10}
47
- value={format.decimals}
48
- onChange={e =>
49
- setFormat(prev => ({
50
- ...prev,
51
- decimals: Number(e.target.value),
52
- }))
53
- }
54
- />
55
- <Switch
56
- checked={format.thousandsSeparator}
57
- onChange={(_e, { checked }) => {
58
- setFormat(prev => ({
59
- ...prev,
60
- thousandsSeparator: checked,
61
- decimalSeparatorEnabled: checked,
62
- decimalSeparator: checked ? prev.decimalSeparator : '.',
63
- }));
64
- }}
65
- label="Thousands separator"
66
- value="switch-example"
23
+ type="text"
24
+ className="dte-formula-advanced-input"
25
+ style={{ width: '100%' }}
26
+ value={format.dateFormat ?? DEFAULT_DATE_FORMAT}
27
+ placeholder={DEFAULT_DATE_FORMAT}
28
+ onChange={e => setFormat(prev => ({ ...prev, dateFormat: e.target.value }))}
67
29
  />
30
+ <Text variant="body" size="small" color="tertiary">
31
+ Tokens: YYYY, YY, MMMM, MMM, MM, M, DD, D
32
+ </Text>
33
+ </div>
34
+ );
35
+
36
+ export const AdvancedSettings: FC<AdvancedSettingsProps> = ({ format, setFormat }) => {
37
+ if (format.resultType === 'date') {
38
+ return <DateFormatSettings format={format} setFormat={setFormat} />;
39
+ }
68
40
 
69
- {format.thousandsSeparator && (
41
+ return (
42
+ <div className="dte-formula-advanced">
43
+ <Text variant="body" size="small">
44
+ Rounding mode
45
+ </Text>
70
46
  <SegmentedControl
71
47
  size="medium"
72
- fill
73
- selected={format.decimalSeparator}
74
- onChange={(decimalSeparator: CalculatedFieldFormat['decimalSeparator']) =>
75
- setFormat(prev => ({ ...prev, decimalSeparator }))
48
+ selected={format.roundingMode}
49
+ onChange={(roundingMode: CalculatedFieldFormat['roundingMode']) =>
50
+ setFormat(prev => ({ ...prev, roundingMode }))
76
51
  }
52
+ fill
77
53
  >
78
- {['.', ','].map(decimalSeparator => (
79
- <SegmentedControl.Segment key={decimalSeparator} value={decimalSeparator}>
80
- {decimalSeparator}
54
+ {ROUNDING_OPTIONS.map(opt => (
55
+ <SegmentedControl.Segment key={opt.value} value={opt.value}>
56
+ {opt.label}
81
57
  </SegmentedControl.Segment>
82
58
  ))}
83
59
  </SegmentedControl>
84
- )}
85
- <Text variant="body" size="small">
86
- Result affixes
87
- </Text>
88
- <Flex gap="2" alignItems="center">
89
- <Text variant="body" size="small">
90
- Prefix
91
- </Text>
60
+ <Flex alignItems="center" justifyContent="space-between">
61
+ <Text variant="body" size="small">
62
+ Decimal places
63
+ </Text>
64
+ <Text variant="body" size="small" className="dte-formula-advanced-value">
65
+ {format.decimals}
66
+ </Text>
67
+ </Flex>
92
68
  <input
93
- type="text"
94
- className="dte-formula-advanced-input"
95
- value={format.prefixText}
96
- onChange={e => setFormat(prev => ({ ...prev, prefixText: e.target.value }))}
69
+ type="range"
70
+ min={0}
71
+ max={10}
72
+ value={format.decimals}
73
+ onChange={e =>
74
+ setFormat(prev => ({
75
+ ...prev,
76
+ decimals: Number(e.target.value),
77
+ }))
78
+ }
79
+ />
80
+ <Switch
81
+ checked={format.thousandsSeparator}
82
+ onChange={(_e, { checked }) => {
83
+ setFormat(prev => ({
84
+ ...prev,
85
+ thousandsSeparator: checked,
86
+ decimalSeparatorEnabled: checked,
87
+ decimalSeparator: checked ? prev.decimalSeparator : '.',
88
+ }));
89
+ }}
90
+ label="Thousands separator"
91
+ value="switch-example"
97
92
  />
93
+
94
+ {format.thousandsSeparator && (
95
+ <SegmentedControl
96
+ size="medium"
97
+ fill
98
+ selected={format.decimalSeparator}
99
+ onChange={(decimalSeparator: CalculatedFieldFormat['decimalSeparator']) =>
100
+ setFormat(prev => ({ ...prev, decimalSeparator }))
101
+ }
102
+ >
103
+ {['.', ','].map(decimalSeparator => (
104
+ <SegmentedControl.Segment key={decimalSeparator} value={decimalSeparator}>
105
+ {decimalSeparator}
106
+ </SegmentedControl.Segment>
107
+ ))}
108
+ </SegmentedControl>
109
+ )}
98
110
  <Text variant="body" size="small">
99
- Postfix
111
+ Result affixes
100
112
  </Text>
101
- <input
102
- type="text"
103
- className="dte-formula-advanced-input"
104
- value={format.postfixText}
105
- onChange={e => setFormat(prev => ({ ...prev, postfixText: e.target.value }))}
106
- />
107
- </Flex>
108
- </div>
109
- );
113
+ <Flex gap="2" alignItems="center">
114
+ <Text variant="body" size="small">
115
+ Prefix
116
+ </Text>
117
+ <input
118
+ type="text"
119
+ className="dte-formula-advanced-input"
120
+ value={format.prefixText}
121
+ onChange={e => setFormat(prev => ({ ...prev, prefixText: e.target.value }))}
122
+ />
123
+ <Text variant="body" size="small">
124
+ Postfix
125
+ </Text>
126
+ <input
127
+ type="text"
128
+ className="dte-formula-advanced-input"
129
+ value={format.postfixText}
130
+ onChange={e => setFormat(prev => ({ ...prev, postfixText: e.target.value }))}
131
+ />
132
+ </Flex>
133
+ </div>
134
+ );
135
+ };
@@ -32,6 +32,7 @@ function getFillableFilteredBuySubTypeFields(
32
32
  type: FieldTypeEnum.fillable,
33
33
  subType: f.subType,
34
34
  path: f.path,
35
+ fieldType: f.subType === 'date' ? 'date' : 'number',
35
36
  }));
36
37
  }
37
38
 
@@ -53,7 +54,7 @@ export const FormulaGenerator: FC<FormulaGeneratorProps> = ({
53
54
  [dataModel],
54
55
  );
55
56
  const fillableFieldsFromDocument = useMemo(
56
- () => getFillableFilteredBuySubTypeFields(documentFields, ['number']),
57
+ () => getFillableFilteredBuySubTypeFields(documentFields, ['number', 'date']),
57
58
  [documentFields],
58
59
  );
59
60
 
@@ -1,8 +1,8 @@
1
1
  import { Button, Dialog, Divider, Flex } from '@servicetitan/anvil2';
2
2
  import IconRedo from '@servicetitan/anvil2/assets/icons/material/round/redo.svg';
3
3
  import IconUndo from '@servicetitan/anvil2/assets/icons/material/round/undo.svg';
4
- import { FC, useCallback, useMemo, useState } from 'react';
5
- import { MODAL_CONTENT_MAX_HEIGHT } from '../../constants';
4
+ import { FC, useCallback, useEffect, useMemo, useState } from 'react';
5
+ import { DEFAULT_DATE_FORMAT, MODAL_CONTENT_MAX_HEIGHT } from '../../constants';
6
6
  import { useFormulaEditor } from '../../hooks';
7
7
  import {
8
8
  CalculatedFieldFormat,
@@ -92,6 +92,21 @@ export const FormulaModal: FC<FormulaModalProps> = ({
92
92
  return m;
93
93
  }, [allFields, fillableFieldsFromDocument]);
94
94
 
95
+ const knownDateFields = useMemo(() => {
96
+ const set = new Set<string>();
97
+ for (const f of allFields) {
98
+ if (f.fieldType === 'date' && f.path) {
99
+ set.add(f.path);
100
+ }
101
+ }
102
+ for (const f of fillableFieldsFromDocument) {
103
+ if (f.fieldType === 'date' && f.path) {
104
+ set.add(f.path);
105
+ }
106
+ }
107
+ return set;
108
+ }, [allFields, fillableFieldsFromDocument]);
109
+
95
110
  const currentExpression = useMemo(() => tokensToExpression(initialFormula), [initialFormula]);
96
111
 
97
112
  const [highlightElementPath, setHighlightElementPath] = useState('');
@@ -102,18 +117,35 @@ export const FormulaModal: FC<FormulaModalProps> = ({
102
117
 
103
118
  const formulaEditor = useFormulaEditor({
104
119
  currentExpression,
120
+ knownDateFields,
105
121
  opened: true,
106
122
  pathToLabel,
107
123
  });
108
124
 
125
+ useEffect(() => {
126
+ if (formulaEditor.expressionHasDateFields && format.resultType !== 'date') {
127
+ setFormat(prev => ({
128
+ ...prev,
129
+ resultType: 'date',
130
+ dateFormat: prev.dateFormat ?? DEFAULT_DATE_FORMAT,
131
+ }));
132
+ setAdvancedOpen(true);
133
+ } else if (!formulaEditor.expressionHasDateFields && format.resultType === 'date') {
134
+ setFormat(prev => ({
135
+ ...prev,
136
+ resultType: 'number',
137
+ }));
138
+ }
139
+ }, [formulaEditor.expressionHasDateFields, format.resultType]);
140
+
109
141
  const parsedTokens = useMemo(
110
- () => parseExpression(formulaEditor.draftExpression, validPaths, pathToLabel),
111
- [formulaEditor.draftExpression, validPaths, pathToLabel],
142
+ () => parseExpression(formulaEditor.draftExpression, validPaths),
143
+ [formulaEditor.draftExpression, validPaths],
112
144
  );
113
145
 
114
146
  const formulaValidation = useMemo(
115
- () => validateFormula({ tokens: parsedTokens }, validPaths),
116
- [parsedTokens, validPaths],
147
+ () => validateFormula({ tokens: parsedTokens }, validPaths, knownDateFields, pathToLabel),
148
+ [parsedTokens, validPaths, knownDateFields, pathToLabel],
117
149
  );
118
150
 
119
151
  const unknownFieldErrors = useMemo(() => {
@@ -132,9 +164,16 @@ export const FormulaModal: FC<FormulaModalProps> = ({
132
164
  }, [onClose]);
133
165
 
134
166
  const handleSave = useCallback(() => {
135
- onSave({ tokens: parsedTokens }, format);
167
+ const usedDatePaths = parsedTokens
168
+ .filter(t => t.type === 'field' && knownDateFields.has(t.path))
169
+ .map(t => (t as { type: 'field'; path: string }).path);
170
+ const savedFormat: CalculatedFieldFormat = {
171
+ ...format,
172
+ dateFieldPaths: usedDatePaths.length > 0 ? [...new Set(usedDatePaths)] : undefined,
173
+ };
174
+ onSave({ tokens: parsedTokens }, savedFormat);
136
175
  onClose();
137
- }, [format, onClose, onSave, parsedTokens]);
176
+ }, [format, knownDateFields, onClose, onSave, parsedTokens]);
138
177
 
139
178
  const validationError = unknownFieldErrors[0] ?? formulaValidation.errors[0] ?? '';
140
179
  const isInvalid = !formulaValidation.valid || unknownFieldErrors.length > 0;
@@ -164,6 +203,7 @@ export const FormulaModal: FC<FormulaModalProps> = ({
164
203
  selectedPaths={formulaEditor.selectedFieldPaths}
165
204
  />
166
205
  <FormulaWorkspace
206
+ disabledOperators={formulaEditor.disabledOperators}
167
207
  editorRef={formulaEditor.editorRef}
168
208
  isInvalid={isInvalid && formulaEditor.isDirty}
169
209
  validationError={validationError}