Testcraft Studio frontend 26: src/pages/CreateCr.jsx
importReact,{useState}from'react';importIconfrom'../Icon.jsx';import{categories}from'../seed.js';import{documentInputIssues}from'../access.js';import{useStudio,uid,bumpVersion,log}from'../store.jsx';import{Badge,Button,Field,Modal,Note,UploadBox}from'../ui.jsx';exportdefaultfunctionCreateCr({close}){const{state:s,workspace:w,mutate,notify}=useStudio();const[id]=useState(()=>uid('cr'));const[reference,setReference]=useState(''),[name,setName]=useState('');const[category,setCategory]=useState(0),[documents,setDocuments]=useState([]);constduplicate=s.crs.some(c=>c.ref===reference.trim()&&c.team===w.team);constcanSave=reference.trim()&&name.trim()&&!duplicate&&!documentInputIssues(documents).length;functionsave(event){event.preventDefault();if (!canSave)return;mutate(d=>{d.crs.push({id,ref:reference.trim(),name:name.trim(),team:w.team,revision:1,requires:[],conflicts:[],changes:[]});d.documents.push(...documents.map(doc=>({...doc,status:'Ready'})));constworkspace=d.workspaces.find(item=>item.id===w.id);workspace.crIds.push(id);bumpVersion(d,workspace);log(d,`Created ${reference.trim()} with ${documents.length} document(s)`);});close();notify('CR created with its supporting document(s). No separate approval is required.');}return<Modaltitle="Add a change request"close={close}wide><pclassName="modal-intro">One document from any category is enough to create a CR.</p><formonSubmit={save}><divclassName="form-grid"><Fieldlabel="CR / SDR reference"><inputrequiredvalue={reference}onChange={e=>setReference(e.target.value)}placeholder="CR-1080"maxLength={60}/></Field><Fieldlabel="Change name"><inputrequiredvalue={name}onChange={e=>setName(e.target.value)}maxLength={120}/></Field></div><divclassName="category-tabs document-category-picker"role="tablist"aria-label="CR upload categories">{categories.map((label,index)=><buttontype="button"role="tab"aria-selected={category===index}className={category===index?'active':''}key={label}onClick={()=>setCategory(index)}>{label}<span>{documents.filter(d=>d.category===index).length}</span></button>)}</div><UploadBoxscope={{team:w.team,workspaceId:w.id,crId:id,category}}onStaged={files=>setDocuments(d=>[...d,...files])}/>{documents.map(doc=><divclassName="selected-file"key={doc.id}><Iconname="file"size={16}/><span>{doc.name}<small>{categories[doc.category]}</small></span><Badgetone="green">Attached</Badge><ButtononClick={()=>setDocuments(files=>files.filter(f=>f.id!==doc.id))}>Remove</Button></div>)}<Note>{documents.length?'The one-document minimum is met. Other categories can remain empty.':'Upload at least one Business, Technical, or Functional / Bug Information document. All three are not required.'}</Note>{duplicate&&<pclassName="form-error"role="alert">This CR reference already exists in your team.</p>}<divclassName="modal-actions"><ButtononClick={close}>Cancel</Button><Buttontype="submit"variant="primary"disabled={!canSave}>Create CR</Button></div></form></Modal>;}
Top comments (0)
Subscribe
We're a place where coders share, stay up-to-date and grow their careers.
Top comments (0)