Skip to content

Commit 00eca8a

Browse files
authored
Merge branch 'master' into av-rc
2 parents f265cd7 + 8f91312 commit 00eca8a

File tree

9 files changed

+312
-22
lines changed

9 files changed

+312
-22
lines changed

CHANGELOG.md

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
1-
## Version 25.03.XX
1+
## Version 25.03.XX
2+
3+
Features:
4+
- [plugins] Add configuration warning tags to settings UI
5+
26
Fixes:
37
- [remote-config] Fix condition matching with complex conditions
48
- [core] Use correct rights validation for loyality
9+
- [crashes] Fix free session for home widget
10+
- [crashes] Use na for free session and free user when there's no data
11+
12+
Enterprise Fixes:
13+
- [ldap] Error handling in ldap plugin on search error
514

615
Features:
716
- [remote-config] Add support for comparing newer/older app version in conditions

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
"method-override": "3.0.0",
8686
"moment": "2.30.1",
8787
"moment-timezone": "0.6.0",
88-
"mongodb": "6.17.0",
88+
"mongodb": "6.18.0",
8989
"nginx-conf": "2.1.0",
9090
"nodemailer": "7.0.5",
9191
"object-hash": "3.0.0",

plugins/crashes/frontend/public/javascripts/countly.models.js

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -152,7 +152,10 @@ function transformAppVersion(inpVersion) {
152152
* @param {bool} isPercent - Flag to just format the metric's total values as percentages.
153153
*/
154154
function populateMetric(metric, isPercent) {
155-
if (dashboard[metric].total !== 0 && dashboard[metric]["prev-total"] !== 0) {
155+
if (dashboard[metric].total === 'NA' || dashboard[metric]['prev-total'] === 'NA') {
156+
dashboard[metric].change = 'NA';
157+
}
158+
else if (dashboard[metric].total !== 0 && dashboard[metric]["prev-total"] !== 0) {
156159
if (isPercent) {
157160
dashboard[metric].change = (dashboard[metric].total - dashboard[metric]["prev-total"]).toFixed(1) + "%";
158161
}
@@ -182,7 +185,9 @@ function transformAppVersion(inpVersion) {
182185

183186
if (isPercent && ["crses", "crnfses", "crfses", "crau", "craunf", "crauf", 'crinv', 'crfinv', 'crnfinv', 'crauinv', 'craufinv', 'craunfinv'].includes(metric)) {
184187
["total", "prev-total"].forEach(function(prop) {
185-
dashboard[metric][prop] = dashboard[metric][prop].toFixed(2) + '%';
188+
if (dashboard[metric][prop] !== 'NA') {
189+
dashboard[metric][prop] = dashboard[metric][prop].toFixed(2) + '%';
190+
}
186191
});
187192
}
188193
}
@@ -219,10 +224,13 @@ function transformAppVersion(inpVersion) {
219224
}
220225

221226
// derive user count from whole users
222-
if (dashboard.crau[prop] > dashboard.cr_u[prop] && 'users' in state.rawData) {
227+
if (dashboard.crau[prop] > dashboard.cr_u[prop] && 'users' in state.rawData && wholeUsers.total > 0) {
223228
dashboard.crauf[prop] = dashboard.cr_u[prop] * ((wholeUsers.fatal / wholeUsers.total) - (dashboard.crf[prop] / dashboard.cr_s[prop]));
229+
dashboard.crauf.isEstimate = true;
224230
dashboard.craunf[prop] = dashboard.cr_u[prop] * ((wholeUsers.nonfatal / wholeUsers.total) - (dashboard.crnf[prop] / dashboard.cr_s[prop]));
231+
dashboard.craunf.isEstimate = true;
225232
dashboard.crau[prop] = dashboard.crauf[prop] + dashboard.craunf[prop];
233+
dashboard.crau.isEstimate = true;
226234
}
227235

228236
dashboard.crinv[prop] = Math.max(0, dashboard.cr_s[prop] - dashboard.cr[prop]);
@@ -234,9 +242,14 @@ function transformAppVersion(inpVersion) {
234242
populateMetric(metric);
235243
});
236244

237-
["crau", "craunf", "crauf"].forEach(function(name) {
238-
["total", "prev-total"].forEach(function(prop) {
239-
dashboard[name][prop] = Math.min(100, (dashboard.cr_u[prop] === 0 || dashboard[name][prop] === 0) ? 100 : (Math.abs(dashboard.cr_u[prop] - dashboard[name][prop]) / dashboard.cr_u[prop] * 100));
245+
['crau', 'craunf', 'crauf'].forEach(function(name) {
246+
['total', 'prev-total'].forEach(function(prop) {
247+
if (dashboard.cr_u[prop] === 0 || !Number.isFinite(dashboard[name][prop])) {
248+
dashboard[name][prop] = 'NA';
249+
}
250+
else {
251+
dashboard[name][prop] = Math.abs(dashboard.cr_u[prop] - dashboard[name][prop]) / dashboard.cr_u[prop] * 100;
252+
}
240253
});
241254
populateMetric(name, true);
242255
});
@@ -264,17 +277,13 @@ function transformAppVersion(inpVersion) {
264277
});
265278

266279
['crinv', 'crfinv', 'crnfinv'].forEach(function(name) {
267-
["total", "prev-total"].forEach(function(prop) {
268-
var propValue = 0;
269-
280+
['total', 'prev-total'].forEach(function(prop) {
270281
if (dashboard.cr_s[prop] === 0) {
271-
propValue = 100;
282+
dashboard[name][prop] = 'NA';
272283
}
273284
else {
274-
propValue = dashboard[name][prop] / dashboard.cr_s[prop] * 100;
285+
dashboard[name][prop] = dashboard[name][prop] / dashboard.cr_s[prop] * 100;
275286
}
276-
277-
dashboard[name][prop] = Math.min(100, propValue);
278287
});
279288
populateMetric(name, true);
280289
});

plugins/crashes/frontend/public/javascripts/countly.views.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1338,7 +1338,7 @@
13381338
{"name": CV.i18n('crashes.unique'), "info": CV.i18n('crashes.home.unique'), "prop": "cru", "r": true},
13391339
{"name": CV.i18n('crashes.total-per-session'), "info": CV.i18n('crashes.home.per-session'), "prop": "cr-session", "r": true},
13401340
{"name": CV.i18n('crashes.free-users'), "info": CV.i18n('crashes.help-free-users'), "prop": "crau", "p": true},
1341-
{"name": CV.i18n('crashes.free-sessions'), "info": CV.i18n('crashes.help-free-sessions'), "prop": "crses", "p": true}
1341+
{"name": CV.i18n('crashes.free-sessions'), "info": CV.i18n('crashes.help-free-sessions'), "prop": "crinv", "p": true}
13421342
];
13431343

13441344
for (var k = 0; k < getUs.length; k++) {

plugins/plugins/frontend/public/javascripts/countly.models.js

Lines changed: 234 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
var _userConfigsData = {};
88
var _themeList = [];
99
var _graph = {};
10+
var _configWarnings = null;
1011

1112
//Public Methods
1213
countlyPlugins.initialize = function() {
@@ -307,4 +308,237 @@
307308
});
308309
};
309310

311+
// Warning types and their associated colors
312+
var WARNING_TYPES = {
313+
DATA_INGESTION: 'dataIngestion',
314+
UI_FILTERING: 'uiFiltering',
315+
SERVER_PERFORMANCE: 'serverPerformance'
316+
// SECURITY_IMPACT: 'securityImpact' // for the 2nd phase
317+
};
318+
319+
// Tooltip color mappings
320+
var TOOLTIP_COLORS = {
321+
dataIngestion: "color-yellow-100",
322+
uiFiltering: "color-blue-100",
323+
serverPerformance: "color-red-100"
324+
};
325+
326+
/**
327+
* Helper function to create warning objects
328+
* @param {string} type - Warning type
329+
* @param {string} textKey - Warning text key
330+
* @returns {Object} Warning object with type and text
331+
*/
332+
function createWarning(type, textKey) {
333+
return {
334+
type: type,
335+
text: textKey
336+
};
337+
}
338+
339+
// Predefined warning combinations
340+
var WARNING_COMBINATIONS = {
341+
DATA_INGESTION: [
342+
createWarning(WARNING_TYPES.DATA_INGESTION, "configs.tooltip.data-ingestion-warning")
343+
],
344+
UI_FILTERING: [
345+
createWarning(WARNING_TYPES.UI_FILTERING, "configs.tooltip.ui-filtering-warning")
346+
],
347+
SERVER_PERFORMANCE: [
348+
createWarning(WARNING_TYPES.SERVER_PERFORMANCE, "configs.tooltip.server-performance-warning")
349+
]
350+
};
351+
352+
/**
353+
* Initialize configuration warnings
354+
* @returns {Object} Configuration warnings map
355+
*/
356+
function initializeConfigWarnings() {
357+
if (_configWarnings !== null) {
358+
return _configWarnings;
359+
}
360+
361+
var configWarnings = {
362+
// API Core Configurations
363+
"api.trim_trailing_ending_spaces": [
364+
...WARNING_COMBINATIONS.DATA_INGESTION,
365+
...WARNING_COMBINATIONS.UI_FILTERING
366+
],
367+
"api.event_limit": [
368+
...WARNING_COMBINATIONS.SERVER_PERFORMANCE,
369+
...WARNING_COMBINATIONS.DATA_INGESTION,
370+
...WARNING_COMBINATIONS.UI_FILTERING
371+
],
372+
"api.event_segmentation_limit": [
373+
...WARNING_COMBINATIONS.SERVER_PERFORMANCE,
374+
...WARNING_COMBINATIONS.DATA_INGESTION,
375+
...WARNING_COMBINATIONS.UI_FILTERING
376+
],
377+
"api.event_segmentation_value_limit": [
378+
...WARNING_COMBINATIONS.SERVER_PERFORMANCE,
379+
...WARNING_COMBINATIONS.DATA_INGESTION,
380+
...WARNING_COMBINATIONS.UI_FILTERING
381+
],
382+
"api.metric_limit": [
383+
...WARNING_COMBINATIONS.SERVER_PERFORMANCE,
384+
...WARNING_COMBINATIONS.DATA_INGESTION,
385+
...WARNING_COMBINATIONS.UI_FILTERING
386+
],
387+
"api.session_duration_limit": [
388+
...WARNING_COMBINATIONS.DATA_INGESTION,
389+
...WARNING_COMBINATIONS.UI_FILTERING
390+
],
391+
"api.array_list_limit": [
392+
...WARNING_COMBINATIONS.SERVER_PERFORMANCE,
393+
...WARNING_COMBINATIONS.DATA_INGESTION,
394+
...WARNING_COMBINATIONS.UI_FILTERING
395+
],
396+
"api.city_data": [
397+
...WARNING_COMBINATIONS.DATA_INGESTION,
398+
...WARNING_COMBINATIONS.UI_FILTERING
399+
],
400+
"api.country_data": [
401+
...WARNING_COMBINATIONS.DATA_INGESTION,
402+
...WARNING_COMBINATIONS.UI_FILTERING
403+
],
404+
405+
// Logging Configurations
406+
"logs.default": WARNING_COMBINATIONS.UI_FILTERING,
407+
408+
// Plugin-specific Configurations
409+
"attribution.segment_value_limit": [
410+
...WARNING_COMBINATIONS.SERVER_PERFORMANCE,
411+
...WARNING_COMBINATIONS.DATA_INGESTION,
412+
...WARNING_COMBINATIONS.UI_FILTERING
413+
],
414+
415+
"crashes.report_limit": [
416+
...WARNING_COMBINATIONS.UI_FILTERING
417+
],
418+
"crashes.max_custom_field_keys": [
419+
...WARNING_COMBINATIONS.SERVER_PERFORMANCE,
420+
...WARNING_COMBINATIONS.DATA_INGESTION,
421+
...WARNING_COMBINATIONS.UI_FILTERING
422+
],
423+
"crashes.smart_regexes": WARNING_COMBINATIONS.UI_FILTERING,
424+
425+
"drill.list_limit": [
426+
...WARNING_COMBINATIONS.UI_FILTERING
427+
],
428+
"drill.custom_property_limit": [
429+
...WARNING_COMBINATIONS.UI_FILTERING
430+
],
431+
"drill.projection_limit": [
432+
...WARNING_COMBINATIONS.UI_FILTERING
433+
],
434+
"drill.big_list_limit": [
435+
...WARNING_COMBINATIONS.SERVER_PERFORMANCE,
436+
...WARNING_COMBINATIONS.DATA_INGESTION,
437+
...WARNING_COMBINATIONS.UI_FILTERING
438+
],
439+
440+
"flows.maxDepth": [
441+
...WARNING_COMBINATIONS.UI_FILTERING
442+
],
443+
"flows.nodesCn": [
444+
...WARNING_COMBINATIONS.UI_FILTERING
445+
],
446+
447+
"hooks.requestLimit": [
448+
...WARNING_COMBINATIONS.DATA_INGESTION
449+
],
450+
451+
"logger.limit": [
452+
...WARNING_COMBINATIONS.SERVER_PERFORMANCE,
453+
...WARNING_COMBINATIONS.DATA_INGESTION,
454+
...WARNING_COMBINATIONS.UI_FILTERING
455+
],
456+
"logger.state": [
457+
...WARNING_COMBINATIONS.SERVER_PERFORMANCE,
458+
...WARNING_COMBINATIONS.DATA_INGESTION,
459+
...WARNING_COMBINATIONS.UI_FILTERING
460+
],
461+
462+
"remote-config.conditions_per_paramaeters": [
463+
...WARNING_COMBINATIONS.DATA_INGESTION,
464+
...WARNING_COMBINATIONS.UI_FILTERING
465+
],
466+
"remote-config.maximum_allowed_parameters": [
467+
...WARNING_COMBINATIONS.DATA_INGESTION,
468+
...WARNING_COMBINATIONS.UI_FILTERING
469+
],
470+
471+
"sources.sources_length_limit": [
472+
...WARNING_COMBINATIONS.DATA_INGESTION,
473+
...WARNING_COMBINATIONS.UI_FILTERING
474+
],
475+
476+
"users.custom_prop_limit": [
477+
...WARNING_COMBINATIONS.SERVER_PERFORMANCE,
478+
...WARNING_COMBINATIONS.DATA_INGESTION,
479+
...WARNING_COMBINATIONS.UI_FILTERING
480+
],
481+
"users.custom_set_limit": [
482+
...WARNING_COMBINATIONS.SERVER_PERFORMANCE,
483+
...WARNING_COMBINATIONS.DATA_INGESTION,
484+
...WARNING_COMBINATIONS.UI_FILTERING
485+
],
486+
487+
"views.segment_limit": [
488+
...WARNING_COMBINATIONS.SERVER_PERFORMANCE,
489+
...WARNING_COMBINATIONS.DATA_INGESTION,
490+
...WARNING_COMBINATIONS.UI_FILTERING
491+
],
492+
"views.segment_value_limit": [
493+
...WARNING_COMBINATIONS.SERVER_PERFORMANCE,
494+
...WARNING_COMBINATIONS.DATA_INGESTION,
495+
...WARNING_COMBINATIONS.UI_FILTERING
496+
],
497+
"views.view_limit": [
498+
...WARNING_COMBINATIONS.SERVER_PERFORMANCE,
499+
...WARNING_COMBINATIONS.DATA_INGESTION,
500+
...WARNING_COMBINATIONS.UI_FILTERING
501+
],
502+
"views.view_name_limit": [
503+
...WARNING_COMBINATIONS.DATA_INGESTION,
504+
...WARNING_COMBINATIONS.UI_FILTERING
505+
],
506+
507+
"data-manager.globalValidationAction": [
508+
...WARNING_COMBINATIONS.DATA_INGESTION,
509+
...WARNING_COMBINATIONS.UI_FILTERING
510+
],
511+
"data-manager.segmentLevelValidationAction": [
512+
...WARNING_COMBINATIONS.DATA_INGESTION,
513+
...WARNING_COMBINATIONS.UI_FILTERING
514+
],
515+
"data-manager.enableDataMasking": [
516+
...WARNING_COMBINATIONS.DATA_INGESTION,
517+
...WARNING_COMBINATIONS.UI_FILTERING
518+
]
519+
};
520+
521+
_configWarnings = configWarnings;
522+
return _configWarnings;
523+
}
524+
525+
countlyPlugins.getConfigWarnings = function(configGroup, key) {
526+
var warnings = initializeConfigWarnings();
527+
var mapKey = configGroup + "." + key;
528+
return warnings[mapKey] || [];
529+
};
530+
531+
countlyPlugins.getTooltipColors = function() {
532+
return TOOLTIP_COLORS;
533+
};
534+
535+
countlyPlugins.getTooltipLabel = function(type) {
536+
var labels = {
537+
dataIngestion: CV.i18n('configs.tooltip.data-ingestion'),
538+
uiFiltering: CV.i18n('configs.tooltip.ui-filtering'),
539+
serverPerformance: CV.i18n('configs.tooltip.server-performance')
540+
};
541+
return labels[type] || 'Unknown Type';
542+
};
543+
310544
}(window.countlyPlugins = window.countlyPlugins || {}, jQuery));

plugins/plugins/frontend/public/javascripts/countly.views.js

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,17 @@
534534
getConfigType: function(id) {
535535
return this.coreDefaults.includes(id) ? "Core" : "Plugins";
536536
},
537+
getWarningTags(configGroup, key) {
538+
var warnings = countlyPlugins.getConfigWarnings(configGroup, key);
539+
var tooltipColors = countlyPlugins.getTooltipColors();
540+
return warnings.map(function(warning) {
541+
return {
542+
tooltipText: CV.i18n(warning.text),
543+
color: tooltipColors[warning.type],
544+
label: countlyPlugins.getTooltipLabel(warning.type)
545+
};
546+
});
547+
},
537548
checkIfOverwritten: function(id, ns) {
538549
ns = ns || this.selectedConfig;
539550
var configsData = countlyPlugins.getConfigsData();

0 commit comments

Comments
 (0)