+
Showing {Math.min(list.length, pageSize)} out of{' '}
{list.length} Alerts
diff --git a/frontend/app/components/Dashboard/components/DashboardWidgetGrid/DashboardWidgetGrid.tsx b/frontend/app/components/Dashboard/components/DashboardWidgetGrid/DashboardWidgetGrid.tsx
index 3c7e1b20c..7720101c0 100644
--- a/frontend/app/components/Dashboard/components/DashboardWidgetGrid/DashboardWidgetGrid.tsx
+++ b/frontend/app/components/Dashboard/components/DashboardWidgetGrid/DashboardWidgetGrid.tsx
@@ -1,12 +1,10 @@
import React from 'react';
import { useStore } from 'App/mstore';
-import WidgetWrapper from '../WidgetWrapper';
-import { NoContent, Loader, Icon } from 'UI';
-import { useObserver } from 'mobx-react-lite';
-import Widget from 'App/mstore/types/widget';
-import MetricTypeList from '../MetricTypeList';
import WidgetWrapperNew from 'Components/Dashboard/components/WidgetWrapper/WidgetWrapperNew';
import { Empty } from 'antd';
+import { NoContent, Loader } from 'UI';
+import { useObserver } from 'mobx-react-lite';
+import AnimatedSVG, { ICONS } from 'Shared/AnimatedSVG/AnimatedSVG';
interface Props {
siteId: string;
@@ -23,48 +21,50 @@ function DashboardWidgetGrid(props: Props) {
const list = useObserver(() => dashboard?.widgets);
return useObserver(() => (
- // @ts-ignore
- list?.length === 0 ?
: (
-
-
-
-
- There are no cards in this dashboard
+
+ {
+ list?.length === 0 ? (
+
+
+
+
+ There are no cards in this dashboard
+
+
+ Create a card by clicking the "Add Card" button to visualize insights here.
+
-
- Create a card from any of the below types or pick an existing one from your library.
-
-
-
- }
- >
-
- {
- list?.map((item: any, index: any) => (
-
-
- dashboard?.swapWidgetPosition(dragIndex, hoverIndex)
- }
- dashboardId={dashboardId}
- siteId={siteId}
- grid="other"
- showMenu={true}
- isSaved={true}
- />
-
- ))
- }
+ }
+ />
-
-
- )
+ ) : (
+
+ {list?.map((item: any, index: any) => (
+
+
+ dashboard?.swapWidgetPosition(dragIndex, hoverIndex)
+ }
+ dashboardId={dashboardId}
+ siteId={siteId}
+ grid="other"
+ showMenu={true}
+ isSaved={true}
+ />
+
+ ))}
+
+ )
+ }
+
));
}
diff --git a/frontend/app/components/Dashboard/components/MetricsList/MetricsList.tsx b/frontend/app/components/Dashboard/components/MetricsList/MetricsList.tsx
index cfdb3d714..e0ceafa7e 100644
--- a/frontend/app/components/Dashboard/components/MetricsList/MetricsList.tsx
+++ b/frontend/app/components/Dashboard/components/MetricsList/MetricsList.tsx
@@ -56,7 +56,7 @@ function MetricsList({
title={
-
+
{metricsSearch !== '' ? 'No matching results' : 'You haven\'t created any cards yet'}
diff --git a/frontend/app/components/FFlags/FFlagsList.tsx b/frontend/app/components/FFlags/FFlagsList.tsx
index e89a2050c..e73469809 100644
--- a/frontend/app/components/FFlags/FFlagsList.tsx
+++ b/frontend/app/components/FFlags/FFlagsList.tsx
@@ -63,7 +63,7 @@ function FFlagsList({ siteId }: { siteId: string }) {
title={
-
+
{featureFlagsStore.sort.query === ''
? "You haven't created any feature flags yet"
: 'No matching results'}
diff --git a/frontend/app/components/Session_/Player/Controls/components/TimelineZoomButton.tsx b/frontend/app/components/Session_/Player/Controls/components/TimelineZoomButton.tsx
index 1d3104ef5..e4e362675 100644
--- a/frontend/app/components/Session_/Player/Controls/components/TimelineZoomButton.tsx
+++ b/frontend/app/components/Session_/Player/Controls/components/TimelineZoomButton.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { connect } from 'react-redux';
-import { Button } from 'antd';
+import { Button, Tooltip } from 'antd';
import { toggleZoom } from 'Duck/components/player';
import { PlayerContext } from 'Components/Session/playerContext';
import { observer } from 'mobx-react-lite';
@@ -33,9 +33,11 @@ function TimelineZoomButton({ enabled, toggleZoom }: Props) {
}
}, [])
return (
+
- Timeline Zoom {enabled ? 'On' : 'Off'}
+ Focus Mode: {enabled ? 'On' : 'Off'}
+
);
}
diff --git a/frontend/app/components/UsabilityTesting/ParticipantOverview.tsx b/frontend/app/components/UsabilityTesting/ParticipantOverview.tsx
index 809ef0e8a..a76fc6d1d 100644
--- a/frontend/app/components/UsabilityTesting/ParticipantOverview.tsx
+++ b/frontend/app/components/UsabilityTesting/ParticipantOverview.tsx
@@ -11,7 +11,7 @@ function ParticipantOverviewItem({
addedNum?: string;
}) {
return (
-
+
{titleRow}
{firstNum ?
{firstNum} : null}
diff --git a/frontend/app/components/UsabilityTesting/SidePanel.tsx b/frontend/app/components/UsabilityTesting/SidePanel.tsx
index ce6784083..aec1a3a70 100644
--- a/frontend/app/components/UsabilityTesting/SidePanel.tsx
+++ b/frontend/app/components/UsabilityTesting/SidePanel.tsx
@@ -1,54 +1,78 @@
import { useStore } from 'App/mstore';
import React from 'react';
import { observer } from 'mobx-react-lite';
-import { Typography, Switch, Button, Space, Tooltip } from 'antd';
+import { Typography, Switch, Button, Space, Tooltip, Alert } from 'antd';
import { ExportOutlined } from '@ant-design/icons';
-const SidePanel = observer(({ onSave, onPreview, taskLen, isStartingPointValid }: any) => {
+interface SidePanelProps {
+ onSave: () => void;
+ onPreview: () => void;
+ taskLen: number;
+ isStartingPointValid: boolean;
+}
+
+const SidePanel: React.FC
= ({ onSave, onPreview, taskLen, isStartingPointValid }) => {
const { uxtestingStore } = useStore();
+
+ const canPublishOrPreview = taskLen > 0 && isStartingPointValid;
+
return (
-
+
Participant Requirements
-
- Mic
- uxtestingStore.instance!.setProperty('requireMic', checked)}
- checkedChildren="Yes"
- unCheckedChildren="No"
- />
-
-
- Camera
- uxtestingStore.instance!.setProperty('requireCamera', checked)}
- checkedChildren="Yes"
- unCheckedChildren="No"
- />
-
-
- Enable camera and mic options to watch participants' reactions and hear their comments for better insights into their experience.
+
+ Enable the camera and mic to observe participants' reactions and hear their comments for better insights.
+ {uxtestingStore.instance && (
+ <>
+
+ Mic
+ uxtestingStore.instance?.setProperty('requireMic', checked)}
+ checkedChildren="Required"
+ unCheckedChildren="Not Required"
+ />
+
+
+ Camera
+ uxtestingStore.instance?.setProperty('requireCamera', checked)}
+ checkedChildren="Required"
+ unCheckedChildren="Not Required"
+ />
+
+ >
+ )}
-
-
+ {!canPublishOrPreview && (
+
+ )}
+
+
+
- Save Draft & Preview
+ Save Draft & Preview
-
-
+
+
Publish Test
+
+
);
-});
+};
-export default SidePanel;
+export default observer(SidePanel);
diff --git a/frontend/app/components/UsabilityTesting/StepsModal.tsx b/frontend/app/components/UsabilityTesting/StepsModal.tsx
index 243b6a507..5baa71c51 100644
--- a/frontend/app/components/UsabilityTesting/StepsModal.tsx
+++ b/frontend/app/components/UsabilityTesting/StepsModal.tsx
@@ -81,7 +81,7 @@ function StepsModal({
checkedChildren="Yes"
unCheckedChildren="No"
/>
-
+
Enabling this option will show a text field for participants to type
their answer.
diff --git a/frontend/app/components/UsabilityTesting/TestEdit.tsx b/frontend/app/components/UsabilityTesting/TestEdit.tsx
index 37ff58535..79c95956f 100644
--- a/frontend/app/components/UsabilityTesting/TestEdit.tsx
+++ b/frontend/app/components/UsabilityTesting/TestEdit.tsx
@@ -10,6 +10,7 @@ import {
import { useParams, useHistory, Prompt } from 'react-router-dom';
import Breadcrumb from 'Shared/Breadcrumb';
import { EditOutlined, DeleteOutlined, MoreOutlined } from '@ant-design/icons';
+import {Power, Info, ListTodo} from 'lucide-react';
import { useModal } from 'App/components/Modal';
import { observer } from 'mobx-react-lite';
import { useStore } from 'App/mstore';
@@ -194,7 +195,7 @@ function TestEdit() {
-
+
{uxtestingStore.instance.title}
{uxtestingStore.instance.description}
@@ -206,32 +207,40 @@ function TestEdit() {
-
- 🏁 Starting point
- {
- setHasChanged(true);
- if (!e.target.value.startsWith('https://')) {
- e.target.value = 'https://';
- }
- uxtestingStore.instance!.setProperty('startingPath', e.target.value);
- }}
- />
- {uxtestingStore.instance!.startingPath === 'https://' || isStartingPointValid ? (
- The test starts at this URL, but not everyone visiting the link will see it. After publishing, you'll get a Distribution URL to share with selected participants.
- ) : (
- Starting point URL is invalid.
- )}
-
+
+
+ Starting point
+
+
{
+ setHasChanged(true);
+ let value = e.target.value;
+ if (value.startsWith('https://')) {
+ value = value.replace('https://', '');
+ }
+ uxtestingStore.instance!.setProperty('startingPath', 'https://' + value);
+ }}
+ />
+ {uxtestingStore.instance!.startingPath === 'https://' || isStartingPointValid ? (
+
+ The test will start on this page. A special link from this will be created for you to share with participants only.
+
+ ) : (
+
Invalid starting point.
+ )}
+
-
-
- 📖 Introduction and Guidelines for Participants
+
+
+
+
+ Introduction and Guidelines for Participants
{isOverviewEditing ? (
@@ -276,15 +285,15 @@ function TestEdit() {
>
) : (
- setIsOverviewEditing(true)}>
- {uxtestingStore.instance?.guidelines?.length ? 'Edit' : 'Add'}
+ setIsOverviewEditing(true)} className='px-0'>
+ {uxtestingStore.instance?.guidelines?.length ? 'Edit' : 'Specify Guidelines'}
)}
-
-
📋 Tasks
+
+
Tasks
{uxtestingStore.instance!.tasks.map((task, index) => (
-
🎉 Conclusion Message
+
🎉 Conclusion
{isConclusionEditing ? (
>
) : (
- setIsConclusionEditing(true)}>
+ setIsConclusionEditing(true)}>
Edit
)}
diff --git a/frontend/app/components/UsabilityTesting/TestOverview.tsx b/frontend/app/components/UsabilityTesting/TestOverview.tsx
index e8b4c3ffd..e990101ad 100644
--- a/frontend/app/components/UsabilityTesting/TestOverview.tsx
+++ b/frontend/app/components/UsabilityTesting/TestOverview.tsx
@@ -4,7 +4,8 @@ import { getPdf2 } from 'Components/AssistStats/pdfGenerator';
import { useModal } from 'Components/Modal';
import LiveTestsModal from 'Components/UsabilityTesting/LiveTestsModal';
import React from 'react';
-import { Button, Typography, Select, Space, Popover, Dropdown } from 'antd';
+import { Button, Typography, Select, Space, Popover, Dropdown, Tooltip } from 'antd';
+import { InfoCircleOutlined } from '@ant-design/icons';
import { withSiteId, usabilityTesting, usabilityTestingEdit } from 'App/routes';
import { useParams, useHistory } from 'react-router-dom';
import Breadcrumb from 'Shared/Breadcrumb';
@@ -106,7 +107,7 @@ function TestOverview() {
}, [testId, siteId]);
if (!uxtestingStore.instance) {
- return No data. ;
+ return No Data ;
} else {
document.title = `Usability Tests | ${uxtestingStore.instance.title}`;
}
@@ -128,8 +129,10 @@ function TestOverview() {
}
]}
/>
-
+
+
+
{uxtestingStore.instance.liveCount ? (
@@ -158,10 +161,12 @@ function TestOverview() {
) : null}
+
+
-
+
Open-ended task responses
@@ -178,11 +183,13 @@ function TestOverview() {
) : (
-
0 at the moment.
+
+ No Data
+
)}
-
+
Sessions
@@ -190,7 +197,12 @@ function TestOverview() {
{/*
clear selection
*/}
-
+
+ No Data
+
+ }>
{uxtestingStore.testSessions.list.map((session) => (
// @ts-ignore
@@ -231,7 +243,7 @@ const ParticipantOverview = observer(() => {
const { uxtestingStore } = useStore();
return (
-
+
Participant Overview
{uxtestingStore.testStats ? (
@@ -316,7 +328,7 @@ const TaskSummary = observer(() => {
: uxtestingStore.taskStats;
return (
-
+
Task Summary
@@ -337,7 +349,12 @@ const TaskSummary = observer(() => {
) : null}
- {!uxtestingStore.taskStats.length ?
: null}
+ {!uxtestingStore.taskStats.length ?
+ No Data
+
+ } /> : null}
{shownTasks.map((tst, index) => (
{
uxtestingStore.updateTestStatus(value);
switch (value) {
case 'in-progress':
- toast.success('The usability test is now live and accessible to participants.');
+ toast.success('The test is now live. Use the distribution link to share it with participants.');
break;
case 'paused':
toast.success(
- 'Usability test is on \'Hold\'—participant activity paused. Switch it to “ongoing” to resume activity.'
+ 'The test is on \'Hold\'—participant activity paused. Toggle back to “ongoing” to resume activity.'
);
break;
case 'closed':
toast.success(
- 'The usability test has been marked as completed. All participant interactions are now finalized.'
+ 'The test is complete and closed.'
);
break;
}
@@ -434,9 +451,10 @@ const Title = observer(({ testId, siteId }: any) => {
return (
-
{uxtestingStore.instance!.title}
+
{uxtestingStore.instance!.title}
{
)}
/>
-
{uxtestingStore.instance!.tasks.length} Tasks {' '}
-
+ */}
{isActive ?
-
- Distribute following link via email or other methods to share the survey with test
- participants.
+
+
+ Distribute the following link with test participants via email or other methods.
{`${uxtestingStore.instance!.startingPath}?oruxt=${
uxtestingStore.instance!.testId
}`}
{
}
>
-
+
+
- Distribute
+ Distribute Test
+
: null}
{
}>
- {truncatedDescr}
+ {truncatedDescr}
{uxtestingStore.instance?.description && uxtestingStore.instance.description.length > 250 ? (
setTruncate(!truncate)}>
{truncate ? 'Show more' : 'Show less'}
diff --git a/frontend/app/components/UsabilityTesting/UsabilityTesting.tsx b/frontend/app/components/UsabilityTesting/UsabilityTesting.tsx
index 36ae77bb6..d949217e4 100644
--- a/frontend/app/components/UsabilityTesting/UsabilityTesting.tsx
+++ b/frontend/app/components/UsabilityTesting/UsabilityTesting.tsx
@@ -132,7 +132,7 @@ function TestsTable() {
{uxtestingStore.searchQuery === '' ? (
) : null}
-
+
{uxtestingStore.searchQuery === ''
? 'Uncover real user insights through usability tests.'
: 'No results matching your search'}
@@ -215,11 +215,11 @@ function Row({ test, siteId }: { test: UxTListEntry; siteId: string }) {
-
+
{test.title}
-
@@ -230,7 +230,7 @@ function Row({ test, siteId }: { test: UxTListEntry; siteId: string }) {
{checkForRecent(getDateFromMill(test.updatedAt)!, 'LLL dd, yyyy, hh:mm a')}
- {statusMap[test.status]}
+ {statusMap[test.status]}
|
);
diff --git a/frontend/app/components/shared/LiveSessionList/LiveSessionList.tsx b/frontend/app/components/shared/LiveSessionList/LiveSessionList.tsx
index 5e3dd944a..417f1c8c2 100644
--- a/frontend/app/components/shared/LiveSessionList/LiveSessionList.tsx
+++ b/frontend/app/components/shared/LiveSessionList/LiveSessionList.tsx
@@ -121,7 +121,7 @@ function LiveSessionList(props: Props) {
-
No live sessions found
+
No live sessions found
}
subtext={
diff --git a/frontend/app/components/shared/SessionsTabOverview/components/Notes/NoteList.tsx b/frontend/app/components/shared/SessionsTabOverview/components/Notes/NoteList.tsx
index ebc808226..053bb3758 100644
--- a/frontend/app/components/shared/SessionsTabOverview/components/Notes/NoteList.tsx
+++ b/frontend/app/components/shared/SessionsTabOverview/components/Notes/NoteList.tsx
@@ -23,7 +23,7 @@ function NotesList({ members }: { members: Array
> }) {
{/*
*/}
-
No notes yet
+
No notes yet
}
subtext={
diff --git a/frontend/app/components/shared/SessionsTabOverview/components/SessionList/SessionList.tsx b/frontend/app/components/shared/SessionsTabOverview/components/SessionList/SessionList.tsx
index 275641058..12369b9c1 100644
--- a/frontend/app/components/shared/SessionsTabOverview/components/SessionList/SessionList.tsx
+++ b/frontend/app/components/shared/SessionsTabOverview/components/SessionList/SessionList.tsx
@@ -217,7 +217,7 @@ function SessionList(props: Props) {
-
diff --git a/frontend/app/styles/general.css b/frontend/app/styles/general.css
index 82da4b033..7228c05cd 100644
--- a/frontend/app/styles/general.css
+++ b/frontend/app/styles/general.css
@@ -416,3 +416,8 @@ p {
display: none;
}
+.utStatusToggler .ant-select-selector{
+ border-radius: .5rem;
+ box-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
+}
+
diff --git a/frontend/app/svg/empty-uxt-list.svg b/frontend/app/svg/empty-uxt-list.svg
index 215b1cee2..4a0a35929 100644
--- a/frontend/app/svg/empty-uxt-list.svg
+++ b/frontend/app/svg/empty-uxt-list.svg
@@ -1,20 +1,16 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+
\ No newline at end of file