fix(ui) uxt fixes
This commit is contained in:
parent
d791c386f6
commit
949207102d
5 changed files with 72 additions and 35 deletions
|
|
@ -85,7 +85,7 @@ function FunnelWidget(props: Props) {
|
|||
));
|
||||
}
|
||||
|
||||
function EmptyStage({ total }: any) {
|
||||
export function EmptyStage({ total }: any) {
|
||||
return useObserver( () => (
|
||||
<div className={cn("flex items-center mb-4 pb-3", stl.step)}>
|
||||
<IndexNumber index={0} />
|
||||
|
|
|
|||
|
|
@ -2,29 +2,49 @@ import React from 'react';
|
|||
import { useStore } from 'App/mstore';
|
||||
import { numberWithCommas } from 'App/utils';
|
||||
import { Step } from 'Components/UsabilityTesting/TestEdit';
|
||||
import OutsideClickDetectingDiv from 'Shared/OutsideClickDetectingDiv';
|
||||
import { Loader, NoContent, Pagination } from 'UI';
|
||||
import { Button, Typography, Input } from 'antd';
|
||||
import { observer } from 'mobx-react-lite';
|
||||
import { DownOutlined } from '@ant-design/icons';
|
||||
import { debounce } from 'App/utils'
|
||||
|
||||
let debounceUpdate: any = () => {}
|
||||
|
||||
const ResponsesOverview = observer(() => {
|
||||
const { uxtestingStore } = useStore();
|
||||
const [search, setSearch] = React.useState('');
|
||||
const [page, setPage] = React.useState(1);
|
||||
const [showAll, setShowAll] = React.useState(false);
|
||||
const [taskId, setTaskId] = React.useState(uxtestingStore.instance?.tasks[0].taskId);
|
||||
const [taskId, setTaskId] = React.useState<number | undefined>(undefined);
|
||||
|
||||
React.useEffect(() => {
|
||||
void refreshData();
|
||||
setTaskId(uxtestingStore.instance?.tasks.filter((t) => t.allowTyping)[0].taskId);
|
||||
}, [uxtestingStore.instance?.tasks]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (taskId) {
|
||||
void refreshData();
|
||||
}
|
||||
}, [page, taskId]);
|
||||
|
||||
const refreshData = () =>
|
||||
debounceUpdate = debounce((text: string) => {
|
||||
void refreshData(text);
|
||||
}, 200)
|
||||
|
||||
const refreshDataQuery = (text: string) => {
|
||||
setSearch(text)
|
||||
debounceUpdate(text)
|
||||
}
|
||||
|
||||
const refreshData = (searchText?: string) =>
|
||||
taskId
|
||||
? uxtestingStore.fetchResponses(uxtestingStore.instance!.testId!, taskId, page, search)
|
||||
? uxtestingStore.fetchResponses(uxtestingStore.instance!.testId!, taskId, page, searchText || search)
|
||||
: null;
|
||||
|
||||
const selectedIndex = uxtestingStore.instance?.tasks.findIndex((task) => task.taskId === taskId)!;
|
||||
const task = uxtestingStore.instance?.tasks.find((task) => task.taskId === taskId);
|
||||
|
||||
return (
|
||||
<div style={{ width: 900 }} className={'h-screen p-4 bg-white flex flex-col gap-4'}>
|
||||
<Typography.Title style={{ marginBottom: 0 }} level={4}>
|
||||
|
|
@ -32,26 +52,28 @@ const ResponsesOverview = observer(() => {
|
|||
</Typography.Title>
|
||||
<div className={'flex flex-col gap-1 relative'}>
|
||||
<Typography.Text strong>Select Task / Question</Typography.Text>
|
||||
<Step
|
||||
ind={selectedIndex}
|
||||
title={task!.title}
|
||||
description={task!.description}
|
||||
buttons={
|
||||
<div className={'self-center'}>
|
||||
<Button
|
||||
onClick={() => setShowAll(!showAll)}
|
||||
icon={<DownOutlined rotate={showAll ? 180 : 0} rev={undefined} />}
|
||||
size={'small'}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
<OutsideClickDetectingDiv onClickOutside={() => setShowAll(false)}>
|
||||
<div className={'cursor-pointer'} onClick={() => setShowAll(!showAll)}>
|
||||
<Step
|
||||
ind={selectedIndex ?? 0}
|
||||
title={task?.title ?? 'Title'}
|
||||
description={task?.description ?? 'Description'}
|
||||
buttons={
|
||||
<div className={'self-center'}>
|
||||
<Button
|
||||
onClick={() => setShowAll(!showAll)}
|
||||
icon={<DownOutlined rotate={showAll ? 180 : 0} rev={undefined} />}
|
||||
size={'small'}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</OutsideClickDetectingDiv>
|
||||
{showAll ? (
|
||||
<div
|
||||
className={
|
||||
'flex flex-col overflow-auto absolute bottom-0 w-full gap-1 z-20 rounded bg-gray-lightest border shadow'
|
||||
}
|
||||
style={{ maxHeight: 300, transform: 'translateY(110%)' }}
|
||||
className={'flex flex-col overflow-auto absolute bottom-0 w-full z-20'}
|
||||
style={{ maxHeight: 300, transform: 'translateY(100%)' }}
|
||||
>
|
||||
{uxtestingStore.instance?.tasks
|
||||
.filter((t) => t.taskId !== taskId && t.allowTyping)
|
||||
|
|
@ -87,8 +109,8 @@ const ResponsesOverview = observer(() => {
|
|||
</div>
|
||||
<Input.Search
|
||||
allowClear
|
||||
placeholder={'Filter by keyboard or participant'}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
placeholder={'Filter by keyword or participant'}
|
||||
onChange={(e) => refreshDataQuery(e.target.value)}
|
||||
classNames={{ input: '!border-0 focus:!border-0' }}
|
||||
onSearch={() => refreshData()}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ import { confirm } from 'UI';
|
|||
import StepsModal from './StepsModal';
|
||||
import SidePanel from './SidePanel';
|
||||
import usePageTitle from 'App/hooks/usePageTitle';
|
||||
import { toast } from 'react-toastify'
|
||||
|
||||
const menuItems = [
|
||||
{
|
||||
|
|
@ -71,6 +72,7 @@ function TestEdit() {
|
|||
setHasChanged(false);
|
||||
if (testId && testId !== 'new') {
|
||||
uxtestingStore.updateTest(uxtestingStore.instance!).then((testId) => {
|
||||
toast.success('The usability test is now live and accessible to participants.');
|
||||
history.push(withSiteId(usabilityTestingView(testId!.toString()), siteId));
|
||||
});
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -29,18 +29,18 @@ import {
|
|||
} from '@ant-design/icons';
|
||||
import SessionItem from 'Shared/SessionItem';
|
||||
import { CopyButton, Loader, NoContent, Pagination } from 'UI';
|
||||
import copy from 'copy-to-clipboard';
|
||||
import { Stage } from 'Components/Funnels/FunnelWidget/FunnelWidget';
|
||||
import { Stage, EmptyStage } from 'Components/Funnels/FunnelWidget/FunnelWidget';
|
||||
import { confirm } from 'UI';
|
||||
import ResponsesOverview from './ResponsesOverview';
|
||||
import ParticipantOverviewItem from 'Components/UsabilityTesting/ParticipantOverview';
|
||||
import { toast } from 'react-toastify'
|
||||
|
||||
const { Option } = Select;
|
||||
|
||||
const statusItems = [
|
||||
{ value: 'in-progress', label: 'Ongoing', icon: <HourglassOutlined rev={undefined} /> },
|
||||
{ value: 'paused', label: 'On Hold', icon: <PauseCircleOutlined rev={undefined} /> },
|
||||
{ value: 'closed', label: 'Closed', icon: <StopOutlined rev={undefined} /> },
|
||||
{ value: 'paused', label: 'Hold', icon: <PauseCircleOutlined rev={undefined} /> },
|
||||
{ value: 'closed', label: 'Close', icon: <StopOutlined rev={undefined} /> },
|
||||
];
|
||||
|
||||
const menuItems = [
|
||||
|
|
@ -310,9 +310,9 @@ const TaskSummary = observer(() => {
|
|||
index={index + 1}
|
||||
/>
|
||||
))}
|
||||
{shouldHide ? (
|
||||
<div onClick={() => setShowAll(!showAll)} className={'link mt-4'}>
|
||||
{showAll ? 'Hide' : 'Show All'}
|
||||
{shouldHide && !showAll ? (
|
||||
<div className={'cursor-pointer'} onClick={() => setShowAll(true)}>
|
||||
<EmptyStage total={uxtestingStore.taskStats.length - 5}/>
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
|
|
@ -326,6 +326,17 @@ const Title = observer(({ testId, siteId }: any) => {
|
|||
|
||||
const handleChange = (value: string) => {
|
||||
uxtestingStore.updateTestStatus(value);
|
||||
switch (value) {
|
||||
case 'in-progress':
|
||||
toast.success('The usability test is now live and accessible to participants.');
|
||||
break;
|
||||
case 'paused':
|
||||
toast.success('Usability test is on \'Hold\'—participant activity paused. Resume at your convenience.');
|
||||
break;
|
||||
case 'closed':
|
||||
toast.success('he usability test has been marked as completed. All participant interactions are now finalized.');
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
const onMenuClick = async ({ key }: any) => {
|
||||
|
|
@ -397,7 +408,8 @@ const Title = observer(({ testId, siteId }: any) => {
|
|||
title={'Participants Link'}
|
||||
content={
|
||||
<div style={{ width: '220px' }}>
|
||||
<div className={'p-2 bg-white rounded border break-all mb-2'}>
|
||||
Distribute following link via email or other methods to share the survey with test participants.
|
||||
<div style={{ background: '#E4F6F6'}} className={'p-2 rounded border shadow break-all my-2'}>
|
||||
{`${uxtestingStore.instance!.startingPath}?oruxt=${
|
||||
uxtestingStore.instance!.testId
|
||||
}`}
|
||||
|
|
|
|||
|
|
@ -123,8 +123,9 @@ function SessionItem(props: RouteComponentProps & Props) {
|
|||
!ignoreAssist &&
|
||||
(isRoute(ASSIST_ROUTE, location.pathname) ||
|
||||
isRoute(ASSIST_LIVE_SESSION, location.pathname) ||
|
||||
location.pathname.includes('multiview'))
|
||||
|| location.pathname.includes('usability-testing');
|
||||
location.pathname.includes('multiview')) ||
|
||||
props.live
|
||||
|
||||
const isLastPlayed = lastPlayedSessionId === sessionId;
|
||||
|
||||
const _metaList = Object.keys(metadata)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue