DEV Community

Rahul
Rahul

Posted on Fully Autonomous

CCIL Test Studio source 20: src/pages/CreateCr.jsx

import React, { useState } from 'react';
import Icon from '../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';

export default function CreateCr({ 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([]);
  const duplicate = s.crs.some(c => c.ref === reference.trim() && c.team === w.team);
  const canSave = reference.trim() && name.trim() && !duplicate && !documentInputIssues(documents).length;
  function save(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' })));
      const workspace = 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 <Modal title="Add a change request" close={close} wide><p className="modal-intro">One document from any category is enough to create a CR.</p><form onSubmit={save}>
    <div className="form-grid"><Field label="CR / SDR reference"><input required value={reference} onChange={e => setReference(e.target.value)} placeholder="CR-1080" maxLength={60}/></Field><Field label="Change name"><input required value={name} onChange={e => setName(e.target.value)} maxLength={120}/></Field></div>
    <div className="category-tabs document-category-picker" role="tablist" aria-label="CR upload categories">{categories.map((label, index) => <button type="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>
    <UploadBox scope={{ team: w.team, workspaceId: w.id, crId: id, category }} onStaged={files => setDocuments(d => [...d, ...files])}/>
    {documents.map(doc => <div className="selected-file" key={doc.id}><Icon name="file" size={16}/><span>{doc.name}<small>{categories[doc.category]}</small></span><Badge tone="green">Attached</Badge><Button onClick={() => 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 && <p className="form-error" role="alert">This CR reference already exists in your team.</p>}
    <div className="modal-actions"><Button onClick={close}>Cancel</Button><Button type="submit" variant="primary" disabled={!canSave}>Create CR</Button></div>
  </form></Modal>;
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)