@qrvey/utils 1.17.4 → 1.17.5

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.
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # [@qrvey/utils](https://bitbucket.org/qrvey/qrvey_utils/wiki/Home) *1.17.4*
1
+ # [@qrvey/utils](https://bitbucket.org/qrvey/qrvey_utils/wiki/Home) *1.17.5*
2
2
 
3
3
  > Helper, Utils for all Qrvey Projects
4
4
 
@@ -0,0 +1,368 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.REFERENCE_COLUMN_MARKER = exports.DELTA_COLUMN_PREFIX = void 0;
4
+ exports.formatDeltaColumnCaption = formatDeltaColumnCaption;
5
+ exports.formatReferenceColumnCaption = formatReferenceColumnCaption;
6
+ exports.resolveComparativeColumnCaption = resolveComparativeColumnCaption;
7
+ exports.formatComparativePeriodCaption = formatComparativePeriodCaption;
8
+ exports.formatDeltaDefaultCaption = formatDeltaDefaultCaption;
9
+ exports.computeComparativeVirtualColumns = computeComparativeVirtualColumns;
10
+ exports.expandColumnListWithComparativeColumns = expandColumnListWithComparativeColumns;
11
+ exports.applyComparativeHeaderBorders = applyComparativeHeaderBorders;
12
+ exports.mapOperatorToValidationType = mapOperatorToValidationType;
13
+ exports.buildComparisonExpressionValue = buildComparisonExpressionValue;
14
+ exports.buildComparativeChartComparison = buildComparativeChartComparison;
15
+ exports.resolveDeltaDiffInfo = resolveDeltaDiffInfo;
16
+ const get_1 = require("../general/object/get");
17
+ exports.DELTA_COLUMN_PREFIX = "\u0394";
18
+ exports.REFERENCE_COLUMN_MARKER = "\u25CF";
19
+ function formatDeltaColumnCaption(caption) {
20
+ return `${exports.DELTA_COLUMN_PREFIX} ${caption}`;
21
+ }
22
+ function formatReferenceColumnCaption(caption) {
23
+ return `${exports.REFERENCE_COLUMN_MARKER} ${caption}`;
24
+ }
25
+ function resolveComparativeColumnCaption(chartModel, columnKey, allDatesText) {
26
+ const fallbackAllDates = allDatesText || "All dates";
27
+ const columnsList = chartModel?.chart?.fields?.columnsList ??
28
+ (0, get_1._get)(chartModel, "data.chart.fields.columnsList") ??
29
+ [];
30
+ const comparativeAnalisis = (0, get_1._get)(chartModel, "store.comparativeAnalisis") ??
31
+ chartModel?.v2?.comparativeAnalisis ??
32
+ (0, get_1._get)(chartModel, "data.v2.comparativeAnalisis") ??
33
+ {};
34
+ const suffixMatch = columnKey.match(/^(.+?)__(comp|delta(?:_(\d+))?)$/);
35
+ if (!suffixMatch) {
36
+ const col = columnsList.find((c) => c.data?.uniqueCode === columnKey) ??
37
+ columnsList.find((c) => c.dataField === columnKey);
38
+ return col?.label || col?.data?.text || columnKey;
39
+ }
40
+ const baseKey = suffixMatch[1];
41
+ const suffixType = suffixMatch[2];
42
+ const deltaIndexStr = suffixMatch[3];
43
+ const deltaIndex = deltaIndexStr ? parseInt(deltaIndexStr, 10) : 0;
44
+ const refCol = columnsList.find((c) => c.data?.uniqueCode === baseKey) ??
45
+ columnsList.find((c) => c.dataField === baseKey);
46
+ if (!refCol)
47
+ return columnKey;
48
+ const defaultName = refCol.data?.text ?? "";
49
+ const uniqueCode = refCol.data?.uniqueCode ?? "";
50
+ const refDataField = refCol.dataField ?? "";
51
+ const customLabels = (0, get_1._get)(comparativeAnalisis, "customColumnLabels") ?? {};
52
+ const dataFieldKey = refDataField
53
+ ? `${refDataField}__${suffixType}`
54
+ : columnKey;
55
+ if (suffixType === "comp") {
56
+ return (customLabels[dataFieldKey] ??
57
+ formatComparativePeriodCaption(comparativeAnalisis.compareTo, fallbackAllDates, defaultName));
58
+ }
59
+ const diffCols = comparativeAnalisis?.styles?.columnDiffs?.[uniqueCode] ?? [];
60
+ const diffCol = diffCols[deltaIndex];
61
+ const hasConfiguredDiffs = comparativeAnalisis?.styles?.columnDiffs?.[uniqueCode] != null;
62
+ const diffName = diffCol?.name?.trim() || null;
63
+ if (hasConfiguredDiffs) {
64
+ if (diffName)
65
+ return formatDeltaColumnCaption(diffName);
66
+ return formatDeltaDefaultCaption(comparativeAnalisis.referencePeriod, comparativeAnalisis.compareTo, fallbackAllDates, defaultName);
67
+ }
68
+ if (diffName)
69
+ return formatDeltaColumnCaption(diffName);
70
+ if (customLabels[dataFieldKey])
71
+ return formatDeltaColumnCaption(customLabels[dataFieldKey]);
72
+ return formatDeltaDefaultCaption(comparativeAnalisis.referencePeriod, comparativeAnalisis.compareTo, fallbackAllDates, defaultName);
73
+ }
74
+ function formatComparativePeriodCaption(period, allDatesText, colLabel = "") {
75
+ if (!period?.date1) {
76
+ return colLabel ? `${colLabel} - ${allDatesText}` : allDatesText;
77
+ }
78
+ const dateRange = period.date2
79
+ ? `${period.date1}-${period.date2}`
80
+ : period.date1;
81
+ return colLabel ? `${colLabel} - ${dateRange}` : dateRange;
82
+ }
83
+ function formatDeltaDefaultCaption(referencePeriod, compareTo, allDatesText, colLabel = "") {
84
+ const fmtPeriodFn = (p) => {
85
+ if (!p?.date1)
86
+ return allDatesText;
87
+ return p.date2 ? `${p.date1}-${p.date2}` : p.date1;
88
+ };
89
+ const ref = fmtPeriodFn(referencePeriod);
90
+ const cmp = fmtPeriodFn(compareTo);
91
+ const comparison = ref && cmp ? `${ref} vs ${cmp}` : ref || cmp;
92
+ const prefix = colLabel ? `${exports.DELTA_COLUMN_PREFIX} ${colLabel}` : exports.DELTA_COLUMN_PREFIX;
93
+ return comparison ? `${prefix} - ${comparison}` : prefix;
94
+ }
95
+ function computeComparativeVirtualColumns(isGrouped, myBus, chart, getChartColumns) {
96
+ if (!isGrouped)
97
+ return [];
98
+ const isActive = (0, get_1._get)(myBus, "store.comparativeAnalisis.enabled", (0, get_1._get)(chart, "data.v2.comparativeAnalisis.enabled")) === true;
99
+ const compareVisible = (0, get_1._get)(myBus, "store.comparativeAnalisis.compareVisible", (0, get_1._get)(chart, "data.v2.comparativeAnalisis.compareVisible", true));
100
+ if (!isActive || compareVisible === false)
101
+ return [];
102
+ const referenceColumnCodes = (0, get_1._get)(myBus, "store.comparativeAnalisis.referenceColumns", (0, get_1._get)(chart, "data.v2.comparativeAnalisis.referenceColumns", [])) || [];
103
+ if (!referenceColumnCodes.length)
104
+ return [];
105
+ const ca = (0, get_1._get)(myBus, "store.comparativeAnalisis") ??
106
+ (0, get_1._get)(chart, "data.v2.comparativeAnalisis") ??
107
+ {};
108
+ const columnList = getChartColumns();
109
+ const result = [];
110
+ columnList.forEach((col, i) => {
111
+ if (!referenceColumnCodes.includes(col.data?.uniqueCode))
112
+ return;
113
+ const uniqueCode = col.data?.uniqueCode;
114
+ const colDiffs = ca?.styles != null
115
+ ? (ca.styles.columnDiffs?.[uniqueCode] ?? [{ id: "default" }])
116
+ : [{ id: "default" }];
117
+ const extraDeltaDataFields = colDiffs
118
+ .slice(1)
119
+ .map((_, j) => `${col.dataField}__delta_${j + 1}`);
120
+ result.push({
121
+ originalDataField: col.dataField,
122
+ originalIndex: i,
123
+ compDataField: `${col.dataField}__comp`,
124
+ ...(colDiffs.length > 0
125
+ ? {
126
+ deltaDataField: `${col.dataField}__delta`,
127
+ extraDeltaDataFields: extraDeltaDataFields.length
128
+ ? extraDeltaDataFields
129
+ : undefined,
130
+ }
131
+ : {}),
132
+ });
133
+ });
134
+ return result;
135
+ }
136
+ function expandColumnListWithComparativeColumns(columnList, comparativeVirtualColumns, myBus, chart, allDatesText) {
137
+ if (!comparativeVirtualColumns?.length)
138
+ return columnList;
139
+ const comparativeData = (0, get_1._get)(myBus, "store.comparativeAnalisis", (0, get_1._get)(chart, "data.v2.comparativeAnalisis", {})) || {};
140
+ const fallbackAllDates = allDatesText || "All dates";
141
+ const result = [];
142
+ for (const col of columnList) {
143
+ const vc = comparativeVirtualColumns.find((v) => v.originalDataField === col.dataField);
144
+ if (!vc) {
145
+ result.push(col);
146
+ }
147
+ else {
148
+ const defaultName = col.data?.text ?? "";
149
+ const hasCustomLabel = typeof col.label === "string" &&
150
+ col.label.trim().length > 0 &&
151
+ col.label.trim() !== defaultName.trim();
152
+ const refLabel = hasCustomLabel
153
+ ? col.label
154
+ : formatComparativePeriodCaption(comparativeData.referencePeriod, fallbackAllDates, defaultName);
155
+ const customLabels = (0, get_1._get)(myBus, "store.comparativeAnalisis.customColumnLabels") ??
156
+ (0, get_1._get)(chart, "data.v2.comparativeAnalisis.customColumnLabels") ??
157
+ {};
158
+ const uniqueCode = col.data?.uniqueCode ?? "";
159
+ const diffCols = comparativeData?.styles != null
160
+ ? (comparativeData.styles.columnDiffs?.[uniqueCode] ?? [
161
+ { id: "default", name: "" },
162
+ ])
163
+ : [{ id: "default", name: "" }];
164
+ const hasConfiguredDiffs = comparativeData?.styles?.columnDiffs?.[uniqueCode] != null;
165
+ const compLabel = customLabels[vc.compDataField] ??
166
+ formatComparativePeriodCaption(comparativeData.compareTo, fallbackAllDates, defaultName);
167
+ result.push({
168
+ ...col,
169
+ _comparativeLabel: refLabel,
170
+ _originalColIndex: vc.originalIndex,
171
+ });
172
+ result.push({
173
+ ...col,
174
+ dataField: vc.compDataField,
175
+ label: compLabel,
176
+ _isVirtualComparative: true,
177
+ _virtualType: "comp",
178
+ _originalDataField: vc.originalDataField,
179
+ _originalColIndex: vc.originalIndex,
180
+ });
181
+ if (vc.deltaDataField) {
182
+ const firstDiffName = diffCols[0]?.name?.trim() || "";
183
+ const resolvedFirstName = firstDiffName || null;
184
+ const deltaLabel = hasConfiguredDiffs
185
+ ? (resolvedFirstName ??
186
+ formatDeltaDefaultCaption(comparativeData.referencePeriod, comparativeData.compareTo, fallbackAllDates, defaultName))
187
+ : (resolvedFirstName ??
188
+ customLabels[vc.deltaDataField] ??
189
+ formatDeltaDefaultCaption(comparativeData.referencePeriod, comparativeData.compareTo, fallbackAllDates, defaultName));
190
+ result.push({
191
+ ...col,
192
+ dataField: vc.deltaDataField,
193
+ label: deltaLabel,
194
+ _isVirtualComparative: true,
195
+ _virtualType: "delta",
196
+ _diffColStyleIndex: 0,
197
+ _originalDataField: vc.originalDataField,
198
+ _originalColIndex: vc.originalIndex,
199
+ });
200
+ }
201
+ (vc.extraDeltaDataFields ?? []).forEach((df, j) => {
202
+ const styleIndex = j + 1;
203
+ const extraDiffName = diffCols[styleIndex]?.name?.trim() || "";
204
+ const resolvedExtraName = extraDiffName || null;
205
+ const extraLabel = hasConfiguredDiffs
206
+ ? (resolvedExtraName ??
207
+ formatDeltaDefaultCaption(comparativeData.referencePeriod, comparativeData.compareTo, fallbackAllDates, defaultName))
208
+ : (resolvedExtraName ??
209
+ customLabels[df] ??
210
+ formatDeltaDefaultCaption(comparativeData.referencePeriod, comparativeData.compareTo, fallbackAllDates, defaultName));
211
+ result.push({
212
+ ...col,
213
+ dataField: df,
214
+ label: extraLabel,
215
+ _isVirtualComparative: true,
216
+ _virtualType: "delta",
217
+ _diffColStyleIndex: styleIndex,
218
+ _originalDataField: vc.originalDataField,
219
+ _originalColIndex: vc.originalIndex,
220
+ });
221
+ });
222
+ }
223
+ }
224
+ return result;
225
+ }
226
+ function applyComparativeHeaderBorders(columns, myBus, chart) {
227
+ const tableBodyStyle = (0, get_1._get)(myBus, "store.stylesSettings.tableBodyStyle") ||
228
+ (0, get_1._get)(chart, "data.v2.stylesSettings.tableBodyStyle") ||
229
+ {};
230
+ const hasVerticalBorder = tableBodyStyle.verticalBorder === undefined ||
231
+ tableBodyStyle.verticalBorder === null
232
+ ? true
233
+ : tableBodyStyle.verticalBorder;
234
+ const borderColor = tableBodyStyle.borderColor || "#CACFD6";
235
+ return columns.map((col) => {
236
+ if (!col?.headerCellTemplate)
237
+ return col;
238
+ const origTemplate = col.headerCellTemplate;
239
+ return {
240
+ ...col,
241
+ headerCellTemplate: (columnHeader, cellInfo) => {
242
+ origTemplate(columnHeader, cellInfo);
243
+ if (col._comparativeLabel) {
244
+ const titleEl = columnHeader.querySelector(".an-header-title-text");
245
+ if (titleEl)
246
+ titleEl.textContent = `${exports.REFERENCE_COLUMN_MARKER} ${col._comparativeLabel}`;
247
+ }
248
+ const totalCols = cellInfo.component?.columnCount?.() ?? 0;
249
+ if (hasVerticalBorder && cellInfo.columnIndex < totalCols - 1) {
250
+ columnHeader.parentElement?.style.setProperty("border-right", `1px solid ${borderColor}`);
251
+ }
252
+ else {
253
+ columnHeader.parentElement?.style.setProperty("border-right", "1px solid transparent");
254
+ }
255
+ },
256
+ };
257
+ });
258
+ }
259
+ function mapOperatorToValidationType(operatorLabel) {
260
+ if (!operatorLabel)
261
+ return "EQUAL";
262
+ switch (operatorLabel) {
263
+ case "EQUAL":
264
+ return "EQUAL";
265
+ case "DOES_NOT_EQUAL":
266
+ return "NOT_EQUAL";
267
+ case "BETWEEN_INCLUSIVE":
268
+ case "BETWEEN_EXCLUSIVE":
269
+ case "BETWEEN":
270
+ case "GREATER_THAN":
271
+ case "LESS_THAN":
272
+ case "GREATER_THAN_OR_EQUAL":
273
+ case "LESS_THAN_OR_EQUAL":
274
+ case "BEFORE":
275
+ case "AFTER":
276
+ case "BEFORE_OR_ON":
277
+ case "AFTER_OR_ON":
278
+ return "RANGE";
279
+ case "IS_NULL":
280
+ return "IS_EMPTY";
281
+ case "IS_NOT_NULL":
282
+ return "IS_NOT_EMPTY";
283
+ default:
284
+ return "EQUAL";
285
+ }
286
+ }
287
+ function buildComparisonExpressionValue(date1, date2, operatorLabel) {
288
+ switch (operatorLabel) {
289
+ case "EQUAL":
290
+ case "DOES_NOT_EQUAL":
291
+ return date1 ? [date1] : [];
292
+ case "BETWEEN_INCLUSIVE":
293
+ return date1 && date2 ? [{ gte: date1, lte: date2 }] : [];
294
+ case "BETWEEN_EXCLUSIVE":
295
+ case "BETWEEN":
296
+ return date1 && date2 ? [{ gt: date1, lt: date2 }] : [];
297
+ case "GREATER_THAN":
298
+ case "AFTER":
299
+ return date1 ? [{ gt: date1 }] : [];
300
+ case "GREATER_THAN_OR_EQUAL":
301
+ case "AFTER_OR_ON":
302
+ return date1 ? [{ gte: date1 }] : [];
303
+ case "LESS_THAN":
304
+ case "BEFORE":
305
+ return date1 ? [{ lt: date1 }] : [];
306
+ case "LESS_THAN_OR_EQUAL":
307
+ case "BEFORE_OR_ON":
308
+ return date1 ? [{ lte: date1 }] : [];
309
+ default:
310
+ return [];
311
+ }
312
+ }
313
+ function buildComparativeChartComparison(myBus, chart, groups) {
314
+ const comparativeData = (0, get_1._get)(myBus, "store.comparativeAnalisis", (0, get_1._get)(chart, "data.v2.comparativeAnalisis", {})) || {};
315
+ const { dateColumn, referencePeriod, compareTo } = comparativeData;
316
+ if (!dateColumn)
317
+ return undefined;
318
+ const dateGroup = groups.find((g) => g.data.id === dateColumn);
319
+ const qrveyid = dateGroup?.data?.qrveyid;
320
+ const questionType = dateGroup?.data?.type || "DATE";
321
+ const buildExpression = (periodData) => {
322
+ if (!periodData || !periodData.operator)
323
+ return null;
324
+ const operatorLabel = periodData.operator.label;
325
+ const isNullType = operatorLabel === "IS_NULL" || operatorLabel === "IS_NOT_NULL";
326
+ if (!isNullType && !periodData.date1)
327
+ return null;
328
+ const validationType = mapOperatorToValidationType(operatorLabel);
329
+ const expression = {
330
+ groupValue: "day",
331
+ questionid: dateColumn,
332
+ qrveyid,
333
+ questionType,
334
+ validationType,
335
+ enabled: true,
336
+ };
337
+ if (!isNullType) {
338
+ expression.value = buildComparisonExpressionValue(periodData.date1, periodData.date2, operatorLabel);
339
+ }
340
+ return expression;
341
+ };
342
+ return {
343
+ comparison: buildExpression(compareTo),
344
+ period: buildExpression(referencePeriod),
345
+ };
346
+ }
347
+ function resolveDeltaDiffInfo(dataField, comparativeVirtualColumns, getChartColumns) {
348
+ for (const vc of comparativeVirtualColumns) {
349
+ if (vc.deltaDataField === dataField) {
350
+ const chartCols = getChartColumns();
351
+ const refCol = chartCols.find((c) => c.dataField === vc.originalDataField);
352
+ return {
353
+ origUniqueCode: refCol?.data?.uniqueCode ?? "",
354
+ diffIndex: 0,
355
+ };
356
+ }
357
+ const extraIdx = (vc.extraDeltaDataFields ?? []).indexOf(dataField);
358
+ if (extraIdx !== -1) {
359
+ const chartCols = getChartColumns();
360
+ const refCol = chartCols.find((c) => c.dataField === vc.originalDataField);
361
+ return {
362
+ origUniqueCode: refCol?.data?.uniqueCode ?? "",
363
+ diffIndex: extraIdx + 1,
364
+ };
365
+ }
366
+ }
367
+ return { origUniqueCode: "", diffIndex: -1 };
368
+ }
package/dist/cjs/index.js CHANGED
@@ -20,3 +20,4 @@ tslib_1.__exportStar(require("./tokens/index"), exports);
20
20
  tslib_1.__exportStar(require("./column_format/index"), exports);
