DEV Community

Rahul
Rahul

Posted on

Testcraft Studio frontend 13: src/TemplateUpload.jsx

import React, { useState } from 'react';
import Icon from './Icon.jsx';
import { readTemplate, saveTemplateImport } from './excel.js';
import { useStudio, uid, log } from './store.jsx';
import { Button, Modal, Note } from './ui.jsx';

export default function TemplateUpload({ onSelected, disabled = false }) {
  const { mutate, workspace, notify } = useStudio();
  const [imported, setImported] = useState(null), [error, setError] = useState(''), [busy, setBusy] = useState(false);
  async function upload(event) {
    const file = event.target.files?.[0]; event.target.value = ''; if (!file || disabled) return;
    setError(''); setBusy(true);
    try { setImported(await readTemplate(file)); } catch (failure) { setError(failure.message); } finally { setBusy(false); }
  }
  function save() { if (disabled) return; const id = uid('template'); mutate(d => { saveTemplateImport(d, imported, workspace?.id, id); log(d, `Uploaded test template ${imported.name}`); }); onSelected?.(id); setImported(null); notify('Excel template selected. Its columns will be used for the test suite.'); }
  return <><label className={`button button-secondary file-button ${busy ? 'is-busy' : ''}`}><Icon name="upload" size={16}/>{busy ? 'Reading template…' : 'Upload Excel template'}<input aria-label="Upload Excel template" type="file" disabled={busy || disabled} accept=".xlsx,.csv" onChange={upload}/></label>{error && <p className="form-error" role="alert">{error}</p>}{imported && <Modal title="Review your test-case template" close={() => setImported(null)} wide><p className="modal-intro">{imported.name}{imported.sourceSheet ? ` · ${imported.sourceSheet}` : ''}</p><div className="field-chips">{imported.fields.map((field, index) => <span key={field}>{index + 1}. {field}</span>)}</div><div className="table-scroll import-table"><table><thead><tr>{imported.fields.map(field => <th key={field}>{field}</th>)}</tr></thead><tbody>{imported.rows.slice(0, 3).map((row, index) => <tr key={index}>{imported.fields.map((field, column) => <td key={field}>{row[column] || '—'}</td>)}</tr>)}</tbody></table></div><Note>These column names define the output format. Example rows are formatting references; expected results come from your workspace evidence.</Note><div className="modal-actions"><Button onClick={() => setImported(null)}>Cancel</Button><Button variant="primary" onClick={save}>Use this template</Button></div></Modal>}</>;
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)