Files
tickte-system/src/components/AssignedProjectCard.jsx
T

132 lines
4.8 KiB
React

import { useState } from 'react'
import { Badge, Button } from './ui'
import PreviewBlock from './PreviewBlock'
import AnalyseRow from './AnalyseRow'
import GiteaLinkButton from './GiteaLinkButton'
import PreviewLinkButton from './PreviewLinkButton'
import { statusValueTone } from './projectTones'
import { suggestSubdomain } from '../lib/subdomain'
import { needsPreviewButton, assignSummary } from '../lib/projectAssign'
import { updateWebsiteProject, backfillProjectPushes } from '../lib/projectAdminApi'
// Status und Provisioning: Wert als Badge, ohne Wert nichts
function StatusValue({ label, value }) {
if (!value) return null
return <span>{label}: <Badge tone={statusValueTone(value)}>{value}</Badge></span>
}
export default function AssignedProjectCard({ project, onUnassign, showActions = false, customerName = '', onChanged = () => {} }) {
const [showPreviewInput, setShowPreviewInput] = useState(false)
const [subdomain, setSubdomain] = useState('')
const [previewBusy, setPreviewBusy] = useState(false)
const [previewMessage, setPreviewMessage] = useState('')
const [pushBusy, setPushBusy] = useState(false)
const [pushMessage, setPushMessage] = useState('')
const [showPreviewBlock, setShowPreviewBlock] = useState(false)
const openPreviewInput = () => {
setSubdomain(suggestSubdomain(customerName, project.projectName))
setPreviewMessage('')
setShowPreviewInput(true)
}
const handleEnablePreview = async () => {
setPreviewBusy(true)
setPreviewMessage('')
try {
const r = await updateWebsiteProject(project.$id, { projectType: 'preview', subdomain })
setPreviewMessage(`Preview läuft: ${r.previewUrl}`)
setShowPreviewInput(false)
onChanged()
} catch (err) {
setPreviewMessage(err.message)
} finally {
setPreviewBusy(false)
}
}
const handleBackfill = async () => {
setPushBusy(true)
setPushMessage('')
try {
const r = await backfillProjectPushes(project.$id)
setPushMessage(assignSummary(project.projectName, r).text)
onChanged()
} catch (err) {
setPushMessage(err.message)
} finally {
setPushBusy(false)
}
}
return (
<div className="proj-item">
<div className="proj-head">
<div className="proj-main">
<strong>{project.projectName}</strong>
{project.subdomain && <>{' '}<span className="muted small">({project.subdomain})</span></>}
{project.repoFullName && <div className="cell-sub">{project.repoFullName}</div>}
</div>
<div className="row-actions">
<PreviewLinkButton href={project.previewUrl} subdomain={project.subdomain} />
<GiteaLinkButton href={project.giteaRepoUrl} />
{showActions && onUnassign && (
<Button variant="danger" type="button" title="Vom Ticket lösen" aria-label="Vom Ticket lösen" onClick={() => onUnassign(project.$id)}>
Lösen
</Button>
)}
</div>
</div>
{(project.status || project.provisioningStatus) && (
<div className="proj-meta">
<StatusValue label="Status" value={project.status} />
<StatusValue label="Provisioning" value={project.provisioningStatus} />
</div>
)}
{project.subdomain && <AnalyseRow key={project.$id} projectId={project.$id} />}
{showActions && project.subdomain && (
<>
<button type="button" className="link" aria-expanded={showPreviewBlock} onClick={() => setShowPreviewBlock((v) => !v)}>
Preview {showPreviewBlock ? '▴' : '▾'}
</button>
{showPreviewBlock && <PreviewBlock key={project.$id} projectId={project.$id} />}
</>
)}
{showActions && (
<>
<div className="row-actions">
{needsPreviewButton(project) && !showPreviewInput && (
<button type="button" className="link" onClick={openPreviewInput}>
Preview einschalten
</button>
)}
{showPreviewInput && (
<>
<input
type="text"
className="input"
aria-label="Subdomain für die Preview"
value={subdomain}
onChange={(e) => setSubdomain(e.target.value)}
/>
<Button type="button" disabled={!subdomain || previewBusy} onClick={handleEnablePreview}>
Einschalten
</Button>
</>
)}
<button type="button" className="link" disabled={pushBusy} onClick={handleBackfill}>
Pushes nachtragen
</button>
</div>
{previewMessage && <p className="msg muted">{previewMessage}</p>}
{pushMessage && <p className="msg muted">{pushMessage}</p>}
</>
)}
</div>
)
}