This commit is contained in:
@@ -1209,7 +1209,7 @@ function ArtefactDetailPanel({ artefact, onClose, onUpdate, onDelete, projects =
|
||||
)}
|
||||
|
||||
{/* Submit for Review */}
|
||||
{artefact.status === 'draft' && (
|
||||
{['draft', 'revision_requested', 'rejected'].includes(artefact.status) && (
|
||||
<div className="border-t border-border pt-6">
|
||||
<button
|
||||
onClick={handleSubmitReview}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { useParams } from 'react-router-dom'
|
||||
import { CheckCircle, XCircle, AlertCircle, FileText, Image as ImageIcon, Film, Sparkles, Globe } from 'lucide-react'
|
||||
import { CheckCircle, XCircle, AlertCircle, FileText, Image as ImageIcon, Film, Sparkles, Globe, User } from 'lucide-react'
|
||||
|
||||
const STATUS_ICONS = {
|
||||
copy: FileText,
|
||||
@@ -35,6 +35,10 @@ export default function PublicReview() {
|
||||
}
|
||||
const data = await res.json()
|
||||
setArtefact(data)
|
||||
// Auto-set reviewer name if there's exactly one approver
|
||||
if (data.approvers?.length === 1 && data.approvers[0].name) {
|
||||
setReviewerName(data.approvers[0].name)
|
||||
}
|
||||
} catch (err) {
|
||||
setError('Failed to load artefact')
|
||||
} finally {
|
||||
@@ -44,7 +48,7 @@ export default function PublicReview() {
|
||||
|
||||
const handleAction = async (action) => {
|
||||
if (!reviewerName.trim()) {
|
||||
alert('Please enter your name')
|
||||
alert('Please select or enter your name')
|
||||
return
|
||||
}
|
||||
|
||||
@@ -395,15 +399,34 @@ export default function PublicReview() {
|
||||
<h3 className="text-lg font-semibold text-text-primary mb-4">Your Review</h3>
|
||||
|
||||
<div className="space-y-4 mb-6">
|
||||
{/* Reviewer identity */}
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-text-primary mb-1">Your Name *</label>
|
||||
<input
|
||||
type="text"
|
||||
value={reviewerName}
|
||||
onChange={e => setReviewerName(e.target.value)}
|
||||
placeholder="Enter your name"
|
||||
className="w-full px-4 py-2 border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-brand-primary/20 focus:border-brand-primary bg-surface transition-colors"
|
||||
/>
|
||||
<label className="block text-sm font-medium text-text-primary mb-1">Reviewer</label>
|
||||
{artefact.approvers?.length === 1 ? (
|
||||
<div className="flex items-center gap-2 px-4 py-2 bg-surface-secondary border border-border rounded-lg">
|
||||
<User className="w-4 h-4 text-text-tertiary" />
|
||||
<span className="text-sm text-text-primary">{artefact.approvers[0].name}</span>
|
||||
</div>
|
||||
) : artefact.approvers?.length > 1 ? (
|
||||
<select
|
||||
value={reviewerName}
|
||||
onChange={e => setReviewerName(e.target.value)}
|
||||
className="w-full px-4 py-2 text-sm border border-border rounded-lg bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-brand-primary/20 focus:border-brand-primary transition-colors"
|
||||
>
|
||||
<option value="">Select your name...</option>
|
||||
{artefact.approvers.map(a => (
|
||||
<option key={a.id} value={a.name}>{a.name}</option>
|
||||
))}
|
||||
</select>
|
||||
) : (
|
||||
<input
|
||||
type="text"
|
||||
value={reviewerName}
|
||||
onChange={e => setReviewerName(e.target.value)}
|
||||
placeholder="Enter your name"
|
||||
className="w-full px-4 py-2 text-sm border border-border rounded-lg bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-brand-primary/20 focus:border-brand-primary transition-colors"
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
@@ -413,7 +436,7 @@ export default function PublicReview() {
|
||||
onChange={e => setFeedback(e.target.value)}
|
||||
rows={4}
|
||||
placeholder="Share your thoughts, suggestions, or required changes..."
|
||||
className="w-full px-4 py-2 border border-border rounded-lg focus:outline-none focus:ring-2 focus:ring-brand-primary/20 focus:border-brand-primary bg-surface transition-colors"
|
||||
className="w-full px-4 py-2 text-sm border border-border rounded-lg bg-surface text-text-primary focus:outline-none focus:ring-2 focus:ring-brand-primary/20 focus:border-brand-primary transition-colors"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -3492,9 +3492,18 @@ app.get('/api/public/review/:token', async (req, res) => {
|
||||
limit: 1000,
|
||||
});
|
||||
|
||||
// Resolve approver names
|
||||
const approvers = [];
|
||||
if (artefact.approver_ids) {
|
||||
for (const id of artefact.approver_ids.split(',').filter(Boolean)) {
|
||||
approvers.push({ id: Number(id), name: await getRecordName('Users', Number(id)) });
|
||||
}
|
||||
}
|
||||
|
||||
res.json({
|
||||
...artefact,
|
||||
brand_name: await getRecordName('Brands', artefact.brand_id),
|
||||
approvers,
|
||||
version: versionData,
|
||||
version_number: reviewVersionNumber,
|
||||
texts,
|
||||
@@ -3569,7 +3578,7 @@ app.post('/api/public/review/:token/reject', async (req, res) => {
|
||||
});
|
||||
|
||||
app.post('/api/public/review/:token/revision', async (req, res) => {
|
||||
const { feedback } = req.body;
|
||||
const { feedback, approved_by_name } = req.body;
|
||||
try {
|
||||
const artefacts = await nocodb.list('Artefacts', {
|
||||
where: `(approval_token,eq,${req.params.token})`,
|
||||
@@ -3586,6 +3595,7 @@ app.post('/api/public/review/:token/revision', async (req, res) => {
|
||||
|
||||
await nocodb.update('Artefacts', artefact.Id, {
|
||||
status: 'revision_requested',
|
||||
approved_by_name: approved_by_name || '',
|
||||
feedback: feedback || '',
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user