Testcraft Studio frontend 31: src/pages/Readiness.jsx
importReact,{useState}from'react';importIconfrom'../Icon.jsx';importTemplateUploadfrom'../TemplateUpload.jsx';import{useStudio,readiness,uid,timestamp,contextKey,log}from'../store.jsx';import{Badge,Button,ContextBar,Empty,Heading,Note,WorkspaceRequired}from'../ui.jsx';exportdefaultfunctionReadiness({navigate}){const{state:s,mutate,workspace:w}=useStudio();const[template,setTemplate]=useState(w?.templateId||s.templates.find(t=>t.team===s.session.team&&t.visibility!=='workspace')?.id||'');if (!w)return<WorkspaceRequirednavigate={navigate}/>;conststatus=readiness(s,w),jobs=s.jobs.filter(job=>job.workspaceId===w.id),running=jobs.find(job=>job.status==='running');consttemplates=s.templates.filter(t=>t.team===s.session.team&&(t.visibility!=='workspace'||t.workspaceId===w.id));functionstart(){if (!status.ready||running||!templates.some(t=>t.id===template))return;mutate(d=>{d.jobs.unshift({id:uid('run'),workspaceId:w.id,version:w.version,context:contextKey(w),templateId:template,provisional:false,status:'running',stageIndex:0,createdAt:timestamp(),stage:'Preparing workspace evidence'});log(d,`Started test suite for ${w.ref}`);});}return<><Headingeyebrow={`${w.ref} · FROM EVIDENCE TO TESTS`}title="Generate test cases"description="Choose your format and generate from the knowledge available in this workspace."/><ContextBarnavigate={navigate}/><divclassName="generation-layout margin-top"><sectionclassName="card padded generation-main"><divclassName="section-heading inset"><h2>Your test-case format</h2><spanclassName="soft-icon soft-purple"><Iconname="checkSquare"size={22}/></span></div><pclassName="supporting-copy">Use the standard format, select a saved template, or upload your own Excel template.</p><labelclassName="form-field"><span>Test-case template</span><selectvalue={template}onChange={e=>setTemplate(e.target.value)}>{templates.map(t=><optionvalue={t.id}key={t.id}>{t.name} · v{t.version}</option>)}</select></label><divclassName="template-upload-option"><TemplateUploadonSelected={setTemplate}/><small>Optional · Excel .xlsx or CSV · Headers in the first row</small></div><divclassName="generation-fields">{templates.find(t=>t.id===template)?.fields.map(field=><spankey={field}>{field}</span>)}</div><divclassName="generation-action"><Buttonvariant="primary"icon="spark"className="full-width"disabled={!status.ready||!template||!!running}onClick={start}>{running?'Generating test cases…':'Generate test cases'}</Button><p>Generation uses your approved baseline and reviewed evidence.</p></div></section><aside><sectionclassName="card padded"><divclassName="section-heading inset"><h2>Workspace evidence</h2><Badgetone={status.ready?'green':'neutral'}>{status.ready?'Ready':'Set up evidence'}</Badge></div><divclassName="evidence-check-row"><Iconname="layers"size={18}/><span>{status.selection?.baseline?.ref||'Connect an approved baseline'}</span></div><divclassName="evidence-check-row"><Iconname="file"size={18}/><span>{status.sources.length} accessible document{status.sources.length===1?'':'s'}</span></div>{status.blockers.map(issue=><Notekey={issue}>{issue}</Note>)}{!status.ready&&<ButtonclassName="full-width margin-top"onClick={()=>navigate('workspace')}>Open workspace evidence</Button>}</section><sectionclassName="card padded margin-top optional-help"><spanclassName="soft-icon soft-purple"><Iconname="chat"size={21}/></span><h2>Want to refine the results?</h2><p>You can answer optional clarifications or ask the system about uploaded documents. You can generate test cases without answering every question.</p><Buttonicon="chat"onClick={()=>navigate('chat')}>Open workspace chat</Button></section></aside></div><sectionclassName="card margin-top"><divclassName="section-heading"><h2>Generation history</h2></div>{jobs.map(job=><divclassName="job-row"key={job.id}><spanclassName={`soft-icon soft-${job.status==='Completed'?'green':'purple'}`}><Iconname={job.status==='Completed'?'check':'clock'}size={18}/></span><div><strong>Test suite · Context {job.version}</strong><p>{job.stage}</p><divclassName="stage-dots">{[0,1,2,3].map(index=><spankey={index}className={index<=job.stageIndex?'done':''}/>)}</div></div><Badge>{job.status}</Badge>{job.status==='running'?<ButtononClick={()=>mutate(d=>{constcurrent=d.jobs.find(item=>item.id===job.id);current.status='Cancelled';current.stage='Cancelled by user.';})}>Cancel</Button>:['Interrupted','Cancelled','Failed'].includes(job.status)?<Buttondisabled={!status.ready}onClick={start}>Retry</Button>:<ButtononClick={()=>navigate('suites')}>Review test suite</Button>}</div>)}{!jobs.length&&<Emptytitle="Your first suite starts here"description="Choose a template, then generate test cases."/>}</section></>;}
Top comments (0)
Subscribe
We're a place where coders share, stay up-to-date and grow their careers.
Top comments (0)