|
@@ -8,6 +8,7 @@ import { api } from '../api/client';
|
|
|
import { Card, CardContent, CardHeader } from './Card';
|
|
import { Card, CardContent, CardHeader } from './Card';
|
|
|
import { Button } from './Button';
|
|
import { Button } from './Button';
|
|
|
import { useToast } from '../contexts/ToastContext';
|
|
import { useToast } from '../contexts/ToastContext';
|
|
|
|
|
+import { useAuth } from '../contexts/AuthContext';
|
|
|
import { ConfirmModal } from './ConfirmModal';
|
|
import { ConfirmModal } from './ConfirmModal';
|
|
|
import { formatFileSize } from '../utils/file';
|
|
import { formatFileSize } from '../utils/file';
|
|
|
import { assignableProjects } from '../utils/projectTree';
|
|
import { assignableProjects } from '../utils/projectTree';
|
|
@@ -20,6 +21,7 @@ interface PendingUploadItemProps {
|
|
|
onDiscard: (id: number) => void;
|
|
onDiscard: (id: number) => void;
|
|
|
isArchiving: boolean;
|
|
isArchiving: boolean;
|
|
|
isDiscarding: boolean;
|
|
isDiscarding: boolean;
|
|
|
|
|
+ canApprove: boolean;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function PendingUploadItem({
|
|
function PendingUploadItem({
|
|
@@ -29,6 +31,7 @@ function PendingUploadItem({
|
|
|
onDiscard,
|
|
onDiscard,
|
|
|
isArchiving,
|
|
isArchiving,
|
|
|
isDiscarding,
|
|
isDiscarding,
|
|
|
|
|
+ canApprove,
|
|
|
}: PendingUploadItemProps) {
|
|
}: PendingUploadItemProps) {
|
|
|
const { t } = useTranslation();
|
|
const { t } = useTranslation();
|
|
|
const [expanded, setExpanded] = useState(false);
|
|
const [expanded, setExpanded] = useState(false);
|
|
@@ -73,7 +76,8 @@ function PendingUploadItem({
|
|
|
variant="primary"
|
|
variant="primary"
|
|
|
size="sm"
|
|
size="sm"
|
|
|
onClick={() => onArchive(upload.id, { tags, notes, project_id: projectId || undefined })}
|
|
onClick={() => onArchive(upload.id, { tags, notes, project_id: projectId || undefined })}
|
|
|
- disabled={isArchiving}
|
|
|
|
|
|
|
+ disabled={isArchiving || !canApprove}
|
|
|
|
|
+ title={canApprove ? undefined : t('pendingUploads.noApprovePermission')}
|
|
|
>
|
|
>
|
|
|
{isArchiving ? (
|
|
{isArchiving ? (
|
|
|
<Loader2 className="w-4 h-4 animate-spin" />
|
|
<Loader2 className="w-4 h-4 animate-spin" />
|
|
@@ -163,6 +167,9 @@ function PendingUploadItem({
|
|
|
export function PendingUploadsPanel() {
|
|
export function PendingUploadsPanel() {
|
|
|
const { t } = useTranslation();
|
|
const { t } = useTranslation();
|
|
|
const queryClient = useQueryClient();
|
|
const queryClient = useQueryClient();
|
|
|
|
|
+ // Approving adds a File Manager file, so it needs both (the backend checks).
|
|
|
|
|
+ const { hasPermission } = useAuth();
|
|
|
|
|
+ const canApprove = hasPermission('queue:create') && hasPermission('library:upload');
|
|
|
const { showToast } = useToast();
|
|
const { showToast } = useToast();
|
|
|
const [showArchiveAllConfirm, setShowArchiveAllConfirm] = useState(false);
|
|
const [showArchiveAllConfirm, setShowArchiveAllConfirm] = useState(false);
|
|
|
const [showDiscardAllConfirm, setShowDiscardAllConfirm] = useState(false);
|
|
const [showDiscardAllConfirm, setShowDiscardAllConfirm] = useState(false);
|
|
@@ -292,7 +299,8 @@ export function PendingUploadsPanel() {
|
|
|
variant="primary"
|
|
variant="primary"
|
|
|
size="sm"
|
|
size="sm"
|
|
|
onClick={() => setShowArchiveAllConfirm(true)}
|
|
onClick={() => setShowArchiveAllConfirm(true)}
|
|
|
- disabled={archiveAllMutation.isPending}
|
|
|
|
|
|
|
+ disabled={archiveAllMutation.isPending || !canApprove}
|
|
|
|
|
+ title={canApprove ? undefined : t('pendingUploads.noApprovePermission')}
|
|
|
>
|
|
>
|
|
|
{archiveAllMutation.isPending ? (
|
|
{archiveAllMutation.isPending ? (
|
|
|
<Loader2 className="w-4 h-4 animate-spin" />
|
|
<Loader2 className="w-4 h-4 animate-spin" />
|
|
@@ -335,6 +343,7 @@ export function PendingUploadsPanel() {
|
|
|
onDiscard={(id) => discardMutation.mutate(id)}
|
|
onDiscard={(id) => discardMutation.mutate(id)}
|
|
|
isArchiving={archivingIds.has(upload.id)}
|
|
isArchiving={archivingIds.has(upload.id)}
|
|
|
isDiscarding={discardingIds.has(upload.id)}
|
|
isDiscarding={discardingIds.has(upload.id)}
|
|
|
|
|
+ canApprove={canApprove}
|
|
|
/>
|
|
/>
|
|
|
))}
|
|
))}
|
|
|
</div>
|
|
</div>
|