import { Button, Input, Typography, Dropdown, Modal } from 'antd'; import { isValidUrl } from 'App/utils'; import React from 'react'; import { withSiteId, usabilityTesting, usabilityTestingView, usabilityTestingEdit, } from 'App/routes'; import { useParams, useHistory, Prompt } from 'react-router-dom'; import Breadcrumb from 'Shared/Breadcrumb'; import { EditOutlined, DeleteOutlined, MoreOutlined } from '@ant-design/icons'; import { useModal } from 'App/components/Modal'; import { observer } from 'mobx-react-lite'; import { useStore } from 'App/mstore'; 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 = [ { key: '1', label: 'Edit Title and Description', icon: , }, { key: '2', label: 'Delete', icon: , }, ]; function TestEdit() { // @ts-ignore const { siteId, testId } = useParams(); const [hasChanged, setHasChanged] = React.useState(testId === 'new'); const [typingEnabled, setTypingEnabled] = React.useState(false); const { uxtestingStore } = useStore(); const [newTestTitle, setNewTestTitle] = React.useState(''); const [newTestDescription, setNewTestDescription] = React.useState(''); const [conclusion, setConclusion] = React.useState(''); const [guidelines, setGuidelines] = React.useState(''); const [isModalVisible, setIsModalVisible] = React.useState(false); const [isConclusionEditing, setIsConclusionEditing] = React.useState(false); const [isOverviewEditing, setIsOverviewEditing] = React.useState(false); const { showModal, hideModal } = useModal(); const history = useHistory(); usePageTitle(`Usability Tests | ${uxtestingStore.instance ? 'Edit' : 'Create'}`); React.useEffect(() => { if (uxtestingStore.instanceCreationSiteId && siteId !== uxtestingStore.instanceCreationSiteId) { history.push(withSiteId(usabilityTesting(), siteId)); } }, [siteId]); React.useEffect(() => { if (testId && testId !== 'new') { uxtestingStore.getTestData(testId).then((inst) => { if (inst) { setConclusion(inst.conclusionMessage || ''); setGuidelines(inst.guidelines || ''); } }); } else { if (!uxtestingStore.instance) { history.push(withSiteId(usabilityTesting(), siteId)); } else { setConclusion(uxtestingStore.instance!.conclusionMessage); setGuidelines(uxtestingStore.instance!.guidelines); } } }, []); if (!uxtestingStore.instance) { return
Loading...
; } const onSave = (isPreview?: boolean) => { setHasChanged(false); if (testId && testId !== 'new') { uxtestingStore.updateTest(uxtestingStore.instance!, isPreview).then((testId) => { if (isPreview) { window.open( `${uxtestingStore.instance!.startingPath}?oruxt=${testId}`, '_blank', 'noopener,noreferrer' ); } else { toast.success('The usability test is now live and accessible to participants.'); history.push(withSiteId(usabilityTestingView(testId!.toString()), siteId)); } }); } else { uxtestingStore.createNewTest(isPreview).then((test) => { if (isPreview) { window.open(`${test.startingPath}?oruxt=${test.testId}`, '_blank', 'noopener,noreferrer'); history.replace(withSiteId(usabilityTestingEdit(test.testId), siteId)); } else { history.push(withSiteId(usabilityTestingView(test.testId), siteId)); } }); } }; const onClose = (confirmed: boolean) => { if (confirmed) { uxtestingStore.instance!.setProperty('title', newTestTitle); uxtestingStore.instance!.setProperty('description', newTestDescription); } setNewTestDescription(''); setNewTestTitle(''); setIsModalVisible(false); }; const onMenuClick = async ({ key }: { key: string }) => { if (key === '1') { setNewTestTitle(uxtestingStore.instance!.title); setNewTestDescription(uxtestingStore.instance!.description); setIsModalVisible(true); } if (key === '2') { if ( await confirm({ confirmation: 'Are you sure you want to delete this usability test? This action cannot be undone.', }) ) { uxtestingStore.deleteTest(testId).then(() => { history.push(withSiteId(usabilityTesting(), siteId)); }); } } }; const isPublished = uxtestingStore.instance.status !== undefined && uxtestingStore.instance.status !== 'preview'; const isStartingPointValid = isValidUrl(uxtestingStore.instance.startingPath); return (
{ return 'You have unsaved changes. Are you sure you want to leave?'; }} /> onClose(true)} onCancel={() => onClose(false)} footer={ } > Title { setHasChanged(true); setNewTestTitle(e.target.value); }} /> Test Objective (optional) { setHasChanged(true); setNewTestDescription(e.target.value); }} placeholder="Share a brief statement about what you aim to discover through this study." />
{uxtestingStore.instance.title} {uxtestingStore.instance.description}
🏁 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 ? ( Test will begin on this page. ) : ( Starting point URL is invalid. )}
📖 Introduction and Guidelines for Participants {isOverviewEditing ? ( { setHasChanged(true); setGuidelines(e.target.value); }} /> ) : (
{uxtestingStore.instance?.guidelines?.length ? uxtestingStore.instance.guidelines : 'Provide an overview of this usability test to and input guidelines that can be of assistance to users at any point during the test.'}
)}
{isOverviewEditing ? ( <> ) : ( )}
📋 Tasks {uxtestingStore.instance!.tasks.map((task, index) => (
🎉 Conclusion Message
{isConclusionEditing ? ( { setHasChanged(true); setConclusion(e.target.value); }} /> ) : ( {uxtestingStore.instance!.conclusionMessage} )}
{isConclusionEditing ? ( <> ) : ( )}
onSave(false)} onPreview={() => onSave(true)} />
); } export function Step({ buttons, ind, title, description, hover, }: { buttons?: React.ReactNode; ind: number; title: string; description: string | null; hover?: boolean; }) { const safeTitle = title.length > 120 ? title.slice(0, 120) + '...' : title; const safeDescription = description && description?.length > 300 ? description.slice(0, 300) + '...' : description; return (
{ind + 1}
{safeTitle}
{safeDescription}
{buttons}
); } export default observer(TestEdit);