Implement "import history" in import page
This commit is contained in:
@ -15,10 +15,6 @@
|
||||
<p class="text-sm text-muted-foreground">
|
||||
{{ trackCount }} track(s)
|
||||
</p>
|
||||
<Dot />
|
||||
<p class="text-sm text-muted-foreground">
|
||||
{{ type }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-row items-center gap-2" v-if="hasProgress">
|
||||
<p class="text-sm text-muted-foreground">
|
||||
@ -56,7 +52,7 @@
|
||||
</DropdownMenu>
|
||||
</div>
|
||||
|
||||
<Dialog :open="isDialogOpen">
|
||||
<Dialog :open="isDialogOpen" @update:open="toggleDialog">
|
||||
<DialogContent class="max-w-3xl">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Playlist Upload Details</DialogTitle>
|
||||
@ -84,25 +80,19 @@
|
||||
<Label>Track Count</Label>
|
||||
<p class="text-sm">{{ trackCount }} tracks</p>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<Label>Type</Label>
|
||||
<p class="text-sm">{{ type }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="playlistProgressData?.ytdlnStdout" class="space-y-4">
|
||||
<div v-if="ytdlnStdout" class="space-y-4">
|
||||
<div class="flex justify-between items-center">
|
||||
<h3 class="text-lg font-semibold">yt-dlp Output</h3>
|
||||
<Button variant="outline" size="sm"
|
||||
@click="copyToClipboard(playlistProgressData.ytdlnStdout)">
|
||||
<Button variant="outline" size="sm" @click="copyToClipboard(ytdlnStdout)">
|
||||
<Copy class="mr-2 h-4 w-4" />
|
||||
Copy
|
||||
</Button>
|
||||
</div>
|
||||
<div class="bg-muted rounded-md p-4">
|
||||
<pre class="text-xs whitespace-pre-wrap overflow-x-auto max-h-60">{{
|
||||
playlistProgressData.ytdlnStdout }}</pre>
|
||||
<pre class="text-xs whitespace-pre-wrap overflow-x-auto max-h-60">{{ ytdlnStdout }}</pre>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -130,7 +120,6 @@
|
||||
import {
|
||||
CassetteTape,
|
||||
Copy,
|
||||
Dot,
|
||||
EllipsisVertical,
|
||||
Eye,
|
||||
FileQuestionMark,
|
||||
@ -139,22 +128,15 @@ import {
|
||||
Trash2
|
||||
} from 'lucide-vue-next';
|
||||
import { ref } from 'vue';
|
||||
import type { PlaylistProgressAllOfStatus } from '~/composeables/api/models';
|
||||
|
||||
interface Props {
|
||||
title: string
|
||||
trackCount?: number
|
||||
type?: string
|
||||
ytdlnStdout: string
|
||||
status: PlaylistProgressAllOfStatus
|
||||
progress?: number
|
||||
error?: string
|
||||
playlistProgressData?: {
|
||||
playlistId: number
|
||||
trackSourceId: number
|
||||
userId: number
|
||||
timestamp: number
|
||||
ytdlnStdout: string
|
||||
overallProgress: number
|
||||
status: 'LOADING' | 'FINISHED'
|
||||
}
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
@ -167,36 +149,34 @@ const emit = defineEmits<{
|
||||
|
||||
const isDialogOpen = ref(false);
|
||||
|
||||
const hasLoaded = props.trackCount && props.type;
|
||||
const hasLoaded = props.trackCount;
|
||||
const hasProgress = props.progress !== undefined && props.progress > 0;
|
||||
const hasError = props.error;
|
||||
|
||||
const openDialog = () => {
|
||||
isDialogOpen.value = true;
|
||||
console.log(isDialogOpen.value)
|
||||
};
|
||||
|
||||
const toggleDialog = (value: boolean) => {
|
||||
isDialogOpen.value = value;
|
||||
}
|
||||
|
||||
const getStatusColor = () => {
|
||||
if (hasError) return 'bg-destructive';
|
||||
if (props.playlistProgressData?.status === 'FINISHED') return 'bg-green-500';
|
||||
if (props.playlistProgressData?.status === 'LOADING') return 'bg-blue-500';
|
||||
if (props.status === 'FINISHED') return 'bg-green-500';
|
||||
if (props.status === 'LOADING') return 'bg-blue-500';
|
||||
if (hasProgress) return 'bg-amber-500';
|
||||
return 'bg-gray-500';
|
||||
};
|
||||
|
||||
const getStatusText = () => {
|
||||
if (hasError) return 'Error';
|
||||
if (props.playlistProgressData?.status === 'FINISHED') return 'Completed';
|
||||
if (props.playlistProgressData?.status === 'LOADING') return 'Loading';
|
||||
if (props.status === 'FINISHED') return 'Completed';
|
||||
if (props.status === 'LOADING') return 'Loading';
|
||||
if (hasProgress) return 'In Progress';
|
||||
return 'Pending';
|
||||
};
|
||||
|
||||
const formatTimestamp = (timestamp?: number) => {
|
||||
if (!timestamp) return 'N/A';
|
||||
return new Date(timestamp).toLocaleString();
|
||||
};
|
||||
|
||||
const copyToClipboard = async (text: string) => {
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
|
||||
@ -19,10 +19,6 @@
|
||||
<p class="text-sm text-muted-foreground">
|
||||
{{ format }}
|
||||
</p>
|
||||
<Dot />
|
||||
<p class="text-sm text-muted-foreground">
|
||||
{{ type }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex flex-row items-center gap-2" v-if="hasProgress">
|
||||
<p class="text-sm text-muted-foreground">
|
||||
@ -85,10 +81,6 @@
|
||||
<Label>Size</Label>
|
||||
<p class="text-sm">{{ size }}</p>
|
||||
</div>
|
||||
<div class="space-y-2">
|
||||
<Label>Type</Label>
|
||||
<p class="text-sm">{{ type }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -194,7 +186,6 @@ interface Props {
|
||||
title: string
|
||||
size?: string
|
||||
format?: string
|
||||
type?: string
|
||||
progress?: number
|
||||
error?: string
|
||||
trackProgressData?: {
|
||||
@ -219,7 +210,7 @@ const emit = defineEmits<{
|
||||
|
||||
const isDialogOpen = ref(false);
|
||||
|
||||
const hasLoaded = props.size && props.format && props.type;
|
||||
const hasLoaded = props.size && props.format;
|
||||
const hasProgress = props.progress !== undefined && props.progress > 0;
|
||||
const hasError = props.error;
|
||||
|
||||
|
||||
27
app/components/internal/import/uploadentry/UploadEntry.vue
Normal file
27
app/components/internal/import/uploadentry/UploadEntry.vue
Normal file
@ -0,0 +1,27 @@
|
||||
<template>
|
||||
<SingleUploadEntry v-if="entry.type === 'TRACK'" :title="(entry as SingleTrackProgressAllOf).title || ''" :size="''"
|
||||
:format="(entry as SingleTrackProgressAllOf).format || ''" />
|
||||
<PlaylistUploadEntry v-if="entry.type === 'PLAYLIST'" title=""
|
||||
:trackCount="(entry as PlaylistProgressAllOf).trackCount"
|
||||
:ytdlnStdout="(entry as PlaylistProgressAllOf).ytdlnStdout || ''"
|
||||
:status="(entry as PlaylistProgressAllOf).status || 'LOADING'" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { PlaylistProgressAllOf, PlaylistProgressAllOfStatus, SingleTrackProgressAllOf, StreamProgress200Item } from '~/composeables/api/models';
|
||||
import SingleUploadEntry from './SingleUploadEntry.vue';
|
||||
import PlaylistUploadEntry from './PlaylistUploadEntry.vue';
|
||||
|
||||
interface Props {
|
||||
entry: StreamProgress200Item
|
||||
}
|
||||
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
retry: []
|
||||
download: []
|
||||
play: []
|
||||
}>();
|
||||
</script>
|
||||
@ -1,6 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { FileMusicIcon } from 'lucide-vue-next';
|
||||
import PlaylistCreateDialog from './PlaylistCreateDialog.vue';
|
||||
import Empty from '@/components/ui/empty/Empty.vue';
|
||||
import EmptyHeader from '@/components/ui/empty/EmptyHeader.vue';
|
||||
import EmptyMedia from '@/components/ui/empty/EmptyMedia.vue';
|
||||
import EmptyTitle from '@/components/ui/empty/EmptyTitle.vue';
|
||||
import EmptyDescription from '@/components/ui/empty/EmptyDescription.vue';
|
||||
import EmptyContent from '@/components/ui/empty/EmptyContent.vue';
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user