Various UI improvements (#2337)

* Various UI improvements

* Title updates

* No results icon update

* UI Improvements in DevTools

---------

Co-authored-by: Sudheer Salavadi <connect.uxmaster@gmail.com>
This commit is contained in:
Shekar Siri 2024-07-03 10:19:13 +02:00 committed by GitHub
parent a21e123ea0
commit a35311f4dc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
55 changed files with 182 additions and 138 deletions

View file

@ -25,7 +25,7 @@ function RecordingsList() {
show={length === 0}
title={
<div className="flex flex-col items-center justify-center">
<AnimatedSVG name={ICONS.NO_RECORDINGS} size={180} />
<AnimatedSVG name={ICONS.NO_RECORDINGS} size={60} />
<div className="text-center mt-4">
{recordsSearch !== ''
? 'No matching results'

View file

@ -38,7 +38,7 @@ function SessionList(props: Props) {
show={!props.loading && props.list.length === 0}
title={
<div className="flex items-center justify-center flex-col">
<AnimatedSVG name={ICONS.NO_LIVE_SESSIONS} size={170} />
<AnimatedSVG name={ICONS.NO_LIVE_SESSIONS} size={60} />
<div className="mt-4" />
<div className="text-center">No live sessions found</div>
</div>

View file

@ -37,7 +37,7 @@ function AuditList(props: Props) {
<NoContent
title={
<div className="flex flex-col items-center justify-center">
<AnimatedSVG name={ICONS.NO_AUDIT_TRAIL} size={80} />
<AnimatedSVG name={ICONS.NO_AUDIT_TRAIL} size={60} />
<div className="text-center my-4">No data available</div>
</div>
}

View file

@ -90,7 +90,7 @@ function CustomFields(props) {
<NoContent
title={
<div className="flex flex-col items-center justify-center">
<AnimatedSVG name={ICONS.NO_METADATA} size={170} />
<AnimatedSVG name={ICONS.NO_METADATA} size={60} />
{/* <div className="mt-4" /> */}
<div className="text-center my-4">None added yet</div>
</div>

View file

@ -135,7 +135,7 @@ const Sites = ({ loading, sites, user, init }: PropsFromRedux) => {
<NoContent
title={
<div className="flex flex-col items-center justify-center">
<AnimatedSVG name={ICONS.NO_PROJECTS} size={170} />
<AnimatedSVG name={ICONS.NO_PROJECTS} size={60} />
<div className="text-center text-gray-600 my-4">No matching results</div>
</div>
}

View file

@ -45,7 +45,7 @@ function UserList(props: Props) {
<NoContent
title={
<div className="flex flex-col items-center justify-center">
<AnimatedSVG name={ICONS.NO_AUDIT_TRAIL} size={80} />
<AnimatedSVG name={ICONS.NO_AUDIT_TRAIL} size={60} />
<div className="text-center my-4">No matching results</div>
</div>
}

View file

@ -59,7 +59,7 @@ function Webhooks() {
<NoContent
title={
<div className="flex flex-col items-center justify-center">
<AnimatedSVG name={ICONS.NO_WEBHOOKS} size={170} />
<AnimatedSVG name={ICONS.NO_WEBHOOKS} size={60} />
<div className="text-center my-4">None added yet</div>
</div>
}

View file

@ -43,9 +43,9 @@ function ClickMapCard({
<NoContent
style={{ minHeight: 220 }}
title={
<div className="flex items-center relative">
<div className="flex items-center relative text-lg">
<Icon name="info-circle" className="mr-2" size="18" />
No data for selected period or URL
No data available for the selected period.
<div style={{ position: 'absolute', right: -240, top: -110 }}>
<Icon name="pointer-sessions-search" size={250} width={240} />
</div>

View file

@ -57,9 +57,9 @@ function CustomMetricTable(props: Props) {
show={data.values && data.values.length === 0}
size="small"
title={
<div className="flex items-center">
<div className="flex items-center text-lg">
<Icon name="info-circle" className="mr-2" size="18"/>
No data for the selected time period
No data available for the selected period.
</div>
}
>

View file

@ -45,7 +45,7 @@ function CustomMetricTableErrors(props: RouteComponentProps & Props) {
return (
<NoContent
title={<div className="flex items-center"><Icon name="info-circle" size={18} className="mr-2" />No data for the selected time period</div>}
title={<div className="flex items-center text-lg"><Icon name="info-circle" size={18} className="mr-2" />No data available for the selected period.</div>}
show={!data.errors || data.errors.length === 0}
size="small"
style={{ minHeight: 220 }}

View file

@ -59,9 +59,9 @@ function InsightsCard({ data }: any) {
<NoContent
style={{ minHeight: 220 }}
title={
<div className="flex items-center">
<div className="flex items-center text-lg">
<Icon name="info-circle" className="mr-2" size="18" />
No data for selected period
No data available for the selected period.
</div>
}
show={data.issues && data.issues.length === 0}

View file

@ -59,9 +59,9 @@ function SessionsBy(props: Props) {
className="flex flex-col items-center justify-center"
imageStyle={{ height: 60 }}
description={
<div className="flex items-center justify-center">
<div className="flex items-center justify-center text-lg">
<Icon name="info-circle" className="mr-2" size="18" />
No data for the selected time period
No data available for the selected period.
</div>
}
/>

View file

@ -1,5 +1,5 @@
import React from 'react';
import { NoContent } from 'UI';
import { NoContent, Icon } from 'UI';
import { Styles } from '../../common';
import {
BarChart, Bar, CartesianGrid, Tooltip,
@ -18,7 +18,12 @@ function BreakdownOfLoadedResources(props: Props) {
return (
<NoContent
size="small"
title="No data available"
title={
<div className="flex items-center text-lg">
<Icon name="info-circle" className="mr-2" size="18" />
No data available for the selected period.
</div>
}
show={ metric.data.chart && metric.data.chart.length === 0 }
>
<ResponsiveContainer height={ 240 } width="100%">

View file

@ -1,5 +1,5 @@
import React from 'react';
import { NoContent } from 'UI';
import { NoContent, Icon } from 'UI';
import { Styles } from '../../common';
import {
AreaChart, Area,
@ -19,7 +19,12 @@ function CPULoad(props: Props) {
return (
<NoContent
size="small"
title="No data available"
title={
<div className="flex items-center text-lg">
<Icon name="info-circle" className="mr-2" size="18" />
No data available for the selected period.
</div>
}
show={ metric.data.chart && metric.data.chart.length === 0 }
style={ { height: '240px' } }
>

View file

@ -1,5 +1,5 @@
import React from 'react';
import { NoContent } from 'UI';
import { NoContent, Icon } from 'UI';
import { Styles } from '../../common';
import {
CartesianGrid, Tooltip,
@ -16,7 +16,12 @@ function CallsErrors5xx(props: Props) {
return (
<NoContent
size="small"
title="No data available"
title={
<div className="flex items-center text-lg">
<Icon name="info-circle" className="mr-2" size="18" />
No data available for the selected period.
</div>
}
show={ metric.data.chart.length === 0 }
style={ { height: '240px' } }
>

View file

@ -36,7 +36,7 @@ function AlertsList({ siteId }: Props) {
show={list.length === 0}
title={
<div className='flex flex-col items-center justify-center'>
<AnimatedSVG name={ICONS.NO_ALERTS} size={180} />
<AnimatedSVG name={ICONS.NO_ALERTS} size={60} />
<div className='text-center mt-4'>
{alertsSearch !== '' ? 'No matching results' : 'You haven\'t created any alerts yet'}
</div>

View file

@ -61,7 +61,7 @@ function SessionsModal(props: Props) {
<NoContent show={data.sessions.length === 0} title={
<div>
<AnimatedSVG name={ICONS.NO_SESSIONS} size={170} />
<AnimatedSVG name={ICONS.NO_SESSIONS} size={60} />
<div className="mt-2" />
<div className="text-center text-gray-600">No recordings found.</div>
</div>

View file

@ -535,7 +535,7 @@ export const CARD_LIST: CardType[] = [
},
{
title: 'DOM Content Loaded Start',
title: 'Avg. DOM Content Loaded Start',
key: FilterKey.AVG_DOM_CONTENT_LOAD_START,
cardType: WEB_VITALS,
metricOf: FilterKey.AVG_DOM_CONTENT_LOAD_START,
@ -605,7 +605,7 @@ export const CARD_LIST: CardType[] = [
},
{
title: 'Page Response Time',
title: 'Avg. Page Response Time',
key: FilterKey.AVG_PAGES_RESPONSE_TIME,
cardType: WEB_VITALS,
metricOf: FilterKey.AVG_PAGES_RESPONSE_TIME,
@ -615,7 +615,7 @@ export const CARD_LIST: CardType[] = [
},
{
title: 'Request Load Time',
title: 'Avg. Request Load Time',
key: FilterKey.AVG_REQUEST_LOADT_IME,
cardType: WEB_VITALS,
metricOf: FilterKey.AVG_REQUEST_LOADT_IME,
@ -624,7 +624,7 @@ export const CARD_LIST: CardType[] = [
example: WebVital
},
{
title: 'Response Time',
title: 'Avg. Response Time',
key: FilterKey.AVG_RESPONSE_TIME,
cardType: WEB_VITALS,
metricOf: FilterKey.AVG_RESPONSE_TIME,
@ -634,7 +634,7 @@ export const CARD_LIST: CardType[] = [
},
{
title: 'Session Duration',
title: 'Avg. Session Duration',
key: FilterKey.AVG_SESSION_DURATION,
cardType: WEB_VITALS,
metricOf: FilterKey.AVG_SESSION_DURATION,
@ -644,7 +644,7 @@ export const CARD_LIST: CardType[] = [
},
{
title: 'Time Till First Byte',
title: 'Avg. Time Till First Byte',
key: FilterKey.AVG_TILL_FIRST_BYTE,
cardType: WEB_VITALS,
metricOf: FilterKey.AVG_TILL_FIRST_BYTE,
@ -654,7 +654,7 @@ export const CARD_LIST: CardType[] = [
},
{
title: 'Time to be Interactive',
title: 'Avg. Time to be Interactive',
key: FilterKey.AVG_TIME_TO_INTERACTIVE,
cardType: WEB_VITALS,
metricOf: FilterKey.AVG_TIME_TO_INTERACTIVE,
@ -664,7 +664,7 @@ export const CARD_LIST: CardType[] = [
},
{
title: 'Time to Render',
title: 'Avg. Time to Render',
key: FilterKey.AVG_TIME_TO_RENDER,
cardType: WEB_VITALS,
metricOf: FilterKey.AVG_TIME_TO_RENDER,
@ -674,7 +674,7 @@ export const CARD_LIST: CardType[] = [
},
{
title: 'JS Heap Size',
title: 'Avg. JS Heap Size',
key: FilterKey.AVG_USED_JS_HEAP_SIZE,
cardType: WEB_VITALS,
metricOf: FilterKey.AVG_USED_JS_HEAP_SIZE,

View file

@ -59,7 +59,7 @@ function FunnelIssues() {
return useObserver(() => (
<div className="bg-white rounded-lg mt-4 p-4 border">
<div className="flex">
<h2 className="font-medium text-xl">Most significant issues <span className="font-normal">identified in this funnel</span></h2>
<h2 className="font-medium text-xl">Significant issues <span className="font-normal"> in this funnel</span></h2>
</div>
<div className="my-6 flex justify-between items-center">
<FunnelIssuesDropdown />

View file

@ -116,7 +116,7 @@ function FunnelIssuesList(props: RouteComponentProps<Props>) {
show={!loading && filteredIssues.length === 0}
title={
<div className="flex flex-col items-center justify-center">
<AnimatedSVG name={ICONS.NO_ISSUES} size="170" />
<AnimatedSVG name={ICONS.NO_ISSUES} size={60} />
<div className="mt-4">No issues found</div>
</div>
}

View file

@ -38,15 +38,6 @@ function MetricViewHeader({siteId}: { siteId: string }) {
<div className='border-y px-6 py-1 mt-2 flex items-center w-full justify-between'>
<div className='items-center flex gap-4'>
<Toggler
label='My Cards'
checked={filter.showMine}
name='test'
className='font-medium mr-2'
onChange={() =>
metricStore.updateKey('filter', {...filter, showMine: !filter.showMine})
}
/>
<Select
options={[{label: 'All Types', value: 'all'}, ...DROPDOWN_OPTIONS]}
name='type'
@ -59,14 +50,14 @@ function MetricViewHeader({siteId}: { siteId: string }) {
/>
<DashboardDropdown
plain={true}
plain={false}
onChange={(value: any) =>
metricStore.updateKey('filter', {...filter, dashboard: value})
}
/>
</div>
<div className='flex items-center'>
<div className='flex items-center gap-2'>
<ListViewToggler/>
<Select
@ -80,6 +71,15 @@ function MetricViewHeader({siteId}: { siteId: string }) {
plain={true}
className='ml-4'
/>
<Toggler
label='My Cards'
checked={filter.showMine}
name='test'
className='font-medium mr-2'
onChange={() =>
metricStore.updateKey('filter', {...filter, showMine: !filter.showMine})
}
/>
</div>
{/*<AddCardSelectionModal open={showAddCardModal}/>*/}
@ -112,6 +112,7 @@ function DashboardDropdown({onChange, plain = false}: { plain?: boolean; onChang
value={metricStore.filter.dashboard}
onChange={({value}: any) => onChange(value)}
isMulti={true}
color='black'
/>
);
}

View file

@ -34,7 +34,7 @@ function ListView(props: Props) {
<div className="col-span-2">Owner</div>
<div className="col-span-2">Visibility</div>
<div className="col-span-2">Last Modified</div>
<div className={'col-span-2 text-right'}>Options</div>
<div className={'col-span-2 text-right invisible'}>Options</div>
</div>
{list.map((metric: any) => (
<MetricListItem

View file

@ -55,7 +55,7 @@ function MetricsList({
show={lenth === 0}
title={
<div className='flex flex-col items-center justify-center'>
<AnimatedSVG name={ICONS.NO_CARDS} size={180} />
<AnimatedSVG name={ICONS.NO_CARDS} size={60} />
<div className='text-center mt-4'>
{metricsSearch !== '' ? 'No matching results' : 'You haven\'t created any cards yet'}
</div>

View file

@ -142,7 +142,7 @@ function WidgetSessions(props: Props) {
<NoContent
title={
<div className='flex items-center justify-center flex-col'>
<AnimatedSVG name={ICONS.NO_SESSIONS} size={170} />
<AnimatedSVG name={ICONS.NO_SESSIONS} size={60} />
<div className='mt-4' />
<div className='text-center'>
No relevant sessions found for the selected time period

View file

@ -132,7 +132,7 @@ function WidgetView(props: Props) {
show={metricNotFound}
title={
<div className="flex flex-col items-center justify-between">
<AnimatedSVG name={ICONS.EMPTY_STATE} size={100}/>
<AnimatedSVG name={ICONS.EMPTY_STATE} size={60}/>
<div className="mt-4">Metric not found!</div>
</div>
}

View file

@ -62,7 +62,7 @@ function FFlagsList({ siteId }: { siteId: string }) {
show={featureFlagsStore.flags.length === 0}
title={
<div className={'flex flex-col items-center justify-center'}>
<AnimatedSVG name={ICONS.NO_FFLAGS} size={285} />
<AnimatedSVG name={ICONS.NO_FFLAGS} size={60} />
<div className="text-center text-gray-600 mt-4">
{featureFlagsStore.sort.query === ''
? "You haven't created any feature flags yet"

View file

@ -45,7 +45,7 @@ function FunnelIssues(props) {
<NoContent
title={
<div className="flex flex-col items-center justify-center">
<AnimatedSVG name={ICONS.NO_RESULTS} size="170" />
<AnimatedSVG name={ICONS.NO_RESULTS} size="60" />
<div className="mt-4">No Issues Found!</div>
</div>
}

View file

@ -6,9 +6,9 @@ function FunnelIssuesHeader({ criticalIssuesCount, filters }) {
<div className="flex items-center">
<div className="flex items-center mr-auto text-xl">
<div className="font-medium mr-2">
Most significant issues
Significant issues
</div>
<div className="mr-2">identified in this funnel</div>
<div className="mr-2">in this funnel</div>
</div>
</div>
)

View file

@ -31,7 +31,7 @@ function FunnelSessionList(props) {
<NoContent
title={
<div className="flex flex-col items-center justify-center">
<AnimatedSVG name={ICONS.NO_RESULTS} size="170" />
<AnimatedSVG name={ICONS.NO_RESULTS} size="60" />
<div className="mt-4">No recordings found!</div>
</div>
}

View file

@ -52,9 +52,9 @@ function FunnelWidget(props: Props) {
<NoContent
style={{ minHeight: 220 }}
title={
<div className="flex items-center">
<div className="flex items-center text-lg">
<Icon name="info-circle" className="mr-2" size="18" />
No data for selected period
No data available for the selected period.
</div>
}
show={!stages || stages.length === 0}

View file

@ -28,7 +28,7 @@ class SessionList extends React.PureComponent {
show={!loading && (similarSessionWithoutCurrent.length === 0 || similarSessionWithoutCurrent.size === 0)}
title={
<div className="flex items-center justify-center flex-col">
<AnimatedSVG name={ICONS.NO_SESSIONS} size={170} />
<AnimatedSVG name={ICONS.NO_SESSIONS} size={60} />
<div className="mt-2" />
<div className="text-center text-gray-600">No sessions found</div>
</div>

View file

@ -28,7 +28,7 @@ class SessionList extends React.PureComponent {
show={!loading && (similarSessionWithoutCurrent.length === 0 || similarSessionWithoutCurrent.size === 0)}
title={
<div className="flex items-center justify-center flex-col">
<AnimatedSVG name={ICONS.NO_SESSIONS} size={170} />
<AnimatedSVG name={ICONS.NO_SESSIONS} size={60} />
<div className="mt-2" />
<div className="text-center text-gray-600">No sessions found</div>
</div>

View file

@ -44,7 +44,7 @@ export default class FetchDetails extends React.PureComponent {
<NoContent
title={
<div className="flex flex-col items-center justify-center">
<AnimatedSVG name={ICONS.NO_RESULTS} size="170" />
<AnimatedSVG name={ICONS.NO_RESULTS} size="60" />
<div className="mt-4">Body is Empty</div>
</div>
}
@ -68,7 +68,7 @@ export default class FetchDetails extends React.PureComponent {
<NoContent
title={
<div className="flex flex-col items-center justify-center">
<AnimatedSVG name={ICONS.NO_RESULTS} size="170" />
<AnimatedSVG name={ICONS.NO_RESULTS} size="60" />
<div className="mt-4">Body is Empty</div>
</div>
}

View file

@ -9,7 +9,7 @@ function Headers(props) {
<NoContent
title={
<div className="flex flex-col items-center justify-center">
<AnimatedSVG name={ICONS.NO_RESULTS} size="170" />
<AnimatedSVG name={ICONS.NO_RESULTS} size="60" />
<div className="mt-4">No data available</div>
</div>
}

View file

@ -35,27 +35,27 @@ const ICONS_SVGS = {
[ICONS.EMPTY_STATE]: require('../../../svg/empty-state.svg').default,
[ICONS.LOGO_SMALL]: require('../../../svg/logo-small.svg').default,
[ICONS.LOGO_FULL]: require('../../../svg/logo.svg').default,
[ICONS.NO_RESULTS]: require('../../../svg/no-results.svg').default,
[ICONS.NO_RESULTS]: require('../../../svg/ghost.svg').default,
[ICONS.LOADER]: require('../../../svg/openreplay-preloader.svg').default,
[ICONS.SIGNAL_GREEN]: require('../../../svg/signal-green.svg').default,
[ICONS.SIGNAL_RED]: require('../../../svg/signal-red.svg').default,
[ICONS.NO_BOOKMARKS]: require('../../../svg/ca-no-bookmarked-session.svg').default,
[ICONS.NO_LIVE_SESSIONS]: require('../../../svg/ca-no-live-sessions.svg').default,
[ICONS.NO_SESSIONS]: require('../../../svg/ca-no-sessions.svg').default,
[ICONS.NO_SESSIONS_IN_VAULT]: require('../../../svg/ca-no-sessions-in-vault.svg').default,
[ICONS.NO_WEBHOOKS]: require('../../../svg/ca-no-webhooks.svg').default,
[ICONS.NO_METADATA]: require('../../../svg/ca-no-metadata.svg').default,
[ICONS.NO_ISSUES]: require('../../../svg/ca-no-issues.svg').default,
[ICONS.NO_AUDIT_TRAIL]: require('../../../svg/ca-no-audit-trail.svg').default,
[ICONS.NO_ANNOUNCEMENTS]: require('../../../svg/ca-no-announcements.svg').default,
[ICONS.NO_ALERTS]: require('../../../svg/ca-no-alerts.svg').default,
[ICONS.NO_NOTES]: require('../../../svg/ca-no-notes.svg').default,
[ICONS.NO_CARDS]: require('../../../svg/ca-no-cards.svg').default,
[ICONS.NO_RECORDINGS]: require('../../../svg/ca-no-recordings.svg').default,
[ICONS.NO_SEARCH_RESULTS]: require('../../../svg/ca-no-search-results.svg').default,
[ICONS.NO_BOOKMARKS]: require('../../../svg/ghost.svg').default,
[ICONS.NO_LIVE_SESSIONS]: require('../../../svg/ghost.svg').default,
[ICONS.NO_SESSIONS]: require('../../../svg/ghost.svg').default,
[ICONS.NO_SESSIONS_IN_VAULT]: require('../../../svg/ghost.svg').default,
[ICONS.NO_WEBHOOKS]: require('../../../svg/ghost.svg').default,
[ICONS.NO_METADATA]: require('../../../svg/ghost.svg').default,
[ICONS.NO_ISSUES]: require('../../../svg/ghost.svg').default,
[ICONS.NO_AUDIT_TRAIL]: require('../../../svg/ghost.svg').default,
[ICONS.NO_ANNOUNCEMENTS]: require('../../../svg/ghost.svg').default,
[ICONS.NO_ALERTS]: require('../../../svg/ghost.svg').default,
[ICONS.NO_NOTES]: require('../../../svg/ghost.svg').default,
[ICONS.NO_CARDS]: require('../../../svg/ghost.svg').default,
[ICONS.NO_RECORDINGS]: require('../../../svg/ghost.svg').default,
[ICONS.NO_SEARCH_RESULTS]: require('../../../svg/ghost.svg').default,
[ICONS.NO_DASHBOARDS]: require('../../../svg/ca-no-dashboards.svg').default,
[ICONS.NO_PROJECTS]: require('../../../svg/ca-no-projects.svg').default,
[ICONS.NO_FFLAGS]: require('../../../svg/no-fflags.svg').default,
[ICONS.NO_PROJECTS]: require('../../../svg/ghost.svg').default,
[ICONS.NO_FFLAGS]: require('../../../svg/ghost.svg').default,
[ICONS.PROCESSING]: require('../../../svg/ca-processing.svg').default,
[ICONS.NO_UXT]: require('../../../svg/empty-uxt-list.svg').default,
};

View file

@ -1,5 +1,5 @@
import React, { useState } from 'react';
import { Tooltip } from 'UI';
import { Tooltip } from 'antd';
import copy from 'copy-to-clipboard';
interface Props {
@ -17,7 +17,7 @@ function CopyText(props: Props) {
setTimeout(() => setIsCopied(false), 5000);
};
return (
<Tooltip delay={0} title={isCopied ? afterLabel : label}>
<Tooltip title={isCopied ? afterLabel : label} placement='top'>
<span onClick={onClick}>{children}</span>
</Tooltip>
);

View file

@ -103,7 +103,7 @@ function SessionListModal(props: Props) {
show={ !loading && (filteredSessions.length === 0 )}
title={
<div className="flex flex-col items-center justify-center">
<AnimatedSVG name={ICONS.NO_RESULTS} size="170" />
<AnimatedSVG name={ICONS.NO_RESULTS} size={60} />
<div className="mt-6 text-2xl">No recordings found!</div>
</div>
}

View file

@ -220,7 +220,7 @@ function ConsolePanel({
ref={_list}
deferredMeasurementCache={cache}
overscanRowCount={5}
estimatedRowSize={36}
estimatedRowSize={24}
rowCount={Math.ceil(filteredList.length || 1)}
rowHeight={cache.rowHeight}
rowRenderer={_rowRenderer}

View file

@ -34,7 +34,7 @@ function ConsoleRow(props: Props) {
<div
style={style}
className={cn(
'border-b flex items-center py-2 px-4 overflow-hidden group relative select-none',
'border-b flex items-start py-1 px-4 overflow-hidden group relative select-none',
{
info: !log.isYellow && !log.isRed,
warn: log.isYellow,
@ -48,14 +48,19 @@ function ConsoleRow(props: Props) {
<Icon size="14" {...iconProps} />
</div>
<div key={log.key} data-scroll-item={log.isRed}>
<div className="flex items-center">
<div className={cn('flex items-center', { 'cursor-pointer underline decoration-dotted decoration-gray-400': !!log.errorId })}>
<div className="flex items-start text-sm">
<div className={cn('flex items-start', { 'cursor-pointer underline decoration-dotted decoration-gray-400': !!log.errorId })}>
{canExpand && (
<Icon name={expanded ? 'caret-down-fill' : 'caret-right-fill'} className="mr-2" />
)}
<span style={{ fontFamily: 'Menlo, Monaco, Consolas' }}>{renderWithNL(lines.pop())}</span>
<span className='font-mono text-nowrap max-w-xs'>
{renderWithNL(lines.pop())}
</span>
</div>
{log.errorId && <TextEllipsis className="ml-2 overflow-hidden" text={log.message}></TextEllipsis>}
{log.errorId &&
<div className="ml-2 overflow-hidden text-ellipsis text-wrap font-mono">
<span className='w-full'>{log.message}</span>
</div>}
</div>
{canExpand &&
expanded &&

View file

@ -83,7 +83,7 @@ type State = TimeLineInfo & typeof initialState;
//const TABLE_HEIGHT = 195;
let _additionalHeight = 0;
const ROW_HEIGHT = 32;
const ROW_HEIGHT = 24;
//const VISIBLE_COUNT = Math.ceil(TABLE_HEIGHT/ROW_HEIGHT);
const TIME_SECTIONS_COUNT = 8;

View file

@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react';
import FetchBasicDetails from './components/FetchBasicDetails';
import { Button } from 'UI';
import { Button } from 'antd';
import { ArrowRightOutlined, ArrowLeftOutlined} from '@ant-design/icons';
import { ResourceType } from 'Player';
import FetchTabs from './components/FetchTabs/FetchTabs';
import { useStore } from 'App/mstore';
@ -53,17 +54,17 @@ function FetchDetailsModal(props: Props) {
return (
<div className="bg-white p-5 h-screen overflow-y-auto" style={{ width: '500px' }}>
<h5 className="mb-2 text-2xl">Network Request</h5>
<h5 className="mb-4 text-2xl ">Network Request</h5>
<FetchBasicDetails resource={resource} timestamp={props.time ? DateTime.fromMillis(props.time).setZone(timezone.value).toFormat(`hh:mm:ss a`) : undefined} />
{isXHR && <FetchTabs resource={resource} />}
{rows && rows.length > 0 && (
<div className="flex justify-between absolute bottom-0 left-0 right-0 p-3 border-t bg-white">
<Button variant="outline" onClick={prevClick} disabled={first}>
<Button type="text" onClick={prevClick} disabled={first} icon={<ArrowLeftOutlined />}>
Prev
</Button>
<Button variant="outline" onClick={nextClick} disabled={last}>
<Button type="text" onClick={nextClick} disabled={last} icon={<ArrowRightOutlined />}>
Next
</Button>
</div>

View file

@ -1,6 +1,7 @@
import React, { useMemo } from 'react';
import { formatBytes } from 'App/utils';
import CopyText from 'Shared/CopyText';
import {Tag} from 'antd';
import cn from 'classnames';
interface Props {
@ -33,56 +34,66 @@ function FetchBasicDetails({ resource, timestamp }: Props) {
</div>
</div>
{!!resource.decodedBodySize && (
<div className="flex items-center py-1">
<div className="font-medium">Size</div>
<div className="rounded bg-active-blue px-2 py-1 ml-2 whitespace-nowrap overflow-hidden text-clip">
{formatBytes(resource.decodedBodySize)}
</div>
</div>
)}
{resource.method && (
<div className="flex items-center py-1">
<div className="font-medium">Request Method</div>
<div className="rounded bg-active-blue px-2 py-1 ml-2 whitespace-nowrap overflow-hidden text-clip">
<div className="font-medium w-36">Request Method</div>
<Tag className='text-base rounded-lg bg-indigo-50 whitespace-nowrap overflow-hidden text-clip' bordered={false}>
{resource.method}
</div>
</Tag>
</div>
)}
{resource.status && (
<div className="flex items-center py-1">
<div className="font-medium">Status</div>
<div
<div className="text-base font-medium w-36">Status Code</div>
<Tag
bordered={false}
className={cn(
'rounded bg-active-blue px-2 py-1 ml-2 whitespace-nowrap overflow-hidden text-clip flex items-center',
'text-base rounded-lg bg-indigo-50 whitespace-nowrap overflow-hidden text-clip flex items-center',
{ 'error color-red': !resource.success }
)}
>
{resource.status === '200' && (
<div className="w-4 h-4 bg-green rounded-full mr-2"></div>
<Tag bordered={false} className="text-base bg-emerald-100 rounded-full mr-2"></Tag>
)}
{resource.status}
</div>
</Tag>
</div>
)}
<div className="flex items-center py-1">
<div className="font-medium w-36">Type</div>
<Tag className="text-base capitalize rounded-lg bg-indgo-50 whitespace-nowrap overflow-hidden text-clip" bordered={false}>
{resource.type}
</Tag>
</div>
{!!resource.decodedBodySize && (
<div className="flex items-center py-1">
<div className="font-medium w-36">Size</div>
<Tag className="text-base rounded-lg bg-indgo-50 whitespace-nowrap overflow-hidden text-clip" bordered={false}>
{formatBytes(resource.decodedBodySize)}
</Tag>
</div>
)}
{!!_duration && (
<div className="flex items-center py-1">
<div className="font-medium">Duration</div>
<div className="rounded bg-active-blue px-2 py-1 ml-2 whitespace-nowrap overflow-hidden text-clip">
<div className="font-medium w-36">Duration</div>
<Tag className="text-base rounded-lg bg-indgo-50 whitespace-nowrap overflow-hidden text-clip" bordered={false}>
{_duration} ms
</div>
</Tag>
</div>
)}
{timestamp && (
<div className="flex items-center py-1">
<div className="font-medium">Time</div>
<div className="rounded bg-active-blue px-2 py-1 ml-2 whitespace-nowrap overflow-hidden text-clip">
<div className="font-medium w-36">Time</div>
<Tag className="text-base rounded-lg bg-indgo-50 whitespace-nowrap overflow-hidden text-clip" bordered={false}>
{timestamp}
</div>
</Tag>
</div>
)}

View file

@ -105,15 +105,15 @@ function FetchTabs({ resource }: Props) {
<NoContent
title={
<div className="flex flex-col items-center justify-center">
<AnimatedSVG name={ICONS.NO_RESULTS} size={170} />
<div className="mt-6">
Body is Empty or not captured.
<AnimatedSVG name={ICONS.NO_RESULTS} size={30} />
<div className="mt-6 text-base font-normal">
Body is empty or not captured.
{' '}
<a href="https://docs.openreplay.com/installation/network-options" className="link" target="_blank">
Configure
</a>
{' '}
network capturing to get more out of fetch/XHR requests.
network capturing to get more out of Fetch/XHR requests.
</div>
</div>
}
@ -137,15 +137,15 @@ function FetchTabs({ resource }: Props) {
<NoContent
title={
<div className="flex flex-col items-center justify-center">
<AnimatedSVG name={ICONS.NO_RESULTS} size={170} />
<div className="mt-6">
Body is Empty or not captured.
<AnimatedSVG name={ICONS.NO_RESULTS} size={30} />
<div className="mt-6 text-base font-normal">
Body is empty or not captured.
{' '}
<a href="https://docs.openreplay.com/installation/network-options" className="link" target="_blank">
Configure
</a>
{' '}
network capturing to get more out of fetch/XHR requests.
network capturing to get more out of Fetch/XHR requests.
</div>
</div>
}

View file

@ -13,7 +13,7 @@ function Headers(props: Props) {
<NoContent
title={
<div className="flex flex-col items-center justify-center">
<AnimatedSVG name={ICONS.NO_RESULTS} size="170" />
<AnimatedSVG name={ICONS.NO_RESULTS} size="60" />
<div className="mt-6 text-2xl">No data available</div>
</div>
}

View file

@ -225,8 +225,8 @@ function FilterModal(props: Props) {
<div className="-mx-6 px-6">
{isResultEmpty && !fetchingFilterSearchList ? (
<div className="flex items-center flex-col">
<AnimatedSVG name={ICONS.NO_SEARCH_RESULTS} size={180} />
<div className="color-gray-medium font-medium px-3">
<AnimatedSVG name={ICONS.NO_SEARCH_RESULTS} size={30} />
<div className="color-gray-medium font-medium px-3 mt-4">
{' '}
No Suggestions Found
</div>

View file

@ -2,7 +2,7 @@ import React, {useState} from 'react';
import {Sankey, ResponsiveContainer} from 'recharts';
import CustomLink from './CustomLink';
import CustomNode from './CustomNode';
import {NoContent} from 'UI';
import {NoContent, Icon} from 'UI';
interface Node {
idd: string;
@ -101,7 +101,12 @@ const SankeyChart: React.FC<Props> = ({data, height = 240, onChartClick}: Props)
<NoContent
style={{paddingTop: '80px'}}
show={!data.nodes.length || !data.links.length}
title={'No data for the selected time period.'}
title={
<div className="flex items-center text-lg">
<Icon name="info-circle" className="mr-2" size="18" />
No data available for the selected period.
</div>
}
>
<ResponsiveContainer height={height} width='100%'>
<Sankey

View file

@ -119,7 +119,7 @@ function LiveSessionList(props: Props) {
<NoContent
title={
<div className="flex items-center justify-center flex-col">
<AnimatedSVG name={ICONS.NO_LIVE_SESSIONS} size={180} />
<AnimatedSVG name={ICONS.NO_LIVE_SESSIONS} size={60} />
<div className="mt-4" />
<div className="text-center">No live sessions found</div>
</div>

View file

@ -26,7 +26,7 @@ function ResultTimings({ duration, timing }) {
<NoContent
title={
<div className="flex flex-col items-center justify-center">
<AnimatedSVG name={ICONS.NO_RESULTS} size="170" />
<AnimatedSVG name={ICONS.NO_RESULTS} size="60" />
<div className="mt-6 text-2xl">No Data!</div>
</div>
}

View file

@ -22,7 +22,7 @@ function NotesList({ members }: { members: Array<Record<string, any>> }) {
title={
<div className="flex flex-col items-center justify-center">
{/* <Icon name="no-dashboard" size={80} color="figmaColors-accent-secondary" /> */}
<AnimatedSVG name={ICONS.NO_NOTES} size={180} />
<AnimatedSVG name={ICONS.NO_NOTES} size={60} />
<div className="text-center mt-4">No notes yet</div>
</div>
}

View file

@ -213,7 +213,9 @@ function SessionList(props: Props) {
<NoContent
title={
<div className='flex items-center justify-center flex-col'>
<AnimatedSVG name={NO_CONTENT.icon} size={180} />
<span className='py-5'>
<AnimatedSVG name={NO_CONTENT.icon} size={60} />
</span>
<div className='mt-4' />
<div className='text-center relative text-lg'>
{NO_CONTENT.message}

View file

@ -1,8 +1,6 @@
import React from 'react';
import { Icon, Tooltip } from 'UI';
import { Segmented } from 'antd';
import { ArrowDownOutlined, ArrowUpOutlined } from '@ant-design/icons';
import cn from 'classnames';
interface Props {
sortOrder: string;
@ -21,6 +19,7 @@ export default React.memo(function SortOrderButton(props: Props) {
{ label: 'Ascending', value: 'Ascending', icon: <ArrowUpOutlined /> },
{ label: 'Descending', value: 'Descending', icon: <ArrowDownOutlined /> },
]}
defaultValue="Descending"
onChange={(value) => {
if (value === 'Ascending') {
onChange('asc');

View file

@ -61,7 +61,7 @@ function UserSessionsModal(props: Props) {
<NoContent show={data.sessions.length === 0} title={
<div>
<AnimatedSVG name={ICONS.NO_SESSIONS} size={170} />
<AnimatedSVG name={ICONS.NO_SESSIONS} size={60} />
<div className="mt-4" />
<div className="text-center">No recordings found</div>
</div>

View file

@ -45,7 +45,7 @@ export default (props: Props) => {
};
let classes = cn(
'relative flex items-center h-10 px-3 rounded tracking-wide whitespace-nowrap',
'relative flex items-center h-10 px-3 rounded-lg tracking-wide whitespace-nowrap',
variantClasses[variant],
{ 'opacity-40 pointer-events-none': disabled },
{ '!rounded-full h-10 w-10 justify-center': rounded },

View file

@ -25,7 +25,7 @@ function Modal(props: Props) {
style.width = '300px';
break;
case 'small':
style.width = '400px';
style.width = '420px';
break;
case 'large':
style.width = '700px';

View file

@ -0,0 +1,5 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="23 10.5 104 129">
<path d="M75 12.5C61.7392 12.5 49.0215 17.7678 39.6447 27.1447C30.2678 36.5215 25 49.2392 25 62.5V137.5L43.75 118.75L59.375 134.375L75 118.75L90.625 134.375L106.25 118.75L125 137.5V62.5C125 49.2392 119.732 36.5215 110.355 27.1447C100.979 17.7678 88.2608 12.5 75 12.5Z" fill="#E2E4F6" stroke="#394EFF" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M56.25 62.5H56.3133" stroke="#394EFF" stroke-width="10" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M93.75 62.5H93.8133" stroke="#394EFF" stroke-width="10" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 680 B