PromucFlow_constructor/app/client/src/usagePulse/index.ts
balajisoundar b40ce96de9
chore: decrease usage pulse trigger interval to 5 minutes (#20394)
## Description
- Decrease the usage pulse trigger interval to 5 minutes.
- In another PR we will add changes to make this value driven by backend

Media
> A video or a GIF is preferred. when using Loom, don’t embed because it
looks like it’s a GIF. instead, just link to the video


## Type of change

> Please delete options that are not relevant.

- Bug fix (non-breaking change which fixes an issue)
- New feature (non-breaking change which adds functionality)
- Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- Chore (housekeeping or task changes that don't impact user perception)
- This change requires a documentation update


## How Has This Been Tested?
> Please describe the tests that you ran to verify your changes. Provide
instructions, so we can reproduce.
> Please also list any relevant details for your test configuration.
> Delete anything that is not important

- Manual
- Jest
- Cypress

### Test Plan
> Add Testsmith test cases links that relate to this PR

### Issues raised during DP testing
> Link issues raised during DP testing for better visiblity and tracking
(copy link from comments dropped on this PR)


## Checklist:
### Dev activity
- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [ ] New and existing unit tests pass locally with my changes
- [ ] PR is being merged under a feature flag


### QA activity:
- [ ] Test plan has been approved by relevant developers
- [ ] Test plan has been peer reviewed by QA
- [ ] Cypress test cases have been added and approved by either SDET or
manual QA
- [ ] Organized project review call with relevant stakeholders after
Round 1/2 of QA
- [ ] Added Test Plan Approved label after reveiwing all Cypress test
2023-02-06 14:37:50 +05:30

119 lines
3.2 KiB
TypeScript

import {
BUILDER_VIEWER_PATH_PREFIX,
VIEWER_PATH_DEPRECATED_REGEX,
} from "constants/routes";
import { noop } from "lodash";
import history from "utils/history";
const PULSE_API_ENDPOINT = "/api/v1/usage-pulse";
const PULSE_INTERVAL = 300; /* 5 minutes in seconds */
const USER_ACTIVITY_LISTENER_EVENTS = ["pointerdown", "keydown"];
class UsagePulse {
static userAnonymousId: string | undefined;
static Timer: ReturnType<typeof setTimeout>;
static unlistenRouteChange: () => void;
/*
* Function to check if the given URL is trakable or not.
* app builder and viewer urls are trackable
*/
static isTrackableUrl(url: string) {
return (
url.includes(BUILDER_VIEWER_PATH_PREFIX) ||
VIEWER_PATH_DEPRECATED_REGEX.test(url)
);
}
static sendPulse() {
const data: Record<string, unknown> = {
viewMode: !window.location.href.endsWith("/edit"),
};
if (UsagePulse.userAnonymousId) {
data["anonymousUserId"] = UsagePulse.userAnonymousId;
}
fetch(PULSE_API_ENDPOINT, {
method: "POST",
credentials: "same-origin",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(data),
keepalive: true,
}).catch(noop);
}
static registerActivityListener() {
USER_ACTIVITY_LISTENER_EVENTS.forEach((event) => {
window.document.body.addEventListener(
event,
UsagePulse.startTrackingActivity,
);
});
}
static deregisterActivityListener() {
USER_ACTIVITY_LISTENER_EVENTS.forEach((event) => {
window.document.body.removeEventListener(
event,
UsagePulse.startTrackingActivity,
);
});
}
/*
* Function to register a history change event and trigger
* a callback and unlisten when the user goes to a trackable URL
*/
static watchForTrackableUrl(callback: () => void) {
UsagePulse.unlistenRouteChange = history.listen(() => {
if (UsagePulse.isTrackableUrl(window.location.href)) {
UsagePulse.unlistenRouteChange();
setTimeout(callback, 0);
}
});
UsagePulse.deregisterActivityListener();
}
/*
* Function that suspends active tracking listeners
* and schedules when next listeners should be registered.
*/
static scheduleNextActivityListeners() {
UsagePulse.deregisterActivityListener();
UsagePulse.Timer = setTimeout(
UsagePulse.registerActivityListener,
PULSE_INTERVAL * 1000,
);
}
/*
* Point of entry for the user tracking
* triggers a pulse and schedules the pulse , if user is on a trackable url, otherwise
* registers listeners to wait for the user to go to a trackable url
*/
static startTrackingActivity() {
if (UsagePulse.isTrackableUrl(window.location.href)) {
UsagePulse.sendPulse();
UsagePulse.scheduleNextActivityListeners();
} else {
UsagePulse.watchForTrackableUrl(UsagePulse.startTrackingActivity);
}
}
/*
* Function to cleanup states and listeners
*/
static stopTrackingActivity() {
UsagePulse.userAnonymousId = undefined;
clearTimeout(UsagePulse.Timer);
UsagePulse.unlistenRouteChange && UsagePulse.unlistenRouteChange();
UsagePulse.deregisterActivityListener();
}
}
export default UsagePulse;