Inline-Projektliste: neue Repos, Zuweisen mit Umzug, Preview einschalten, Pushes nachtragen
Implementiert auf TicketProjects.jsx (Paket-E-Inline-Liste) statt des frueheren Dialogs, gemaess Controller-Ruling R3. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
56489b8d6d
commit
3e3a9a3bbd
3 files changed
+160
-14
No files matched your search
@@ -1,7 +1,11 @@
|
||||
import { useState } from 'react'
|
||||
import { FaCodeBranch } from 'react-icons/fa'
|
||||
import { FaLinkSlash } from 'react-icons/fa6'
|
||||
import GiteaLinkButton from './GiteaLinkButton'
|
||||
import PreviewLinkButton from './PreviewLinkButton'
|
||||
import { suggestSubdomain } from '../lib/subdomain'
|
||||
import { needsPreviewButton, assignSummary } from '../lib/projectAssign'
|
||||
import { updateWebsiteProject, backfillProjectPushes } from '../lib/projectAdminApi'
|
||||
|
||||
const STATUS_COLORS = {
|
||||
ready: '#10b981',
|
||||
@@ -28,7 +32,49 @@ function StatusBadge({ label, value }) {
|
||||
)
|
||||
}
|
||||
|
||||
export default function AssignedProjectCard({ project, onUnassign, showActions = false }) {
|
||||
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 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 style={{ background: 'rgba(30,41,59,0.5)', border: '1px solid rgba(59,130,246,0.25)', borderRadius: 10, padding: '12px 14px', marginBottom: 12 }}>
|
||||
<div style={{ display: 'flex', gap: 8, alignItems: 'flex-start', justifyContent: 'space-between' }}>
|
||||
@@ -63,6 +109,46 @@ export default function AssignedProjectCard({ project, onUnassign, showActions =
|
||||
<StatusBadge label="Status" value={project.status} />
|
||||
<StatusBadge label="Provisioning" value={project.provisioningStatus} />
|
||||
</div>
|
||||
|
||||
{showActions && (
|
||||
<div style={{ marginTop: 10 }}>
|
||||
<div style={{ display: 'flex', gap: 8, flexWrap: 'wrap', alignItems: 'center' }}>
|
||||
{needsPreviewButton(project) && !showPreviewInput && (
|
||||
<button type="button" className="btn btn-sm" onClick={openPreviewInput}>
|
||||
Preview einschalten
|
||||
</button>
|
||||
)}
|
||||
{showPreviewInput && (
|
||||
<>
|
||||
<input
|
||||
type="text"
|
||||
className="form-control"
|
||||
style={{ maxWidth: 200 }}
|
||||
value={subdomain}
|
||||
onChange={(e) => setSubdomain(e.target.value)}
|
||||
/>
|
||||
<button
|
||||
type="button"
|
||||
className="btn btn-sm"
|
||||
disabled={!subdomain || previewBusy}
|
||||
onClick={handleEnablePreview}
|
||||
>
|
||||
Einschalten
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
<button type="button" className="btn btn-sm" disabled={pushBusy} onClick={handleBackfill}>
|
||||
Pushes nachtragen
|
||||
</button>
|
||||
</div>
|
||||
{(previewMessage || pushMessage) && (
|
||||
<div className="text-grey" style={{ marginTop: 6, fontSize: 12 }}>
|
||||
{previewMessage && <div>{previewMessage}</div>}
|
||||
{pushMessage && <div>{pushMessage}</div>}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
Reference in new issue
Block a user