feat(admin): add standalone submission package modal support
- Add data-is-standalone flag to manage-submission buttons
- Create openStandaloneSubmissionModal function for packages without blog posts
- Update renderOverviewTab to handle null article (standalone submissions)
- Display standalone submission notice with purple badge
- Load submission data directly via /api/submissions/{id}
- Differentiate UI labels (Submitted vs Published dates)
- Files modified: blog-validation.js, submission-modal-enhanced.js
This commit is contained in:
parent
c4f370cc6e
commit
9729878f96
3 changed files with 91 additions and 21 deletions
|
|
@ -43,8 +43,8 @@
|
||||||
"last_deliberation": null
|
"last_deliberation": null
|
||||||
},
|
},
|
||||||
"FileEditHook": {
|
"FileEditHook": {
|
||||||
"timestamp": "2025-10-23T22:02:15.582Z",
|
"timestamp": "2025-10-23T22:06:08.878Z",
|
||||||
"file": "/home/theflow/projects/tractatus/public/js/admin/blog-curation-enhanced.js",
|
"file": "/home/theflow/projects/tractatus/public/js/admin/submission-modal-enhanced.js",
|
||||||
"result": "passed"
|
"result": "passed"
|
||||||
},
|
},
|
||||||
"FileWriteHook": {
|
"FileWriteHook": {
|
||||||
|
|
@ -58,25 +58,25 @@
|
||||||
"tokens": 30000
|
"tokens": 30000
|
||||||
},
|
},
|
||||||
"alerts": [],
|
"alerts": [],
|
||||||
"last_updated": "2025-10-23T22:02:15.582Z",
|
"last_updated": "2025-10-23T22:06:08.878Z",
|
||||||
"initialized": true,
|
"initialized": true,
|
||||||
"framework_components": {
|
"framework_components": {
|
||||||
"CrossReferenceValidator": {
|
"CrossReferenceValidator": {
|
||||||
"message": 0,
|
"message": 0,
|
||||||
"tokens": 0,
|
"tokens": 0,
|
||||||
"timestamp": "2025-10-23T22:02:25.695Z",
|
"timestamp": "2025-10-23T22:06:19.032Z",
|
||||||
"last_validation": "2025-10-23T22:02:25.694Z",
|
"last_validation": "2025-10-23T22:06:19.032Z",
|
||||||
"validations_performed": 766
|
"validations_performed": 773
|
||||||
},
|
},
|
||||||
"BashCommandValidator": {
|
"BashCommandValidator": {
|
||||||
"message": 0,
|
"message": 0,
|
||||||
"tokens": 0,
|
"tokens": 0,
|
||||||
"timestamp": null,
|
"timestamp": null,
|
||||||
"last_validation": "2025-10-23T22:02:25.695Z",
|
"last_validation": "2025-10-23T22:06:19.033Z",
|
||||||
"validations_performed": 414,
|
"validations_performed": 417,
|
||||||
"blocks_issued": 37
|
"blocks_issued": 37
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"action_count": 414,
|
"action_count": 417,
|
||||||
"auto_compact_events": []
|
"auto_compact_events": []
|
||||||
}
|
}
|
||||||
|
|
@ -221,7 +221,8 @@ async function loadValidationArticles() {
|
||||||
<div class="ml-4 flex items-center gap-2 flex-wrap">
|
<div class="ml-4 flex items-center gap-2 flex-wrap">
|
||||||
<button class="manage-submission px-4 py-2 bg-green-600 text-white rounded-md text-sm hover:bg-green-700"
|
<button class="manage-submission px-4 py-2 bg-green-600 text-white rounded-md text-sm hover:bg-green-700"
|
||||||
data-article-id="${itemId}"
|
data-article-id="${itemId}"
|
||||||
data-submission-id="${submission ? submission._id : ''}">
|
data-submission-id="${submission ? submission._id : ''}"
|
||||||
|
data-is-standalone="${isStandalone ? 'true' : 'false'}">
|
||||||
${isStandalone ? 'View Package' : 'Manage Submission'}
|
${isStandalone ? 'View Package' : 'Manage Submission'}
|
||||||
</button>
|
</button>
|
||||||
${!isStandalone ? `
|
${!isStandalone ? `
|
||||||
|
|
@ -843,6 +844,41 @@ let currentSubmissionArticleId = null;
|
||||||
let currentSubmissionId = null;
|
let currentSubmissionId = null;
|
||||||
let currentArticleData = null;
|
let currentArticleData = null;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open modal for standalone submission package (no blog post)
|
||||||
|
*/
|
||||||
|
async function openStandaloneSubmissionModal(submissionId) {
|
||||||
|
const modal = document.getElementById('manage-submission-modal');
|
||||||
|
if (!modal) {
|
||||||
|
createEnhancedSubmissionModal();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Load submission data directly
|
||||||
|
const response = await apiCall(`/api/submissions/${submissionId}`);
|
||||||
|
if (!response.ok) throw new Error('Failed to load submission data');
|
||||||
|
|
||||||
|
const submissionResponse = await response.json();
|
||||||
|
currentSubmission = submissionResponse.data || submissionResponse;
|
||||||
|
|
||||||
|
// No article for standalone submissions
|
||||||
|
currentArticle = null;
|
||||||
|
|
||||||
|
// Update modal title
|
||||||
|
document.getElementById('modal-title').textContent = `Submission Package: ${currentSubmission.title}`;
|
||||||
|
|
||||||
|
// Show modal
|
||||||
|
document.getElementById('manage-submission-modal').classList.remove('hidden');
|
||||||
|
|
||||||
|
// Load overview tab
|
||||||
|
switchTab('overview');
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error loading standalone submission:', error);
|
||||||
|
alert('Failed to load submission package. Please try again.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize Manage Submission button handlers
|
* Initialize Manage Submission button handlers
|
||||||
*/
|
*/
|
||||||
|
|
@ -852,7 +888,15 @@ function initManageSubmissionHandlers() {
|
||||||
if (e.target.classList.contains('manage-submission')) {
|
if (e.target.classList.contains('manage-submission')) {
|
||||||
const articleId = e.target.dataset.articleId;
|
const articleId = e.target.dataset.articleId;
|
||||||
const submissionId = e.target.dataset.submissionId;
|
const submissionId = e.target.dataset.submissionId;
|
||||||
openManageSubmissionModal(articleId, submissionId || null);
|
const isStandalone = e.target.dataset.isStandalone === 'true';
|
||||||
|
|
||||||
|
if (isStandalone) {
|
||||||
|
// For standalone submissions, open with submission ID only
|
||||||
|
openStandaloneSubmissionModal(articleId);
|
||||||
|
} else {
|
||||||
|
// For blog-linked submissions, open with article ID
|
||||||
|
openManageSubmissionModal(articleId, submissionId || null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,11 @@ function renderOverviewTab() {
|
||||||
const submission = currentSubmission || {};
|
const submission = currentSubmission || {};
|
||||||
const article = currentArticle;
|
const article = currentArticle;
|
||||||
|
|
||||||
const wordCount = article.content ? article.content.split(/\s+/).length : 0;
|
// Handle standalone submissions (no article)
|
||||||
|
const isStandalone = !article;
|
||||||
|
const title = isStandalone ? submission.title : article.title;
|
||||||
|
const subtitle = isStandalone ? '' : (article.subtitle || '');
|
||||||
|
const wordCount = isStandalone ? (submission.wordCount || 0) : (article.content ? article.content.split(/\s+/).length : 0);
|
||||||
const publicationName = submission.publicationName || 'Not assigned';
|
const publicationName = submission.publicationName || 'Not assigned';
|
||||||
const status = submission.status || 'draft';
|
const status = submission.status || 'draft';
|
||||||
|
|
||||||
|
|
@ -235,26 +239,48 @@ function renderOverviewTab() {
|
||||||
if (submission.documents?.authorBio?.versions?.length > 0) completionScore += 25;
|
if (submission.documents?.authorBio?.versions?.length > 0) completionScore += 25;
|
||||||
if (submission.publicationId) completionScore += 25;
|
if (submission.publicationId) completionScore += 25;
|
||||||
|
|
||||||
const excerptText = article.excerpt || (article.content?.substring(0, 300) + '...') || 'No content available';
|
// Get content/excerpt - for standalone, use document content if available
|
||||||
const publishedDate = article.published_at ? new Date(article.published_at).toLocaleDateString() : 'N/A';
|
let excerptText = 'No content available';
|
||||||
|
if (isStandalone) {
|
||||||
|
const mainArticle = submission.documents?.mainArticle?.versions?.[0];
|
||||||
|
if (mainArticle?.content) {
|
||||||
|
excerptText = mainArticle.content.substring(0, 300) + '...';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
excerptText = article.excerpt || (article.content?.substring(0, 300) + '...') || 'No content available';
|
||||||
|
}
|
||||||
|
|
||||||
|
const publishedDate = isStandalone
|
||||||
|
? (submission.submittedAt ? new Date(submission.submittedAt).toLocaleDateString() : 'Not submitted')
|
||||||
|
: (article.published_at ? new Date(article.published_at).toLocaleDateString() : 'N/A');
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<div class="space-y-6">
|
<div class="space-y-6">
|
||||||
<!-- Article Preview -->
|
${isStandalone ? `
|
||||||
|
<!-- Standalone Submission Notice -->
|
||||||
|
<div class="bg-purple-50 border border-purple-200 rounded-lg p-4">
|
||||||
|
<div class="flex items-center gap-2">
|
||||||
|
<span class="text-purple-600 font-semibold">📦 Standalone Submission Package</span>
|
||||||
|
<span class="text-sm text-purple-600">This is a direct submission without an associated blog post</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
` : ''}
|
||||||
|
|
||||||
|
<!-- Article/Submission Preview -->
|
||||||
<div class="bg-gray-50 rounded-lg p-6">
|
<div class="bg-gray-50 rounded-lg p-6">
|
||||||
<h3 class="text-lg font-semibold text-gray-900 mb-4">Article Preview</h3>
|
<h3 class="text-lg font-semibold text-gray-900 mb-4">${isStandalone ? 'Submission' : 'Article'} Preview</h3>
|
||||||
<div class="prose max-w-none">
|
<div class="prose max-w-none">
|
||||||
<h4 class="text-xl font-bold mb-2">${escapeHtml(article.title)}</h4>
|
<h4 class="text-xl font-bold mb-2">${escapeHtml(title)}</h4>
|
||||||
<div class="text-sm text-gray-600 mb-4">
|
${subtitle ? `<div class="text-sm text-gray-600 mb-4">
|
||||||
${escapeHtml(article.subtitle || '')}
|
${escapeHtml(subtitle)}
|
||||||
</div>
|
</div>` : ''}
|
||||||
<div class="text-gray-700 line-clamp-6">
|
<div class="text-gray-700 line-clamp-6">
|
||||||
${escapeHtml(excerptText)}
|
${escapeHtml(excerptText)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="mt-4 flex items-center space-x-4 text-sm text-gray-600">
|
<div class="mt-4 flex items-center space-x-4 text-sm text-gray-600">
|
||||||
<span><strong>Word Count:</strong> ${wordCount.toLocaleString()}</span>
|
<span><strong>Word Count:</strong> ${wordCount.toLocaleString()}</span>
|
||||||
<span><strong>Published:</strong> ${publishedDate}</span>
|
<span><strong>${isStandalone ? 'Submitted' : 'Published'}:</strong> ${publishedDate}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue