Merge branch 'dev' of github.com:openreplay/openreplay into funnels

This commit is contained in:
Shekar Siri 2022-04-22 16:10:44 +02:00
commit eeebe11915
8 changed files with 58 additions and 22 deletions

View file

@ -25,12 +25,15 @@ def get_live_sessions_ws(project_id, user_id=None):
if user_id and len(user_id) > 0:
params["userId"] = user_id
try:
connected_peers = requests.get(config("assist") % config("S3_KEY") + f"/{project_key}", params)
connected_peers = requests.get(config("assist") % config("S3_KEY") + f"/{project_key}", params, timeout=6)
if connected_peers.status_code != 200:
print("!! issue with the peer-server")
print(connected_peers.text)
return []
live_peers = connected_peers.json().get("data", [])
except requests.exceptions.Timeout:
print("Timeout getting Assist response")
live_peers = []
except Exception as e:
print("issue getting Live-Assist response")
print(str(e))
@ -60,12 +63,15 @@ def is_live(project_id, session_id, project_key=None):
if project_key is None:
project_key = projects.get_project_key(project_id)
try:
connected_peers = requests.get(config("assistList") % config("S3_KEY") + f"/{project_key}")
connected_peers = requests.get(config("assistList") % config("S3_KEY") + f"/{project_key}", timeout=6)
if connected_peers.status_code != 200:
print("!! issue with the peer-server")
print(connected_peers.text)
return False
connected_peers = connected_peers.json().get("data", [])
except requests.exceptions.Timeout:
print("Timeout getting Assist response")
return False
except Exception as e:
print("issue getting Assist response")
print(str(e))

View file

@ -1,9 +1,9 @@
require('dotenv').config()
const dumps = require('./utils/HeapSnapshot');
const {request_logger} = require('./utils/helper');
const express = require('express');
let socket;
if (process.env.redis === "true") {
console.log("Using Redis");
socket = require("./servers/websocket-cluster");
} else {
socket = require("./servers/websocket");

View file

@ -18,7 +18,7 @@ const SESSION_RECONNECTED = "SESSION_RECONNECTED";
const REDIS_URL = process.env.REDIS_URL || "redis://localhost:6379";
const pubClient = createClient({url: REDIS_URL});
const subClient = pubClient.duplicate();
console.log(`Using Redis: ${REDIS_URL}`);
let io;
const debug = process.env.debug === "1" || false;
@ -389,11 +389,16 @@ module.exports = {
console.error(e);
}
}, 20000, io);
Promise.all([pubClient.connect(), subClient.connect()]).then(() => {
io.adapter(createAdapter(pubClient, subClient));
console.log("> redis connected.");
// io.listen(3000);
});
Promise.all([pubClient.connect(), subClient.connect()])
.then(() => {
io.adapter(createAdapter(pubClient, subClient));
console.log("> redis connected.");
})
.catch((err) => {
console.log("> redis connection error");
console.error(err);
process.exit(2);
});
},
handlers: {
socketsList,

View file

@ -1,5 +1,5 @@
import { useObserver } from 'mobx-react-lite';
import React from 'react';
import React, { useEffect } from 'react';
import { NoContent, Pagination } from 'UI';
import { useStore } from 'App/mstore';
import { getRE } from 'App/utils';
@ -22,6 +22,10 @@ function MetricsList(props: Props) {
const list: any = metricsSearch !== '' ? filterList(metrics) : metrics;
const lenth = list.length;
useEffect(() => {
metricStore.updateKey('sessionsPage', 1);
}, [])
return useObserver(() => (
<NoContent show={lenth === 0} animatedIcon="no-results">
<div className="mt-3 border rounded bg-white">

View file

@ -29,6 +29,7 @@ function WidgetForm(props: Props) {
const isTable = metric.metricType === 'table';
const _issueOptions = [{ text: 'All', value: 'all' }].concat(issueOptions);
const canAddToDashboard = metric.exists() && dashboards.length > 0;
const canAddSeries = metric.series.length < 3;
const write = ({ target: { value, name } }) => metricStore.merge({ [ name ]: value });
const writeOption = (e, { value, name }) => {
@ -150,16 +151,17 @@ function WidgetForm(props: Props) {
</div>
<div className="form-group">
<label className="font-medium items-center">
<div className="font-medium items-center py-2">
{`${isTable ? 'Filter by' : 'Chart Series'}`}
{!isTable && (
<Button
className="ml-2"
primary plain size="small"
onClick={() => metric.addSeries()}
disabled={!canAddSeries}
>Add Series</Button>
)}
</label>
</div>
{metric.series.length > 0 && metric.series.slice(0, isTable ? 1 : metric.series.length).map((series: any, index: number) => (
<div className="mb-2">

View file

@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { NoContent, Dropdown, Icon, Loader } from 'UI';
import { NoContent, Dropdown, Icon, Loader, Pagination } from 'UI';
import cn from 'classnames';
import { useStore } from 'App/mstore';
import SessionItem from 'Shared/SessionItem';
@ -12,6 +12,7 @@ interface Props {
function WidgetSessions(props: Props) {
const { className = '' } = props;
const [data, setData] = useState<any>([]);
const [loading, setLoading] = useState(false);
const [seriesOptions, setSeriesOptions] = useState([
{ text: 'All', value: 'all' },
@ -51,8 +52,8 @@ function WidgetSessions(props: Props) {
const depsString = JSON.stringify(widget.series);
useEffect(() => {
debounceRequest(widget.metricId, { ...filter, series: widget.toJsonDrilldown() });
}, [filter.startTimestamp, filter.endTimestamp, filter.filters, depsString]);
debounceRequest(widget.metricId, { ...filter, series: widget.toJsonDrilldown(), page: metricStore.sessionsPage, limit: metricStore.sessionsPageSize });
}, [filter.startTimestamp, filter.endTimestamp, filter.filters, depsString, metricStore.sessionsPage]);
return useObserver(() => (
<div className={cn(className)}>
@ -85,12 +86,22 @@ function WidgetSessions(props: Props) {
<Loader loading={loading}>
<NoContent
title="No recordings found"
show={filteredSessions.length === 0}
show={filteredSessions.sessions.length === 0}
animatedIcon="no-results"
>
{filteredSessions.map((session: any) => (
{filteredSessions.sessions.map((session: any) => (
<SessionItem key={ session.sessionId } session={ session } />
))}
<div className="w-full flex items-center justify-center py-6">
<Pagination
page={metricStore.sessionsPage}
totalPages={Math.ceil(filteredSessions.total / metricStore.sessionsPageSize)}
onPageChange={(page) => metricStore.updateKey('sessionsPage', page)}
limit={metricStore.sessionsPageSize}
debounceRequest={500}
/>
</div>
</NoContent>
</Loader>
</div>
@ -99,14 +110,16 @@ function WidgetSessions(props: Props) {
}
const getListSessionsBySeries = (data, seriesId) => {
const arr: any = []
const arr: any = { sessions: [], total: 0 };
data.forEach(element => {
if (seriesId === 'all') {
const sessionIds = arr.map(i => i.sessionId);
arr.push(...element.sessions.filter(i => !sessionIds.includes(i.sessionId)));
const sessionIds = arr.sessions.map(i => i.sessionId);
arr.sessions.push(...element.sessions.filter(i => !sessionIds.includes(i.sessionId)));
arr.total = element.total
} else {
if (element.seriesId === seriesId) {
arr.push(...element.sessions)
arr.sessions.push(...element.sessions)
arr.total = element.total
}
}
});

View file

@ -23,7 +23,7 @@ export default ({
className={ classnames(
className,
size,
{ 'disabled' : disabled },
{ 'btn-disabled' : disabled },
styles[ plain ? 'plain' : '' ],
styles[ hover ? 'hover' : '' ],
styles.button,

View file

@ -16,6 +16,9 @@ export interface IMetricStore {
pageSize: number
metricsSearch: string
sort: any
sessionsPage: number
sessionsPageSize: number
// State Actions
init(metric?: IWidget|null): void
@ -46,6 +49,9 @@ export default class MetricStore implements IMetricStore {
metricsSearch: string = ""
sort: any = {}
sessionsPage: number = 1
sessionsPageSize: number = 10
constructor() {
makeAutoObservable(this, {
isLoading: observable,