UNPKG

datajunction-ui

Version:
271 lines (253 loc) 7.69 kB
import React, { useState } from 'react'; /** * Modal for creating a pull request from a branch namespace. */ export function CreatePRModal({ isOpen, onClose, onCreate, namespace, gitBranch, parentBranch, repoPath, }) { const [title, setTitle] = useState(''); const [body, setBody] = useState(''); const [progress, setProgress] = useState(null); // null | 'syncing' | 'creating' const [error, setError] = useState(null); const [result, setResult] = useState(null); const handleSubmit = async e => { e.preventDefault(); if (!title.trim()) return; setError(null); setProgress('syncing'); try { const res = await onCreate( title.trim(), body.trim() || null, setProgress, ); if (res?._error) { setError(res.message); } else { setResult(res); } } catch (err) { setError(err.message || 'Failed to create pull request'); } finally { setProgress(null); } }; const getProgressText = () => { if (progress === 'syncing') return 'Syncing to git...'; if (progress === 'creating') return 'Creating PR...'; return 'Create PR'; }; const handleClose = () => { setTitle(''); setBody(''); setError(null); setResult(null); setProgress(null); onClose(); }; const isWorking = progress !== null; if (!isOpen) return null; return ( <div className="modal-overlay" onClick={handleClose}> <div className="modal-content" onClick={e => e.stopPropagation()} style={{ maxWidth: '560px' }} > <div className="modal-header"> <h3>Create Pull Request</h3> <button className="btn-close-modal" onClick={handleClose} title="Close" > × </button> </div> {result ? ( <div className="modal-body"> <div style={{ textAlign: 'center', padding: '16px 0', }} > <span style={{ display: 'inline-flex', alignItems: 'center', justifyContent: 'center', width: '48px', height: '48px', borderRadius: '50%', backgroundColor: '#dcfce7', color: '#16a34a', fontSize: '24px', marginBottom: '12px', }} ></span> <h4 style={{ margin: '0 0 8px 0' }}> Pull Request #{result.pr_number} Created! </h4> </div> <div style={{ backgroundColor: '#f8fafc', borderRadius: '6px', padding: '12px', fontSize: '13px', }} > <div style={{ marginBottom: '8px' }}> <strong>Title:</strong> {title} </div> <div style={{ marginBottom: '8px' }}> <strong>Branch:</strong> {result.head_branch} →{' '} {result.base_branch} </div> <div> <strong>URL:</strong>{' '} <a href={result.pr_url} target="_blank" rel="noopener noreferrer" style={{ color: '#3b82f6' }} > {result.pr_url} </a> </div> </div> <div className="modal-actions"> <button className="btn-secondary" onClick={handleClose}> Close </button> <a href={result.pr_url} target="_blank" rel="noopener noreferrer" className="btn-primary" style={{ textDecoration: 'none' }} > View on GitHub </a> </div> </div> ) : ( <form onSubmit={handleSubmit}> <div className="modal-body"> {/* Branch flow indicator */} <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: '12px', padding: '12px', backgroundColor: '#f8fafc', borderRadius: '6px', marginBottom: '16px', fontSize: '13px', }} > <span style={{ padding: '4px 8px', backgroundColor: '#dbeafe', borderRadius: '4px', fontFamily: 'monospace', }} > {gitBranch} </span> <span style={{ color: '#64748b' }}></span> <span style={{ padding: '4px 8px', backgroundColor: '#dcfce7', borderRadius: '4px', fontFamily: 'monospace', }} > {parentBranch} </span> </div> {error && ( <div style={{ padding: '12px', backgroundColor: '#fef2f2', border: '1px solid #fecaca', borderRadius: '6px', color: '#dc2626', fontSize: '13px', marginBottom: '16px', }} > {error} </div> )} <div className="form-group"> <label htmlFor="pr-title">Title *</label> <input id="pr-title" type="text" placeholder="Add new metrics for revenue tracking" value={title} onChange={e => setTitle(e.target.value)} disabled={isWorking} autoFocus /> </div> <div className="form-group"> <label htmlFor="pr-body">Description</label> <textarea id="pr-body" placeholder="Describe the changes in this pull request..." value={body} onChange={e => setBody(e.target.value)} disabled={isWorking} rows={4} style={{ width: '100%', padding: '8px 12px', border: '1px solid #e2e8f0', borderRadius: '6px', fontSize: '14px', fontFamily: 'inherit', resize: 'vertical', }} /> </div> </div> <div className="modal-actions"> <button type="button" className="btn-secondary" onClick={handleClose} disabled={isWorking} > Cancel </button> <button type="submit" className="btn-primary" disabled={isWorking || !title.trim()} > {getProgressText()} </button> </div> </form> )} </div> </div> ); } export default CreatePRModal;