refactor: PostDetail cards as status dashboard, panel for creation

Reverted inline asset creation — the copy workflow (original → approve →
translate → approve translations) needs the full panel, not a card form.

PostDetail cards now:
- "Create new" → creates asset (type pre-set, post linked) → opens panel
- "Open" → opens panel for editing/reviewing
- Card shows: title, status, preview, approval info (status dashboard)

Panel handles: write copy, add translations, upload files, select reviewer,
submit for review — the full workflow in its proper workspace.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
fahed
2026-03-16 15:10:40 +03:00
parent 49e1a796ed
commit eb23931ce0
5 changed files with 164 additions and 76 deletions
+22 -4
View File
@@ -56,11 +56,29 @@ async function getPostComposition(postId) {
video ? (video.thumbnail_url || getFirstAttachment(video.Id)) : null,
]);
// Resolve approver names for each piece
const resolveApprover = async (record) => {
if (!record || !record.approver_ids) return { approver_ids: null, approver_name: null };
const ids = record.approver_ids.split(',').map(s => s.trim()).filter(Boolean);
if (ids.length === 0) return { approver_ids: null, approver_name: null };
try {
const user = await nocodb.get('Users', Number(ids[0]));
return { approver_ids: record.approver_ids, approver_name: user ? (user.display_name || user.name || user.email) : null };
} catch { return { approver_ids: record.approver_ids, approver_name: null }; }
};
const [captionApprover, bodyApprover, designApprover, videoApprover] = await Promise.all([
resolveApprover(caption),
resolveApprover(bodyCopy),
resolveApprover(design),
resolveApprover(video),
]);
return {
caption: caption ? { id: caption.Id, title: caption.title, status: caption.status, language: caption.source_language, content_preview: (caption.source_content || '').slice(0, 120), languages: captionTexts } : null,
body_copy: bodyCopy ? { id: bodyCopy.Id, title: bodyCopy.title, status: bodyCopy.status, language: bodyCopy.source_language, content_preview: (bodyCopy.source_content || '').slice(0, 120), languages: bodyTexts } : null,
design: design ? { id: design.Id, title: design.title, status: design.status, thumbnail_url: designThumb, current_version: design.current_version } : null,
video: video ? { id: video.Id, title: video.title, status: video.status, thumbnail_url: videoThumb, current_version: video.current_version } : null,
caption: caption ? { id: caption.Id, title: caption.title, status: caption.status, language: caption.source_language, content_preview: (caption.source_content || '').slice(0, 120), languages: captionTexts, ...captionApprover } : null,
body_copy: bodyCopy ? { id: bodyCopy.Id, title: bodyCopy.title, status: bodyCopy.status, language: bodyCopy.source_language, content_preview: (bodyCopy.source_content || '').slice(0, 120), languages: bodyTexts, ...bodyApprover } : null,
design: design ? { id: design.Id, title: design.title, status: design.status, thumbnail_url: designThumb, current_version: design.current_version, ...designApprover } : null,
video: video ? { id: video.Id, title: video.title, status: video.status, thumbnail_url: videoThumb, current_version: video.current_version, ...videoApprover } : null,
platforms,
pieces_ready: piecesReady,
waiting_on: waitingOn,