Add bulk update functionality for image status
- Introduced a new endpoint in the backend to handle bulk updates of image statuses by content ID or image IDs. - Updated the frontend to include a new row action for updating image status and integrated a modal for status confirmation. - Enhanced the API service to support bulk status updates and updated the images page to manage status updates effectively.
This commit is contained in:
@@ -11,11 +11,13 @@ import {
|
||||
ContentImagesResponse,
|
||||
fetchImageGenerationSettings,
|
||||
generateImages,
|
||||
bulkUpdateImagesStatus,
|
||||
} from '../../services/api';
|
||||
import { useToast } from '../../components/ui/toast/ToastContainer';
|
||||
import { FileIcon, DownloadIcon, BoltIcon } from '../../icons';
|
||||
import { createImagesPageConfig } from '../../config/pages/images.config';
|
||||
import ImageQueueModal, { ImageQueueItem } from '../../components/common/ImageQueueModal';
|
||||
import SingleRecordStatusUpdateModal from '../../components/common/SingleRecordStatusUpdateModal';
|
||||
import { useResourceDebug } from '../../hooks/useResourceDebug';
|
||||
|
||||
export default function Images() {
|
||||
@@ -76,6 +78,12 @@ export default function Images() {
|
||||
const [imageModel, setImageModel] = useState<string | null>(null);
|
||||
const [imageProvider, setImageProvider] = useState<string | null>(null);
|
||||
|
||||
// Status update modal state
|
||||
const [isStatusModalOpen, setIsStatusModalOpen] = useState(false);
|
||||
const [statusUpdateContentId, setStatusUpdateContentId] = useState<number | null>(null);
|
||||
const [statusUpdateRecordName, setStatusUpdateRecordName] = useState<string>('');
|
||||
const [isUpdatingStatus, setIsUpdatingStatus] = useState(false);
|
||||
|
||||
// Load images - wrapped in useCallback
|
||||
const loadImages = useCallback(async () => {
|
||||
setLoading(true);
|
||||
@@ -175,6 +183,35 @@ export default function Images() {
|
||||
toast.info(`Bulk action "${action}" for ${ids.length} items`);
|
||||
}, [toast]);
|
||||
|
||||
// Row action handler
|
||||
const handleRowAction = useCallback(async (action: string, row: ContentImagesGroup) => {
|
||||
if (action === 'update_status') {
|
||||
setStatusUpdateContentId(row.content_id);
|
||||
setStatusUpdateRecordName(row.content_title || `Content #${row.content_id}`);
|
||||
setIsStatusModalOpen(true);
|
||||
}
|
||||
}, []);
|
||||
|
||||
// Handle status update confirmation
|
||||
const handleStatusUpdate = useCallback(async (status: string) => {
|
||||
if (!statusUpdateContentId) return;
|
||||
|
||||
setIsUpdatingStatus(true);
|
||||
try {
|
||||
const result = await bulkUpdateImagesStatus(statusUpdateContentId, status);
|
||||
toast.success(`Successfully updated ${result.updated_count} image(s) status to ${status}`);
|
||||
setIsStatusModalOpen(false);
|
||||
setStatusUpdateContentId(null);
|
||||
setStatusUpdateRecordName('');
|
||||
// Reload images to reflect the changes
|
||||
loadImages();
|
||||
} catch (error: any) {
|
||||
toast.error(`Failed to update status: ${error.message}`);
|
||||
} finally {
|
||||
setIsUpdatingStatus(false);
|
||||
}
|
||||
}, [statusUpdateContentId, toast, loadImages]);
|
||||
|
||||
// Build image queue structure
|
||||
const buildImageQueue = useCallback((contentId: number, maxInArticleImages: number) => {
|
||||
const contentImages = images.find(g => g.content_id === contentId);
|
||||
@@ -396,6 +433,7 @@ export default function Images() {
|
||||
setStatusFilter('');
|
||||
setCurrentPage(1);
|
||||
}}
|
||||
onRowAction={handleRowAction}
|
||||
/>
|
||||
<ImageQueueModal
|
||||
isOpen={isQueueModalOpen}
|
||||
@@ -418,6 +456,25 @@ export default function Images() {
|
||||
onLog={addAiLog}
|
||||
/>
|
||||
|
||||
{/* Status Update Modal */}
|
||||
<SingleRecordStatusUpdateModal
|
||||
isOpen={isStatusModalOpen}
|
||||
onClose={() => {
|
||||
setIsStatusModalOpen(false);
|
||||
setStatusUpdateContentId(null);
|
||||
setStatusUpdateRecordName('');
|
||||
}}
|
||||
onConfirm={handleStatusUpdate}
|
||||
title="Update Image Status"
|
||||
recordName={statusUpdateRecordName}
|
||||
statusOptions={[
|
||||
{ value: 'pending', label: 'Pending' },
|
||||
{ value: 'generated', label: 'Generated' },
|
||||
{ value: 'failed', label: 'Failed' },
|
||||
]}
|
||||
isLoading={isUpdatingStatus}
|
||||
/>
|
||||
|
||||
{/* AI Function Logs - Display below table (only when Resource Debug is enabled) */}
|
||||
{resourceDebugEnabled && aiLogs.length > 0 && (
|
||||
<div className="mt-6 bg-gray-50 dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-4">
|
||||
|
||||
Reference in New Issue
Block a user