Skip to content

Commit 38c2d4a

Browse files
authored
Merge branch 'master' into dependabot/npm_and_yarn/mongodb-6.15.0
2 parents 86a0c23 + 74622e8 commit 38c2d4a

File tree

24 files changed

+612
-170
lines changed

24 files changed

+612
-170
lines changed

.github/workflows/main.yml

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,20 +21,29 @@ jobs:
2121
# This workflow contains a single job called "build"
2222
install:
2323
# The type of runner that the job will run on
24-
runs-on: ubuntu-20.04
24+
runs-on: ubuntu-22.04
2525

2626
# Steps represent a sequence of tasks that will be executed as part of the job
2727
steps:
2828
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
2929
- uses: actions/checkout@v3
3030

31+
- name: Copy code
32+
shell: bash
33+
run: |
34+
sudo mkdir -p /opt/countly
35+
touch log/countly-dashboard.log
36+
touch log/countly-api.log
37+
cp -rf ./* /opt/countly
38+
3139
- name: Github Actions Azure connection fix
3240
run: |
3341
# Workaround for https://github.com/actions/runner-images/issues/675#issuecomment-1381389712
3442
sudo sed -i 's/azure/us/g' /etc/apt/sources.list
35-
43+
3644
- name: Installing Countly
3745
shell: bash
46+
working-directory: /opt/countly
3847
run: sudo bash ./bin/countly.install.sh
3948

4049
- name: NodeJS version
@@ -50,10 +59,12 @@ jobs:
5059
run: mongosh --version
5160

5261
- name: Output API Logs
62+
working-directory: /opt/countly
5363
if: ${{ always() }}
5464
run: cat log/countly-api.log
5565

5666
- name: Output Dashboard Logs
67+
working-directory: /opt/countly
5768
if: ${{ always() }}
5869
run: cat log/countly-dashboard.log
5970

CHANGELOG.md

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,27 @@
1-
## Version 25.03.x
2-
1+
## Version 25.03.4
32
Features:
43
- Add ability to allow multiple CORS per app for web apps
54
- Add app id and name as view segment for self-tracking
5+
- [dashboards] Added the option to set a refresh rate for dashboards, allowing data to update more frequently for selected dashboards
66

77
Enterprise Features:
88
- [license] Update locking conditions for expired license and over limit usage
99
- [license] Enable force locking with remote config
1010
- [license] Update dashboard lock with redirection to home page for non admin user
1111

12+
Fixes:
13+
- [core] Allow downloading data also from other databases in dbviewer
14+
- [crashes] Fix unescaped SDK logs
15+
- [crash_symbolication] Symbolication server api end point test fix
16+
- [star-rating] Added missing columns to Rating Widgets table edit
17+
- [ui] Fix alignment of drawers title and close icon
18+
- [push] Fixed push notifications title and content text and variables combination
19+
- [reports] Correctly match event for email report if event key contains '.'
20+
21+
Enterprise Fixes:
22+
- [cohorts] Fixed issue with combining multiple cohorts
23+
- [drill] Do not recheck old collections on app_user data deletion if querying from old collections is disabled
24+
1225
Dependencies:
1326
- Bump body-parser from 1.20.3 to 2.2.0
1427
- Bump moment-timezone from 0.5.47 to 0.5.48

Gruntfile.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -483,7 +483,7 @@ module.exports = function(grunt) {
483483
name = name.replace('.properties', '');
484484
if (name.indexOf('_') !== -1) {
485485
lang = name.split('_').pop();
486-
if (lang.length > 3 || lang === "en") {
486+
if (lang.length > 2 || lang === "en") {
487487
lang = '';
488488
}
489489
}

api/jobs/topEvents.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,14 +138,19 @@ class TopEventsJob extends job.Job {
138138
* The errors of all functions will be caught here.
139139
*/
140140
async getAllApps() {
141+
log.d("Fetching all apps");
141142
try {
142143
const getAllApps = await new Promise((res, rej) => common.db.collection("apps").find({}, { _id: 1, timezone: 1 }).toArray((err, apps) => err ? rej(err) : res(apps)));
143-
await Promise.all(getAllApps.map((app) => this.getAppEvents(app)));
144+
for (var z = 0; z < getAllApps.length; z++) {
145+
//Calculating for each app serially.
146+
await this.getAppEvents(getAllApps[z]);
147+
}
144148
}
145149
catch (error) {
146150
log.e("TopEvents Job has a error: ", error);
147151
throw error;
148152
}
153+
log.d("Finished processing");
149154
}
150155

151156
/**
@@ -178,6 +183,7 @@ class TopEventsJob extends job.Job {
178183
* @param {Object} app - saveAppEvents object
179184
*/
180185
async getAppEvents(app) {
186+
log.d(app._id + ": Fetching app events");
181187
const getEvents = await new Promise((res, rej) => common.db.collection("events").findOne({ _id: app._id }, (errorEvents, result) => errorEvents ? rej(errorEvents) : res(result)));
182188
if (getEvents && 'list' in getEvents) {
183189
const eventMap = this.eventsFilter(getEvents.list);
@@ -199,6 +205,7 @@ class TopEventsJob extends job.Job {
199205
let totalDuration = 0;
200206
let prevTotalDuration = 0;
201207
for (const event of eventMap) {
208+
log.d(" getting event data for event: " + event + " (" + period + ")");
202209
const collectionNameEvents = this.eventsCollentions({ event, id: app._id });
203210
await this.getEventsCount({ collectionNameEvents, ob, data, event });
204211
totalCount += data[event].data.count.total;
@@ -208,11 +215,16 @@ class TopEventsJob extends job.Job {
208215
totalDuration += data[event].data.duration.total;
209216
prevTotalDuration += data[event].data.duration["prev-total"];
210217
}
218+
log.d(" getting session count (" + period + ")");
211219
await this.getSessionCount({ ob, sessionData, usersData, usersCollectionName });
220+
log.d(" saving data (" + period + ")");
212221
await this.saveAppEvents({ app, data, sessionData, usersData, period, totalCount, prevTotalCount, totalSum, prevTotalSum, totalDuration, prevTotalDuration });
213222
}
214223
}
215224
}
225+
else {
226+
log.d(" No events found for app");
227+
}
216228

217229
}
218230

api/utils/taskmanager.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -984,7 +984,13 @@ taskmanager.rerunTask = function(options, callback) {
984984
});
985985
}
986986