21
21
  tslib_1.__exportStar(require("./themes/index"), exports);
22
22
  tslib_1.__exportStar(require("./elements/index"), exports);
23
+ tslib_1.__exportStar(require("./comparativeAnalysis/index"), exports);
@@ -0,0 +1,24 @@
1
+ export declare const DELTA_COLUMN_PREFIX = "\u0394";
2
+ export declare const REFERENCE_COLUMN_MARKER = "\u25CF";
3
+ export declare function formatDeltaColumnCaption(caption: string): string;
4
+ export declare function formatReferenceColumnCaption(caption: string): string;
5
+ export declare function resolveComparativeColumnCaption(chartModel: any, columnKey: string, allDatesText?: string): string;
6
+ export interface ComparativeVirtualColumn {
7
+ originalDataField: string;
8
+ originalIndex: number;
9
+ compDataField: string;
10
+ deltaDataField?: string;
11
+ extraDeltaDataFields?: string[];
12
+ }
13
+ export declare function formatComparativePeriodCaption(period: any, allDatesText: string, colLabel?: string): string;
14
+ export declare function formatDeltaDefaultCaption(referencePeriod: any, compareTo: any, allDatesText: string, colLabel?: string): string;
15
+ export declare function computeComparativeVirtualColumns(isGrouped: boolean, myBus: any, chart: any, getChartColumns: () => any[]): ComparativeVirtualColumn[];
16
+ export declare function expandColumnListWithComparativeColumns(columnList: any[], comparativeVirtualColumns: ComparativeVirtualColumn[], myBus: any, chart: any, allDatesText?: string): any[];
17
+ export declare function applyComparativeHeaderBorders(columns: any[], myBus: any, chart: any): any[];
18
+ export declare function mapOperatorToValidationType(operatorLabel: string): string;
19
+ export declare function buildComparisonExpressionValue(date1: string | null, date2: string | null, operatorLabel: string): Array<string | Record<string, string>>;
20
+ export declare function buildComparativeChartComparison(myBus: any, chart: any, groups: any[]): object | undefined;
21
+ export declare function resolveDeltaDiffInfo(dataField: string, comparativeVirtualColumns: ComparativeVirtualColumn[], getChartColumns: () => any[]): {
22
+ origUniqueCode: string;
23
+ diffIndex: number;
24
+ };
@@ -0,0 +1,353 @@
1
+ import { _get } from "../general/object/get";
2
+ export const DELTA_COLUMN_PREFIX = "\u0394";
3
+ export const REFERENCE_COLUMN_MARKER = "\u25CF";
4
+ export function formatDeltaColumnCaption(caption) {
5
+ return `${DELTA_COLUMN_PREFIX} ${caption}`;
6
+ }
7
+ export function formatReferenceColumnCaption(caption) {
8
+ return `${REFERENCE_COLUMN_MARKER} ${caption}`;
9
+ }
10
+ export function resolveComparativeColumnCaption(chartModel, columnKey, allDatesText) {
11
+ const fallbackAllDates = allDatesText || "All dates";
12
+ const columnsList = chartModel?.chart?.fields?.columnsList ??
13
+ _get(chartModel, "data.chart.fields.columnsList") ??
14
+ [];
15
+ const comparativeAnalisis = _get(chartModel, "store.comparativeAnalisis") ??
16
+ chartModel?.v2?.comparativeAnalisis ??
17
+ _get(chartModel, "data.v2.comparativeAnalisis") ??
18
+ {};
19
+ const suffixMatch = columnKey.match(/^(.+?)__(comp|delta(?:_(\d+))?)$/);
20
+ if (!suffixMatch) {
21
+ const col = columnsList.find((c) => c.data?.uniqueCode === columnKey) ??
22
+ columnsList.find((c) => c.dataField === columnKey);
23
+ return col?.label || col?.data?.text || columnKey;
24
+ }
25
+ const baseKey = suffixMatch[1];
26
+ const suffixType = suffixMatch[2];
27
+ const deltaIndexStr = suffixMatch[3];
28
+ const deltaIndex = deltaIndexStr ? parseInt(deltaIndexStr, 10) : 0;
29
+ const refCol = columnsList.find((c) => c.data?.uniqueCode === baseKey) ??
30
+ columnsList.find((c) => c.dataField === baseKey);
31
+ if (!refCol)
32
+ return columnKey;
33
+ const defaultName = refCol.data?.text ?? "";
34
+ const uniqueCode = refCol.data?.uniqueCode ?? "";
35
+ const refDataField = refCol.dataField ?? "";
36
+ const customLabels = _get(comparativeAnalisis, "customColumnLabels") ?? {};
37
+ const dataFieldKey = refDataField
38
+ ? `${refDataField}__${suffixType}`
39
+ : columnKey;
40
+ if (suffixType === "comp") {
41
+ return (customLabels[dataFieldKey] ??
42
+ formatComparativePeriodCaption(comparativeAnalisis.compareTo, fallbackAllDates, defaultName));
43
+ }
44
+ const diffCols = comparativeAnalisis?.styles?.columnDiffs?.[uniqueCode] ?? [];
45
+ const diffCol = diffCols[deltaIndex];
46
+ const hasConfiguredDiffs = comparativeAnalisis?.styles?.columnDiffs?.[uniqueCode] != null;
47
+ const diffName = diffCol?.name?.trim() || null;
48
+ if (hasConfiguredDiffs) {
49
+ if (diffName)
50
+ return formatDeltaColumnCaption(diffName);
51
+ return formatDeltaDefaultCaption(comparativeAnalisis.referencePeriod, comparativeAnalisis.compareTo, fallbackAllDates, defaultName);
52
+ }
53
+ if (diffName)
54
+ return formatDeltaColumnCaption(diffName);
55
+ if (customLabels[dataFieldKey])
56
+ return formatDeltaColumnCaption(customLabels[dataFieldKey]);
57
+ return formatDeltaDefaultCaption(comparativeAnalisis.referencePeriod, comparativeAnalisis.compareTo, fallbackAllDates, defaultName);
58
+ }
59
+ export function formatComparativePeriodCaption(period, allDatesText, colLabel = "") {
60
+ if (!period?.date1) {
61
+ return colLabel ? `${colLabel} - ${allDatesText}` : allDatesText;
62
+ }
63
+ const dateRange = period.date2
64
+ ? `${period.date1}-${period.date2}`
65
+ : period.date1;
66
+ return colLabel ? `${colLabel} - ${dateRange}` : dateRange;
67
+ }
68
+ export function formatDeltaDefaultCaption(referencePeriod, compareTo, allDatesText, colLabel = "") {
69
+ const fmtPeriodFn = (p) => {
70
+ if (!p?.date1)
71
+ return allDatesText;
72
+ return p.date2 ? `${p.date1}-${p.date2}` : p.date1;
73
+ };
74
+ const ref = fmtPeriodFn(referencePeriod);
75
+ const cmp = fmtPeriodFn(compareTo);
76
+ const comparison = ref && cmp ? `${ref} vs ${cmp}` : ref || cmp;
77
+ const prefix = colLabel ? `${DELTA_COLUMN_PREFIX} ${colLabel}` : DELTA_COLUMN_PREFIX;
78
+ return comparison ? `${prefix} - ${comparison}` : prefix;
79
+ }
80
+ export function computeComparativeVirtualColumns(isGrouped, myBus, chart, getChartColumns) {
81
+ if (!isGrouped)
82
+ return [];
83
+ const isActive = _get(myBus, "store.comparativeAnalisis.enabled", _get(chart, "data.v2.comparativeAnalisis.enabled")) === true;
84
+ const compareVisible = _get(myBus, "store.comparativeAnalisis.compareVisible", _get(chart, "data.v2.comparativeAnalisis.compareVisible", true));
85
+ if (!isActive || compareVisible === false)
86
+ return [];
87
+ const referenceColumnCodes = _get(myBus, "store.comparativeAnalisis.referenceColumns", _get(chart, "data.v2.comparativeAnalisis.referenceColumns", [])) || [];
88
+ if (!referenceColumnCodes.length)
89
+ return [];
90
+ const ca = _get(myBus, "store.comparativeAnalisis") ??
91
+ _get(chart, "data.v2.comparativeAnalisis") ??
92
+ {};
93
+ const columnList = getChartColumns();
94
+ const result = [];
95
+ columnList.forEach((col, i) => {
96
+ if (!referenceColumnCodes.includes(col.data?.uniqueCode))
97
+ return;
98
+ const uniqueCode = col.data?.uniqueCode;
99
+ const colDiffs = ca?.styles != null
100
+ ? (ca.styles.columnDiffs?.[uniqueCode] ?? [{ id: "default" }])
101
+ : [{ id: "default" }];
102
+ const extraDeltaDataFields = colDiffs
103
+ .slice(1)
104
+ .map((_, j) => `${col.dataField}__delta_${j + 1}`);
105
+ result.push({
106
+ originalDataField: col.dataField,
107
+ originalIndex: i,
108
+ compDataField: `${col.dataField}__comp`,
109
+ ...(colDiffs.length > 0
110
+ ? {
111
+ deltaDataField: `${col.dataField}__delta`,
112
+ extraDeltaDataFields: extraDeltaDataFields.length
113
+ ? extraDeltaDataFields
114
+ : undefined,
115
+ }
116
+ : {}),
117
+ });
118
+ });
119
+ return result;
120
+ }
121
+ export function expandColumnListWithComparativeColumns(columnList, comparativeVirtualColumns, myBus, chart, allDatesText) {
122
+ if (!comparativeVirtualColumns?.length)
123
+ return columnList;
124
+ const comparativeData = _get(myBus, "store.comparativeAnalisis", _get(chart, "data.v2.comparativeAnalisis", {})) || {};
125
+ const fallbackAllDates = allDatesText || "All dates";
126
+ const result = [];
127
+ for (const col of columnList) {
128
+ const vc = comparativeVirtualColumns.find((v) => v.originalDataField === col.dataField);
129
+ if (!vc) {
130
+ result.push(col);
131
+ }
132
+ else {
133
+ const defaultName = col.data?.text ?? "";
134
+ const hasCustomLabel = typeof col.label === "string" &&
135
+ col.label.trim().length > 0 &&
136
+ col.label.trim() !== defaultName.trim();
137
+ const refLabel = hasCustomLabel
138
+ ? col.label
139
+ : formatComparativePeriodCaption(comparativeData.referencePeriod, fallbackAllDates, defaultName);
140
+ const customLabels = _get(myBus, "store.comparativeAnalisis.customColumnLabels") ??
141
+ _get(chart, "data.v2.comparativeAnalisis.customColumnLabels") ??
142
+ {};
143
+ const uniqueCode = col.data?.uniqueCode ?? "";
144
+ const diffCols = comparativeData?.styles != null
145
+ ? (comparativeData.styles.columnDiffs?.[uniqueCode] ?? [
146
+ { id: "default", name: "" },
147
+ ])
148
+ : [{ id: "default", name: "" }];
149
+ const hasConfiguredDiffs = comparativeData?.styles?.columnDiffs?.[uniqueCode] != null;
150
+ const compLabel = customLabels[vc.compDataField] ??
151
+ formatComparativePeriodCaption(comparativeData.compareTo, fallbackAllDates, defaultName);
152
+ result.push({
153
+ ...col,
154
+ _comparativeLabel: refLabel,
155
+ _originalColIndex: vc.originalIndex,
156
+ });
157
+ result.push({
158
+ ...col,
159
+ dataField: vc.compDataField,
160
+ label: compLabel,
161
+ _isVirtualComparative: true,
162
+ _virtualType: "comp",
163
+ _originalDataField: vc.originalDataField,
164
+ _originalColIndex: vc.originalIndex,
165
+ });
166
+ if (vc.deltaDataField) {
167
+ const firstDiffName = diffCols[0]?.name?.trim() || "";
168
+ const resolvedFirstName = firstDiffName || null;
169
+ const deltaLabel = hasConfiguredDiffs
170
+ ? (resolvedFirstName ??
171
+ formatDeltaDefaultCaption(comparativeData.referencePeriod, comparativeData.compareTo, fallbackAllDates, defaultName))
172
+ : (resolvedFirstName ??
173
+ customLabels[vc.deltaDataField] ??
174
+ formatDeltaDefaultCaption(comparativeData.referencePeriod, comparativeData.compareTo, fallbackAllDates, defaultName));
175
+ result.push({
176
+ ...col,
177
+ dataField: vc.deltaDataField,
178
+ label: deltaLabel,
179
+ _isVirtualComparative: true,
180
+ _virtualType: "delta",
181
+ _diffColStyleIndex: 0,
182
+ _originalDataField: vc.originalDataField,
183
+ _originalColIndex: vc.originalIndex,
184
+ });
185
+ }
186
+ (vc.extraDeltaDataFields ?? []).forEach((df, j) => {
187
+ const styleIndex = j + 1;
188
+ const extraDiffName = diffCols[styleIndex]?.name?.trim() || "";
189
+ const resolvedExtraName = extraDiffName || null;
190
+ const extraLabel = hasConfiguredDiffs
191
+ ? (resolvedExtraName ??
192
+ formatDeltaDefaultCaption(comparativeData.referencePeriod, comparativeData.compareTo, fallbackAllDates, defaultName))
193
+ : (resolvedExtraName ??
194
+ customLabels[df] ??
195
+ formatDeltaDefaultCaption(comparativeData.referencePeriod, comparativeData.compareTo, fallbackAllDates, defaultName));
196
+ result.push({
197
+ ...col,
198
+ dataField: df,
199
+ label: extraLabel,
200
+ _isVirtualComparative: true,
201
+ _virtualType: "delta",
202
+ _diffColStyleIndex: styleIndex,
203
+ _originalDataField: vc.originalDataField,
204
+ _originalColIndex: vc.originalIndex,
205
+ });
206
+ });
207
+ }
208
+ }
209
+ return result;
210
+ }
211
+ export function applyComparativeHeaderBorders(columns, myBus, chart) {
212
+ const tableBodyStyle = _get(myBus, "store.stylesSettings.tableBodyStyle") ||
213
+ _get(chart, "data.v2.stylesSettings.tableBodyStyle") ||
214
+ {};
215
+ const hasVerticalBorder = tableBodyStyle.verticalBorder === undefined ||
216
+ tableBodyStyle.verticalBorder === null
217
+ ? true
218
+ : tableBodyStyle.verticalBorder;
219
+ const borderColor = tableBodyStyle.borderColor || "#CACFD6";
220
+ return columns.map((col) => {
221
+ if (!col?.headerCellTemplate)
222
+ return col;
223
+ const origTemplate = col.headerCellTemplate;
224
+ return {
225
+ ...col,
226
+ headerCellTemplate: (columnHeader, cellInfo) => {
227
+ origTemplate(columnHeader, cellInfo);
228
+ if (col._comparativeLabel) {
229
+ const titleEl = columnHeader.querySelector(".an-header-title-text");
230
+ if (titleEl)
231
+ titleEl.textContent = `${REFERENCE_COLUMN_MARKER} ${col._comparativeLabel}`;
232
+ }
233
+ const totalCols = cellInfo.component?.columnCount?.() ?? 0;
234
+ if (hasVerticalBorder && cellInfo.columnIndex < totalCols - 1) {
235
+ columnHeader.parentElement?.style.setProperty("border-right", `1px solid ${borderColor}`);
236
+ }
237
+ else {
238
+ columnHeader.parentElement?.style.setProperty("border-right", "1px solid transparent");
239
+ }
240
+ },
241
+ };
242
+ });
243
+ }
244
+ export function mapOperatorToValidationType(operatorLabel) {
245
+ if (!operatorLabel)
246
+ return "EQUAL";
247
+ switch (operatorLabel) {
248
+ case "EQUAL":
249
+ return "EQUAL";
250
+ case "DOES_NOT_EQUAL":
251
+ return "NOT_EQUAL";
252
+ case "BETWEEN_INCLUSIVE":
253
+ case "BETWEEN_EXCLUSIVE":
254
+ case "BETWEEN":
255
+ case "GREATER_THAN":
256
+ case "LESS_THAN":
257
+ case "GREATER_THAN_OR_EQUAL":
258
+ case "LESS_THAN_OR_EQUAL":
259
+ case "BEFORE":
260
+ case "AFTER":
261
+ case "BEFORE_OR_ON":
262
+ case "AFTER_OR_ON":
263
+ return "RANGE";
264
+ case "IS_NULL":
265
+ return "IS_EMPTY";
266
+ case "IS_NOT_NULL":
267
+ return "IS_NOT_EMPTY";
268
+ default:
269
+ return "EQUAL";
270
+ }
271
+ }
272
+ export function buildComparisonExpressionValue(date1, date2, operatorLabel) {
273
+ switch (operatorLabel) {
274
+ case "EQUAL":
275
+ case "DOES_NOT_EQUAL":
276
+ return date1 ? [date1] : [];
277
+ case "BETWEEN_INCLUSIVE":
278
+ return date1 && date2 ? [{ gte: date1, lte: date2 }] : [];
279
+ case "BETWEEN_EXCLUSIVE":
280
+ case "BETWEEN":
281
+ return date1 && date2 ? [{ gt: date1, lt: date2 }] : [];
282
+ case "GREATER_THAN":
283
+ case "AFTER":
284
+ return date1 ? [{ gt: date1 }] : [];
285
+ case "GREATER_THAN_OR_EQUAL":
286
+ case "AFTER_OR_ON":
287
+ return date1 ? [{ gte: date1 }] : [];
288
+ case "LESS_THAN":
289
+ case "BEFORE":
290
+ return date1 ? [{ lt: date1 }] : [];
291
+ case "LESS_THAN_OR_EQUAL":
292
+ case "BEFORE_OR_ON":
293
+ return date1 ? [{ lte: date1 }] : [];
294
+ default:
295
+ return [];
296
+ }
297
+ }
298
+ export function buildComparativeChartComparison(myBus, chart, groups) {
299
+ const comparativeData = _get(myBus, "store.comparativeAnalisis", _get(chart, "data.v2.comparativeAnalisis", {})) || {};
300
+ const { dateColumn, referencePeriod, compareTo } = comparativeData;
301
+ if (!dateColumn)
302
+ return undefined;
303
+ const dateGroup = groups.find((g) => g.data.id === dateColumn);
304
+ const qrveyid = dateGroup?.data?.qrveyid;
305
+ const questionType = dateGroup?.data?.type || "DATE";
306
+ const buildExpression = (periodData) => {
307
+ if (!periodData || !periodData.operator)
308
+ return null;
309
+ const operatorLabel = periodData.operator.label;
310
+ const isNullType = operatorLabel === "IS_NULL" || operatorLabel === "IS_NOT_NULL";
311
+ if (!isNullType && !periodData.date1)
312
+ return null;
313
+ const validationType = mapOperatorToValidationType(operatorLabel);
314
+ const expression = {
315
+ groupValue: "day",
316
+ questionid: dateColumn,
317
+ qrveyid,
318
+ questionType,
319
+ validationType,
320
+ enabled: true,
321
+ };
322
+ if (!isNullType) {
323
+ expression.value = buildComparisonExpressionValue(periodData.date1, periodData.date2, operatorLabel);
324
+ }
325
+ return expression;
326
+ };
327
+ return {
328
+ comparison: buildExpression(compareTo),
329
+ period: buildExpression(referencePeriod),
330
+ };
331
+ }
332
+ export function resolveDeltaDiffInfo(dataField, comparativeVirtualColumns, getChartColumns) {
333
+ for (const vc of comparativeVirtualColumns) {
334
+ if (vc.deltaDataField === dataField) {
335
+ const chartCols = getChartColumns();
336
+ const refCol = chartCols.find((c) => c.dataField === vc.originalDataField);
337
+ return {
338
+ origUniqueCode: refCol?.data?.uniqueCode ?? "",
339
+ diffIndex: 0,
340
+ };
341
+ }
342
+ const extraIdx = (vc.extraDeltaDataFields ?? []).indexOf(dataField);
343
+ if (extraIdx !== -1) {
344
+ const chartCols = getChartColumns();
345
+ const refCol = chartCols.find((c) => c.dataField === vc.originalDataField);
346
+ return {
347
+ origUniqueCode: refCol?.data?.uniqueCode ?? "",
348
+ diffIndex: extraIdx + 1,
349
+ };
350
+ }
351
+ }
352
+ return { origUniqueCode: "", diffIndex: -1 };
353
+ }
package/dist/index.d.ts CHANGED
@@ -17,3 +17,4 @@ export * from "./tokens/index";
17
17
  export * from "./column_format/index";
18
18
  export * from "./themes/index";
19
19
  export * from "./elements/index";
20
+ export * from "./comparativeAnalysis/index";
package/dist/index.js CHANGED
@@ -17,3 +17,4 @@ export * from "./tokens/index";
17
17
  export * from "./column_format/index";
18
18
  export * from "./themes/index";
19
19
  export * from "./elements/index";
20
+ export * from "./comparativeAnalysis/index";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qrvey/utils",
3
- "version": "1.17.4",
3
+ "version": "1.17.5",
4
4
  "description": "Helper, Utils for all Qrvey Projects",
5
5
  "homepage": "https://bitbucket.org/qrvey/qrvey_utils/wiki/Home",
6
6
  "main": "dist/cjs/index.js",