132 lines
4.8 KiB
React
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>
|
|
)
|
|
}
|