987-
options.db.collection("long_tasks").findOne({_id: options.id}, function(err, res) {
987+
var qq = {_id: options.id};
988+
if (options.additionalQuery) {
989+
qq = options.additionalQuery;
990+
qq._id = options.id;
991+
}
992+
log.d("Fetching from long_tasks to rerun: " + JSON.stringify(qq));
993+
options.db.collection("long_tasks").findOne(qq, function(err, res) {
988994
if (!err && res && res.request) {
989995
var reqData = {};
990996
try {

bin/countly.install_ubuntu.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
66

77
UBUNTU_YEAR="$(lsb_release -sr | cut -d '.' -f 1)";
88

9-
if [[ "$UBUNTU_YEAR" != "20" && "$UBUNTU_YEAR" != "22" ]]; then
9+
if [[ "$UBUNTU_YEAR" != "20" && "$UBUNTU_YEAR" != "22" && "$UBUNTU_YEAR" != "24" ]]; then
1010
echo "Unsupported OS version, only support Ubuntu 20 and 22."
1111
exit 1
1212
fi
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* Description: Deletes empty collections from database.By default it checks to delete from drill database. You can further tweak it to delete from countly database by changing drill to db in parameters passed
3+
* Server: countly
4+
* Path: $(countly dir)/bin/scripts/expire-data
5+
* Command: node delete_empty_collections.js
6+
*/
7+
var plugins = require("../../../plugins/pluginManager");
8+
var Promise = require("bluebird");
9+
var DRY_RUN = true; // Set this to false to perform actual drop
10+
Promise.all([plugins.dbConnection("countly"), plugins.dbConnection("countly_drill")]).spread(function(db, drill) {
11+
function dropCollections(database, collections, dryRun) {
12+
collections.forEach(function(collection) {
13+
if (database.collection(collection)) {
14+
console.log((dryRun ? "[DRY RUN] " : "") + "Dropping collection: " + collection);
15+
if (!dryRun) {
16+
database.collection(collection).drop(function(err, delOK) {
17+
if (err) {
18+
console.log("Error dropping collection: " + collection, err);
19+
}
20+
else if (delOK) {
21+
console.log("Collection dropped: " + collection);
22+
}
23+
else {
24+
console.log("Failed to drop collection: " + collection);
25+
}
26+
});
27+
}
28+
}
29+
else {
30+
console.log("Collection not found: " + collection);
31+
}
32+
});
33+
console.log("Collection drop process completed.");
34+
}
35+
// Fetch empty collections from countly_drill
36+
let emptyCollections = [];
37+
drill.listCollections().toArray(function(err, collections) {
38+
if (err) {
39+
console.log("Error fetching collections:", err);
40+
}
41+
else {
42+
collections.forEach(function(collection) {
43+
drill.collection(collection.name).countDocuments({}, function(err, count) {
44+
if (!err && count === 0) {
45+
console.log("Empty Collection: " + collection.name);
46+
emptyCollections.push(collection.name);
47+
}
48+
});
49+
});
50+
// Once empty collections are identified, proceed with dropping
51+
setTimeout(() => {
52+
console.log("\nDropping empty collections from countly_drill...");
53+
dropCollections(drill, emptyCollections, DRY_RUN);
54+
db.close();
55+
drill.close();
56+
}, 5000); // Delay to ensure collections are logged before drop
57+
}
58+
});
59+
});

frontend/express/public/javascripts/countly/vue/components/drawer.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
'is-open': this.isOpened,
6363
'has-sidecars': this.hasSidecars
6464
};
65+
// NOTE: currentScreenMode variable seems to be not defined it should be defined or removed
6566
classes["cly-vue-drawer--" + this.currentScreenMode + "-screen"] = true;
6667
if (this.currentScreenMode === 'half') {
6768
classes["cly-vue-drawer--half-screen-" + this.size] = true;

frontend/express/public/javascripts/countly/vue/templates/drawer.html

Lines changed: 29 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,35 @@
2020
</div>
2121
<div class="cly-vue-drawer__header" :class="{ 'is-full-screen': currentScreenMode === 'full'}">
2222
<div class="cly-vue-drawer__title">
23-
<div v-if="currentScreenMode !== 'full'">
24-
<div v-if="hasBackLink" class="cly-vue-drawer__title-container bu-is-flex bu-is-justify-content-space-between">
25-
<div class="bu-is-flex bu-is-flex-direction-column bu-is-justify-content-center bu-p-1 bu-ml-5 bu-mt-5">
26-
<a style="cursor: pointer;" @click="doClose" :data-test-id="testId + '-drawer-back-link'">
27-
<span class="text-medium bu-is-capitalized"><i class="fas fa-arrow-left bu-pr-3"></i>{{i18n('plugins.back')}}</span>
28-
</a>
29-
</div>
30-
<div class="bu-is-flex" :style="hasBackLink.style" :class="{ 'bu-is-justify-content-flex-start': hasBackLink, 'bu-is-justify-content-center': !hasBackLink }">
31-
<h3 :data-test-id="testId + '-header-title'" class="cly-vue-drawer__title-header">{{title}}</h3>
32-
</div>
33-
<span :data-test-id="testId + '-close-button'" class="cly-vue-drawer__close-button bu-p-1 bu-mr-5" v-on:click="doClose">
34-
<i class="ion-ios-close-empty"></i>
35-
</span>
36-
</div>
37-
<div v-else class="cly-vue-drawer__title-container bu-is-flex bu-is-justify-content-space-between">
38-
<h3 :data-test-id="testId + '-header-title'" class="cly-vue-drawer__title-header">{{title}}</h3>
39-
<span :data-test-id="testId + '-close-button'" class="cly-vue-drawer__close-button" v-on:click="doClose">
40-
<i class="ion-ios-close-empty"></i>
23+
<div
24+
v-if="currentScreenMode !== 'full'"
25+
class="cly-vue-drawer__title-container bu-is-flex bu-is-justify-content-space-between"
26+
:class="{ 'bu-is-align-items-center': !hasBackLink }"
27+
>
28+
<a
29+
v-if="hasBackLink"
30+
:data-test-id="testId + '-drawer-back-link'"
31+
style="cursor: pointer;"
32+
@click="doClose"
33+
>
34+
<span class="text-medium bu-is-capitalized">
35+
<i class="fas fa-arrow-left bu-pr-3" />
36+
{{ i18n('plugins.back') }}
4137
</span>
38+
</a>
39+
<h3
40+
class="cly-vue-drawer__title-header"
41+
:data-test-id="testId + '-header-title'"
42+
:style="hasBackLink.style"
43+
>
44+
{{ title }}
45+
</h3>
46+
<div
47+
class="cly-vue-drawer__close-button"
48+
:data-test-id="testId + '-close-button'"
49+
@click="doClose"
50+
>
51+
<i class="ion-ios-close-empty" />
4252
</div>
4353
</div>
4454
<div v-if="isMultiStep" class="bu-columns bu-is-gapless bu-is-mobile cly-vue-drawer__subtitle">
@@ -51,7 +61,7 @@ <h3 :data-test-id="testId + '-header-title'" class="cly-vue-drawer__title-header
5161
<span class="index text-small" :data-test-id="testId + '-current-step-index-' + (i + 1)" :class="{'color-white': i === currentStepIndex}">{{i + 1}}</span>
5262
<span class="done-icon text-small color-white bu-pt-0" :data-test-id="testId + '-current-step-index-img-container' + (i + 1)">
5363
<img :data-test-id="testId + '-step-' + (i + 1)" src="images/icons/check-icon.svg">
54-
</span>
64+
</span>
5565
</div>
5666
<div :data-test-id="testId + '-' + (currentContent && currentContent.name ? currentContent.name.toLowerCase().replaceAll(/[\s&]+/g, '-') + '-label' : 'content-label')" class="cly-vue-drawer__step-title text-small font-weight-bold color-cool-gray-40">{{currentContent.name}}</div>
5767
</div>

frontend/express/public/stylesheets/vue/clyvue.scss

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1899,31 +1899,29 @@
18991899
box-sizing: border-box;
19001900
}
19011901

1902+
// .cly-vue-drawer__title-container
19021903
&__title-container {
1903-
width: 100%;
1904-
margin-bottom: 24px;
1905-
}
1906-
1907-
&__title-header {
1908-
margin-top: 24px;
1909-
margin-left: 32px;
1904+
margin: 24px 32px;
19101905
}
19111906

19121907
&__subtitle {
19131908
margin-left: 32px !important;
19141909
margin-bottom: 24px !important;
19151910
}
19161911

1912+
// .cly-vue-drawer__close-button
19171913
&__close-button {
1914+
display: flex;
1915+
align-items: center;
1916+
justify-content: center;
1917+
19181918
font-size: 30px;
19191919
color: #81868D;
19201920
transition: color 1s;
19211921
cursor: pointer;
1922-
//width: 30px;
1923-
height: 15px;
1924-
//margin-block: auto;
1925-
margin-right: 32px;
1926-
margin-top: 24px;
1922+
height: 20px;
1923+
1924+
// .cly-vue-drawer__close-button:hover
19271925
&:hover {
19281926
color: #333;
19291927
transition: color 1s;

0 commit comments

Comments
 (0)