nuxt-media-library 0.0.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +243 -0
- package/dist/module.d.mts +31 -0
- package/dist/module.d.ts +31 -0
- package/dist/module.json +9 -0
- package/dist/module.mjs +118 -0
- package/dist/runtime/components/MLAssetManager/AssetActivity.d.vue.ts +6 -0
- package/dist/runtime/components/MLAssetManager/AssetActivity.vue +13 -0
- package/dist/runtime/components/MLAssetManager/AssetActivity.vue.d.ts +6 -0
- package/dist/runtime/components/MLAssetManager/AssetCard.d.vue.ts +14 -0
- package/dist/runtime/components/MLAssetManager/AssetCard.vue +100 -0
- package/dist/runtime/components/MLAssetManager/AssetCard.vue.d.ts +14 -0
- package/dist/runtime/components/MLAssetManager/AssetDetail.d.vue.ts +14 -0
- package/dist/runtime/components/MLAssetManager/AssetDetail.vue +156 -0
- package/dist/runtime/components/MLAssetManager/AssetDetail.vue.d.ts +14 -0
- package/dist/runtime/components/MLAssetManager/AssetList.d.vue.ts +15 -0
- package/dist/runtime/components/MLAssetManager/AssetList.vue +41 -0
- package/dist/runtime/components/MLAssetManager/AssetList.vue.d.ts +15 -0
- package/dist/runtime/components/MLAssetManager/AssetOverview.d.vue.ts +8 -0
- package/dist/runtime/components/MLAssetManager/AssetOverview.vue +321 -0
- package/dist/runtime/components/MLAssetManager/AssetOverview.vue.d.ts +8 -0
- package/dist/runtime/components/MLAssetManager/AssetPreview.d.vue.ts +10 -0
- package/dist/runtime/components/MLAssetManager/AssetPreview.vue +18 -0
- package/dist/runtime/components/MLAssetManager/AssetPreview.vue.d.ts +10 -0
- package/dist/runtime/components/MLAssetManager/AssetPreviewAudio.d.vue.ts +9 -0
- package/dist/runtime/components/MLAssetManager/AssetPreviewAudio.vue +21 -0
- package/dist/runtime/components/MLAssetManager/AssetPreviewAudio.vue.d.ts +9 -0
- package/dist/runtime/components/MLAssetManager/AssetPreviewDocument.d.vue.ts +9 -0
- package/dist/runtime/components/MLAssetManager/AssetPreviewDocument.vue +39 -0
- package/dist/runtime/components/MLAssetManager/AssetPreviewDocument.vue.d.ts +9 -0
- package/dist/runtime/components/MLAssetManager/AssetPreviewFallback.d.vue.ts +7 -0
- package/dist/runtime/components/MLAssetManager/AssetPreviewFallback.vue +41 -0
- package/dist/runtime/components/MLAssetManager/AssetPreviewFallback.vue.d.ts +7 -0
- package/dist/runtime/components/MLAssetManager/AssetPreviewImage.d.vue.ts +9 -0
- package/dist/runtime/components/MLAssetManager/AssetPreviewImage.vue +30 -0
- package/dist/runtime/components/MLAssetManager/AssetPreviewImage.vue.d.ts +9 -0
- package/dist/runtime/components/MLAssetManager/AssetPreviewSidebar.d.vue.ts +15 -0
- package/dist/runtime/components/MLAssetManager/AssetPreviewSidebar.vue +69 -0
- package/dist/runtime/components/MLAssetManager/AssetPreviewSidebar.vue.d.ts +15 -0
- package/dist/runtime/components/MLAssetManager/AssetPreviewVideo.d.vue.ts +9 -0
- package/dist/runtime/components/MLAssetManager/AssetPreviewVideo.vue +148 -0
- package/dist/runtime/components/MLAssetManager/AssetPreviewVideo.vue.d.ts +9 -0
- package/dist/runtime/components/MLAssetManager/AssetRenditions.d.vue.ts +8 -0
- package/dist/runtime/components/MLAssetManager/AssetRenditions.vue +148 -0
- package/dist/runtime/components/MLAssetManager/AssetRenditions.vue.d.ts +8 -0
- package/dist/runtime/components/MLAssetManager/Processing.d.vue.ts +8 -0
- package/dist/runtime/components/MLAssetManager/Processing.vue +84 -0
- package/dist/runtime/components/MLAssetManager/Processing.vue.d.ts +8 -0
- package/dist/runtime/components/MLAssetManager/SlotCard.d.vue.ts +17 -0
- package/dist/runtime/components/MLAssetManager/SlotCard.vue +94 -0
- package/dist/runtime/components/MLAssetManager/SlotCard.vue.d.ts +17 -0
- package/dist/runtime/components/MLAssetManager/Widget.d.vue.ts +14 -0
- package/dist/runtime/components/MLAssetManager/Widget.vue +328 -0
- package/dist/runtime/components/MLAssetManager/Widget.vue.d.ts +14 -0
- package/dist/runtime/components/MLPreviewProvider.d.vue.ts +31 -0
- package/dist/runtime/components/MLPreviewProvider.vue +51 -0
- package/dist/runtime/components/MLPreviewProvider.vue.d.ts +31 -0
- package/dist/runtime/components/MLProcessing/Forms/ConfigureStepModal.d.vue.ts +13 -0
- package/dist/runtime/components/MLProcessing/Forms/ConfigureStepModal.vue +47 -0
- package/dist/runtime/components/MLProcessing/Forms/ConfigureStepModal.vue.d.ts +13 -0
- package/dist/runtime/components/MLProcessing/Forms/FramePicker.d.vue.ts +11 -0
- package/dist/runtime/components/MLProcessing/Forms/FramePicker.vue +162 -0
- package/dist/runtime/components/MLProcessing/Forms/FramePicker.vue.d.ts +11 -0
- package/dist/runtime/components/MLProcessing/Forms/StepOptionsForm.d.vue.ts +14 -0
- package/dist/runtime/components/MLProcessing/Forms/StepOptionsForm.vue +113 -0
- package/dist/runtime/components/MLProcessing/Forms/StepOptionsForm.vue.d.ts +14 -0
- package/dist/runtime/components/MLProcessing/Pipeline.d.vue.ts +15 -0
- package/dist/runtime/components/MLProcessing/Pipeline.vue +178 -0
- package/dist/runtime/components/MLProcessing/Pipeline.vue.d.ts +15 -0
- package/dist/runtime/components/MLProcessing/PipelineStepItem.d.vue.ts +20 -0
- package/dist/runtime/components/MLProcessing/PipelineStepItem.vue +309 -0
- package/dist/runtime/components/MLProcessing/PipelineStepItem.vue.d.ts +20 -0
- package/dist/runtime/components/MLProcessing/ProgressBar.d.vue.ts +9 -0
- package/dist/runtime/components/MLProcessing/ProgressBar.vue +27 -0
- package/dist/runtime/components/MLProcessing/ProgressBar.vue.d.ts +9 -0
- package/dist/runtime/components/MLProcessing/StepLayout.d.vue.ts +31 -0
- package/dist/runtime/components/MLProcessing/StepLayout.vue +36 -0
- package/dist/runtime/components/MLProcessing/StepLayout.vue.d.ts +31 -0
- package/dist/runtime/components/MLProcessing/Stepper.d.vue.ts +16 -0
- package/dist/runtime/components/MLProcessing/Stepper.vue +87 -0
- package/dist/runtime/components/MLProcessing/Stepper.vue.d.ts +16 -0
- package/dist/runtime/components/MLProcessing/StepperItem.d.vue.ts +16 -0
- package/dist/runtime/components/MLProcessing/StepperItem.vue +150 -0
- package/dist/runtime/components/MLProcessing/StepperItem.vue.d.ts +16 -0
- package/dist/runtime/components/MLProcessing/TopBar.d.vue.ts +21 -0
- package/dist/runtime/components/MLProcessing/TopBar.vue +46 -0
- package/dist/runtime/components/MLProcessing/TopBar.vue.d.ts +21 -0
- package/dist/runtime/components/MLUploader/ButtonUploader.d.vue.ts +55 -0
- package/dist/runtime/components/MLUploader/ButtonUploader.vue +211 -0
- package/dist/runtime/components/MLUploader/ButtonUploader.vue.d.ts +55 -0
- package/dist/runtime/components/MLUploader/Item.d.vue.ts +34 -0
- package/dist/runtime/components/MLUploader/Item.vue +242 -0
- package/dist/runtime/components/MLUploader/Item.vue.d.ts +34 -0
- package/dist/runtime/components/MLUploader/PolicyPopover.d.vue.ts +7 -0
- package/dist/runtime/components/MLUploader/PolicyPopover.vue +160 -0
- package/dist/runtime/components/MLUploader/PolicyPopover.vue.d.ts +7 -0
- package/dist/runtime/components/MLUploader/Widget.d.vue.ts +44 -0
- package/dist/runtime/components/MLUploader/Widget.vue +251 -0
- package/dist/runtime/components/MLUploader/Widget.vue.d.ts +44 -0
- package/dist/runtime/composables/resourcePolicy/mimeUtils.d.ts +4 -0
- package/dist/runtime/composables/resourcePolicy/mimeUtils.js +71 -0
- package/dist/runtime/composables/resourcePolicy/useMLResourcePolicy.d.ts +17 -0
- package/dist/runtime/composables/resourcePolicy/useMLResourcePolicy.js +150 -0
- package/dist/runtime/composables/useElapsedTimer.d.ts +13 -0
- package/dist/runtime/composables/useElapsedTimer.js +46 -0
- package/dist/runtime/composables/useMLAssetLibrary.d.ts +31 -0
- package/dist/runtime/composables/useMLAssetLibrary.js +53 -0
- package/dist/runtime/composables/useMLAssetManager.d.ts +30 -0
- package/dist/runtime/composables/useMLAssetManager.js +229 -0
- package/dist/runtime/composables/useMLAssetManagerPreview.d.ts +28 -0
- package/dist/runtime/composables/useMLAssetManagerPreview.js +232 -0
- package/dist/runtime/composables/useMLAssetPreview.d.ts +23 -0
- package/dist/runtime/composables/useMLAssetPreview.js +153 -0
- package/dist/runtime/composables/useMLChunkUploader.d.ts +9 -0
- package/dist/runtime/composables/useMLChunkUploader.js +22 -0
- package/dist/runtime/composables/useMLProcessingPipeline.d.ts +38 -0
- package/dist/runtime/composables/useMLProcessingPipeline.js +258 -0
- package/dist/runtime/composables/useMLProcessingStatus.d.ts +34 -0
- package/dist/runtime/composables/useMLProcessingStatus.js +100 -0
- package/dist/runtime/composables/useMLProcessingStepper.d.ts +32 -0
- package/dist/runtime/composables/useMLProcessingStepper.js +280 -0
- package/dist/runtime/composables/useMLProcessingStrategies.d.ts +7 -0
- package/dist/runtime/composables/useMLProcessingStrategies.js +47 -0
- package/dist/runtime/composables/useMLRepeater.d.ts +5 -0
- package/dist/runtime/composables/useMLRepeater.js +11 -0
- package/dist/runtime/css/index.css +1 -0
- package/dist/runtime/index.d.ts +13 -0
- package/dist/runtime/index.js +13 -0
- package/dist/runtime/plugins/asset-direcetive-client.d.ts +2 -0
- package/dist/runtime/plugins/asset-direcetive-client.js +64 -0
- package/dist/runtime/plugins/config.d.ts +13 -0
- package/dist/runtime/plugins/config.js +23 -0
- package/dist/runtime/schemas/resource-policy.schema.d.ts +607 -0
- package/dist/runtime/schemas/resource-policy.schema.js +117 -0
- package/dist/runtime/server/assets-proxy.d.ts +2 -0
- package/dist/runtime/server/assets-proxy.js +81 -0
- package/dist/runtime/server/create-ml-proxy.d.ts +47 -0
- package/dist/runtime/server/create-ml-proxy.js +232 -0
- package/dist/runtime/server/delivery-proxy.d.ts +2 -0
- package/dist/runtime/server/delivery-proxy.js +74 -0
- package/dist/runtime/server/index.d.ts +2 -0
- package/dist/runtime/server/index.js +1 -0
- package/dist/runtime/server/processing-proxy.d.ts +2 -0
- package/dist/runtime/server/processing-proxy.js +55 -0
- package/dist/runtime/server/resource-policy-proxy.d.ts +2 -0
- package/dist/runtime/server/resource-policy-proxy.js +80 -0
- package/dist/runtime/server/tsconfig.json +0 -0
- package/dist/runtime/server/uploads-proxy.d.ts +2 -0
- package/dist/runtime/server/uploads-proxy.js +99 -0
- package/dist/runtime/types/asset.d.ts +174 -0
- package/dist/runtime/types/asset.js +7 -0
- package/dist/runtime/types/preview.d.ts +20 -0
- package/dist/runtime/types/preview.js +0 -0
- package/dist/runtime/types/resourcePolicy.d.ts +77 -0
- package/dist/runtime/types/resourcePolicy.js +25 -0
- package/dist/runtime/types/uploader.d.ts +71 -0
- package/dist/runtime/types/uploader.js +0 -0
- package/dist/runtime/utils/uploader/checksum.d.ts +21 -0
- package/dist/runtime/utils/uploader/checksum.js +23 -0
- package/dist/runtime/utils/uploader/chunking.d.ts +8 -0
- package/dist/runtime/utils/uploader/chunking.js +21 -0
- package/dist/runtime/utils/uploader/uploader.d.ts +20 -0
- package/dist/runtime/utils/uploader/uploader.js +206 -0
- package/dist/types.d.mts +11 -0
- package/package.json +81 -0
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
assetId?: string | null;
|
|
3
|
+
fallbackSrc?: string | null;
|
|
4
|
+
autoRegister?: boolean;
|
|
5
|
+
};
|
|
6
|
+
declare var __VLS_1: {
|
|
7
|
+
asset: import("../types/preview.js").AssetPreview | undefined;
|
|
8
|
+
src: string | null;
|
|
9
|
+
broken: boolean;
|
|
10
|
+
forbidden: boolean;
|
|
11
|
+
loading: boolean;
|
|
12
|
+
renditions: import("..").DeliveryRendition[];
|
|
13
|
+
sources: import("../types/preview.js").AssetSource[];
|
|
14
|
+
thumbnailUrl: string | null;
|
|
15
|
+
status: string | null;
|
|
16
|
+
refresh: () => Promise<void>;
|
|
17
|
+
};
|
|
18
|
+
type __VLS_Slots = {} & {
|
|
19
|
+
default?: (props: typeof __VLS_1) => any;
|
|
20
|
+
};
|
|
21
|
+
declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
|
|
22
|
+
autoRegister: boolean;
|
|
23
|
+
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
24
|
+
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
|
|
25
|
+
declare const _default: typeof __VLS_export;
|
|
26
|
+
export default _default;
|
|
27
|
+
type __VLS_WithSlots<T, S> = T & {
|
|
28
|
+
new (): {
|
|
29
|
+
$slots: S;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { PipelineOptionSchema } from "../../../types/asset.js";
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
taskType: string;
|
|
4
|
+
schema: Record<string, PipelineOptionSchema>;
|
|
5
|
+
downloadUrl?: string | null;
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
8
|
+
close: (result?: Record<string, any> | undefined) => any;
|
|
9
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
10
|
+
onClose?: ((result?: Record<string, any> | undefined) => any) | undefined;
|
|
11
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
|
+
declare const _default: typeof __VLS_export;
|
|
13
|
+
export default _default;
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { ref } from "vue";
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
taskType: { type: String, required: true },
|
|
5
|
+
schema: { type: Object, required: true },
|
|
6
|
+
downloadUrl: { type: [String, null], required: false }
|
|
7
|
+
});
|
|
8
|
+
const emit = defineEmits(["close"]);
|
|
9
|
+
const title = props.taskType.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
10
|
+
const initialOptions = {};
|
|
11
|
+
for (const [key, opt] of Object.entries(props.schema)) {
|
|
12
|
+
if (opt.default !== void 0) initialOptions[key] = opt.default;
|
|
13
|
+
}
|
|
14
|
+
const options = ref(initialOptions);
|
|
15
|
+
function submit() {
|
|
16
|
+
emit("close", options.value);
|
|
17
|
+
}
|
|
18
|
+
</script>
|
|
19
|
+
|
|
20
|
+
<template>
|
|
21
|
+
<UModal :title="`Configure ${title}`" @update:open="(v) => !v && emit('close')">
|
|
22
|
+
<template #body>
|
|
23
|
+
<MLProcessingFormsFramePicker
|
|
24
|
+
v-if="taskType === 'video_thumbnail'"
|
|
25
|
+
:download-url="downloadUrl ?? null"
|
|
26
|
+
v-model="options"
|
|
27
|
+
/>
|
|
28
|
+
|
|
29
|
+
<MLProcessingFormsStepOptionsForm
|
|
30
|
+
v-else-if="Object.keys(schema).length"
|
|
31
|
+
:schema="schema"
|
|
32
|
+
v-model="options"
|
|
33
|
+
/>
|
|
34
|
+
|
|
35
|
+
<div v-else class="text-sm text-muted">
|
|
36
|
+
No configurable options for this step.
|
|
37
|
+
</div>
|
|
38
|
+
</template>
|
|
39
|
+
|
|
40
|
+
<template #footer>
|
|
41
|
+
<div class="flex justify-end gap-2">
|
|
42
|
+
<UButton variant="outline" color="neutral" label="Cancel" @click="emit('close')" />
|
|
43
|
+
<UButton color="primary" label="Apply & Start" @click="submit" />
|
|
44
|
+
</div>
|
|
45
|
+
</template>
|
|
46
|
+
</UModal>
|
|
47
|
+
</template>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { PipelineOptionSchema } from "../../../types/asset.js";
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
taskType: string;
|
|
4
|
+
schema: Record<string, PipelineOptionSchema>;
|
|
5
|
+
downloadUrl?: string | null;
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
8
|
+
close: (result?: Record<string, any> | undefined) => any;
|
|
9
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
10
|
+
onClose?: ((result?: Record<string, any> | undefined) => any) | undefined;
|
|
11
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
|
+
declare const _default: typeof __VLS_export;
|
|
13
|
+
export default _default;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
downloadUrl: string | null;
|
|
3
|
+
modelValue: Record<string, any>;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
6
|
+
"update:modelValue": (value: Record<string, any>) => any;
|
|
7
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
8
|
+
"onUpdate:modelValue"?: ((value: Record<string, any>) => any) | undefined;
|
|
9
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
10
|
+
declare const _default: typeof __VLS_export;
|
|
11
|
+
export default _default;
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, ref, watch } from "vue";
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
downloadUrl: { type: [String, null], required: true },
|
|
5
|
+
modelValue: { type: Object, required: true }
|
|
6
|
+
});
|
|
7
|
+
const emit = defineEmits(["update:modelValue"]);
|
|
8
|
+
const videoEl = ref(null);
|
|
9
|
+
function parseTimestamp(val) {
|
|
10
|
+
if (typeof val === "number") return val;
|
|
11
|
+
if (typeof val === "string") {
|
|
12
|
+
const parts = val.split(":").map(Number);
|
|
13
|
+
if (parts.length === 3) return (parts[0] ?? 0) * 3600 + (parts[1] ?? 0) * 60 + (parts[2] ?? 0);
|
|
14
|
+
if (parts.length === 2) return (parts[0] ?? 0) * 60 + (parts[1] ?? 0);
|
|
15
|
+
const num = Number(val);
|
|
16
|
+
if (!Number.isNaN(num)) return num;
|
|
17
|
+
}
|
|
18
|
+
return 1;
|
|
19
|
+
}
|
|
20
|
+
const duration = ref(0);
|
|
21
|
+
const currentTimestamp = ref(parseTimestamp(props.modelValue.timestamp));
|
|
22
|
+
const seeking = ref(false);
|
|
23
|
+
const sizeOptions = ["default", "medium", "high", "standard", "maxres"];
|
|
24
|
+
const selectedSizes = computed(
|
|
25
|
+
() => Array.isArray(props.modelValue.sizes) ? props.modelValue.sizes : []
|
|
26
|
+
);
|
|
27
|
+
function formatTimestamp(secs) {
|
|
28
|
+
const h = Math.floor(secs / 3600);
|
|
29
|
+
const m = Math.floor(secs % 3600 / 60);
|
|
30
|
+
const s = secs % 60;
|
|
31
|
+
if (h > 0) return `${h}:${String(m).padStart(2, "0")}:${s.toFixed(1).padStart(4, "0")}`;
|
|
32
|
+
return `${m}:${s.toFixed(1).padStart(4, "0")}`;
|
|
33
|
+
}
|
|
34
|
+
function onMetadata() {
|
|
35
|
+
if (videoEl.value) {
|
|
36
|
+
duration.value = videoEl.value.duration || 0;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
function onSeeked() {
|
|
40
|
+
seeking.value = false;
|
|
41
|
+
}
|
|
42
|
+
function seekTo(time) {
|
|
43
|
+
const clamped = Math.max(0, Math.min(time, duration.value));
|
|
44
|
+
currentTimestamp.value = clamped;
|
|
45
|
+
if (videoEl.value) {
|
|
46
|
+
seeking.value = true;
|
|
47
|
+
videoEl.value.currentTime = clamped;
|
|
48
|
+
}
|
|
49
|
+
emitUpdate(clamped);
|
|
50
|
+
}
|
|
51
|
+
function onSliderChange(value) {
|
|
52
|
+
const v = Array.isArray(value) ? value[0] : value;
|
|
53
|
+
if (v != null) seekTo(v);
|
|
54
|
+
}
|
|
55
|
+
function onManualInput(value) {
|
|
56
|
+
const num = Number.parseFloat(value);
|
|
57
|
+
if (!Number.isNaN(num) && num >= 0) {
|
|
58
|
+
seekTo(num);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
function emitUpdate(timestamp) {
|
|
62
|
+
emit("update:modelValue", { ...props.modelValue, timestamp });
|
|
63
|
+
}
|
|
64
|
+
function onSizesChange(sizes) {
|
|
65
|
+
emit("update:modelValue", { ...props.modelValue, sizes, timestamp: currentTimestamp.value });
|
|
66
|
+
}
|
|
67
|
+
watch(() => props.modelValue.timestamp, (val) => {
|
|
68
|
+
const parsed = parseTimestamp(val);
|
|
69
|
+
if (parsed !== currentTimestamp.value) {
|
|
70
|
+
currentTimestamp.value = parsed;
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
const quickJumps = [0, 25, 50, 75, 100];
|
|
74
|
+
</script>
|
|
75
|
+
|
|
76
|
+
<template>
|
|
77
|
+
<div class="flex gap-4">
|
|
78
|
+
<!-- Video Preview -->
|
|
79
|
+
<div class="flex-1 /crelative rounded-lg overflow-hidden bg-black aspect-video">
|
|
80
|
+
<div class="">
|
|
81
|
+
<video
|
|
82
|
+
v-if="downloadUrl"
|
|
83
|
+
ref="videoEl"
|
|
84
|
+
:src="downloadUrl"
|
|
85
|
+
crossorigin="anonymous"
|
|
86
|
+
preload="metadata"
|
|
87
|
+
muted
|
|
88
|
+
class="w-full h-full object-contain"
|
|
89
|
+
@loadedmetadata="onMetadata"
|
|
90
|
+
@seeked="onSeeked"
|
|
91
|
+
/>
|
|
92
|
+
|
|
93
|
+
<div v-else class="flex items-center justify-center h-full text-muted text-sm">
|
|
94
|
+
<div class="text-center">
|
|
95
|
+
<UIcon name="i-lucide-video-off" class="size-8 mb-2"/>
|
|
96
|
+
<div>Video preview unavailable</div>
|
|
97
|
+
<div class="text-xs mt-1">Enter timestamp manually below</div>
|
|
98
|
+
</div>
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
<!-- Seeking indicator -->
|
|
102
|
+
<div v-if="seeking" class="absolute inset-0 flex items-center justify-center bg-black/30">
|
|
103
|
+
<UIcon name="i-lucide-loader" class="size-6 text-white animate-spin"/>
|
|
104
|
+
</div>
|
|
105
|
+
</div>
|
|
106
|
+
<!-- Scrubber -->
|
|
107
|
+
<div v-if="duration > 0" class="space-y-2">
|
|
108
|
+
<USlider
|
|
109
|
+
:model-value="currentTimestamp"
|
|
110
|
+
:min="0"
|
|
111
|
+
:max="duration"
|
|
112
|
+
:step="0.1"
|
|
113
|
+
size="sm"
|
|
114
|
+
@update:model-value="onSliderChange"
|
|
115
|
+
/>
|
|
116
|
+
<div class="flex items-center justify-between text-xs text-muted">
|
|
117
|
+
<span>{{ formatTimestamp(currentTimestamp) }}</span>
|
|
118
|
+
<span>{{ formatTimestamp(duration) }}</span>
|
|
119
|
+
</div>
|
|
120
|
+
|
|
121
|
+
<!-- Quick jump buttons -->
|
|
122
|
+
<div class="flex gap-1">
|
|
123
|
+
<UButton
|
|
124
|
+
v-for="pct in quickJumps"
|
|
125
|
+
:key="pct"
|
|
126
|
+
size="xs"
|
|
127
|
+
variant="ghost"
|
|
128
|
+
color="neutral"
|
|
129
|
+
:label="`${pct}%`"
|
|
130
|
+
@click="seekTo(duration * pct / 100)"
|
|
131
|
+
/>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
|
|
135
|
+
<!-- Manual timestamp input (always shown as fallback/alternative) -->
|
|
136
|
+
<UFormField label="Timestamp (seconds)">
|
|
137
|
+
<UInput
|
|
138
|
+
type="number"
|
|
139
|
+
:model-value="currentTimestamp"
|
|
140
|
+
:min="0"
|
|
141
|
+
:max="duration || void 0"
|
|
142
|
+
:step="0.1"
|
|
143
|
+
size="sm"
|
|
144
|
+
class="w-40"
|
|
145
|
+
@update:model-value="onManualInput(String($event))"
|
|
146
|
+
/>
|
|
147
|
+
</UFormField>
|
|
148
|
+
</div>
|
|
149
|
+
|
|
150
|
+
<div class="flex-1">
|
|
151
|
+
|
|
152
|
+
<!-- Thumbnail sizes -->
|
|
153
|
+
<UCheckboxGroup
|
|
154
|
+
legend="Sizes"
|
|
155
|
+
:items="sizeOptions"
|
|
156
|
+
:model-value="selectedSizes"
|
|
157
|
+
@update:model-value="onSizesChange"
|
|
158
|
+
/>
|
|
159
|
+
</div>
|
|
160
|
+
|
|
161
|
+
</div>
|
|
162
|
+
</template>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
downloadUrl: string | null;
|
|
3
|
+
modelValue: Record<string, any>;
|
|
4
|
+
};
|
|
5
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
6
|
+
"update:modelValue": (value: Record<string, any>) => any;
|
|
7
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
8
|
+
"onUpdate:modelValue"?: ((value: Record<string, any>) => any) | undefined;
|
|
9
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
10
|
+
declare const _default: typeof __VLS_export;
|
|
11
|
+
export default _default;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { PipelineOptionSchema } from "../../../types/asset.js";
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
schema: Record<string, PipelineOptionSchema>;
|
|
4
|
+
modelValue: Record<string, any>;
|
|
5
|
+
/** Keys to exclude from rendering (handled elsewhere, e.g., timestamp in FramePicker) */
|
|
6
|
+
exclude?: string[];
|
|
7
|
+
};
|
|
8
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
9
|
+
"update:modelValue": (value: Record<string, any>) => any;
|
|
10
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
11
|
+
"onUpdate:modelValue"?: ((value: Record<string, any>) => any) | undefined;
|
|
12
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
13
|
+
declare const _default: typeof __VLS_export;
|
|
14
|
+
export default _default;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed } from "vue";
|
|
3
|
+
const props = defineProps({
|
|
4
|
+
schema: { type: Object, required: true },
|
|
5
|
+
modelValue: { type: Object, required: true },
|
|
6
|
+
exclude: { type: Array, required: false }
|
|
7
|
+
});
|
|
8
|
+
const emit = defineEmits(["update:modelValue"]);
|
|
9
|
+
const entries = computed(() => {
|
|
10
|
+
const excluded = new Set(props.exclude ?? []);
|
|
11
|
+
return Object.entries(props.schema).filter(([key]) => !excluded.has(key));
|
|
12
|
+
});
|
|
13
|
+
function formatLabel(key) {
|
|
14
|
+
return key.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
15
|
+
}
|
|
16
|
+
function update(key, value) {
|
|
17
|
+
emit("update:modelValue", { ...props.modelValue, [key]: value });
|
|
18
|
+
}
|
|
19
|
+
function toggleArrayItem(key, item) {
|
|
20
|
+
const current = Array.isArray(props.modelValue[key]) ? [...props.modelValue[key]] : [];
|
|
21
|
+
const idx = current.indexOf(item);
|
|
22
|
+
if (idx >= 0) current.splice(idx, 1);
|
|
23
|
+
else current.push(item);
|
|
24
|
+
update(key, current);
|
|
25
|
+
}
|
|
26
|
+
function isArrayItemSelected(key, item) {
|
|
27
|
+
const current = props.modelValue[key];
|
|
28
|
+
return Array.isArray(current) && current.includes(item);
|
|
29
|
+
}
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
<template>
|
|
33
|
+
<div class="space-y-3">
|
|
34
|
+
<div v-for="([key, opt]) in entries" :key="key">
|
|
35
|
+
<!-- String with allowed values → Select -->
|
|
36
|
+
<UFormField v-if="opt.type === 'string' && opt.allowed_values?.length" :label="formatLabel(key)">
|
|
37
|
+
<USelect
|
|
38
|
+
:model-value="modelValue[key] ?? opt.default"
|
|
39
|
+
:items="opt.allowed_values.map((v) => ({ label: String(v), value: v }))"
|
|
40
|
+
size="sm"
|
|
41
|
+
class="w-full"
|
|
42
|
+
@update:model-value="update(key, $event)"
|
|
43
|
+
/>
|
|
44
|
+
</UFormField>
|
|
45
|
+
|
|
46
|
+
<!-- String without allowed values → Input -->
|
|
47
|
+
<UFormField v-else-if="opt.type === 'string'" :label="formatLabel(key)">
|
|
48
|
+
<UInput
|
|
49
|
+
:model-value="modelValue[key] ?? opt.default ?? ''"
|
|
50
|
+
size="sm"
|
|
51
|
+
@update:model-value="update(key, $event)"
|
|
52
|
+
/>
|
|
53
|
+
</UFormField>
|
|
54
|
+
|
|
55
|
+
<!-- Integer → Number input with min/max -->
|
|
56
|
+
<UFormField v-else-if="opt.type === 'integer'" :label="formatLabel(key)">
|
|
57
|
+
<UInput
|
|
58
|
+
type="number"
|
|
59
|
+
:model-value="modelValue[key] ?? opt.default"
|
|
60
|
+
:min="opt.min"
|
|
61
|
+
:max="opt.max"
|
|
62
|
+
size="sm"
|
|
63
|
+
class="w-32"
|
|
64
|
+
@update:model-value="update(key, Number($event))"
|
|
65
|
+
/>
|
|
66
|
+
<template v-if="opt.min != null || opt.max != null" #hint>
|
|
67
|
+
<span class="text-[10px] text-muted">
|
|
68
|
+
{{ opt.min != null ? `Min: ${opt.min}` : "" }}
|
|
69
|
+
{{ opt.min != null && opt.max != null ? " \xB7 " : "" }}
|
|
70
|
+
{{ opt.max != null ? `Max: ${opt.max}` : "" }}
|
|
71
|
+
</span>
|
|
72
|
+
</template>
|
|
73
|
+
</UFormField>
|
|
74
|
+
|
|
75
|
+
<!-- Boolean → Checkbox -->
|
|
76
|
+
<UFormField v-else-if="opt.type === 'boolean'" :label="formatLabel(key)">
|
|
77
|
+
<UCheckbox
|
|
78
|
+
:model-value="modelValue[key] ?? opt.default ?? false"
|
|
79
|
+
@update:model-value="update(key, $event)"
|
|
80
|
+
/>
|
|
81
|
+
</UFormField>
|
|
82
|
+
|
|
83
|
+
<!-- Array with allowed values → Checkbox group -->
|
|
84
|
+
<UFormField v-else-if="opt.type === 'array' && opt.allowed_values?.length" :label="formatLabel(key)">
|
|
85
|
+
<div class="flex flex-wrap gap-2">
|
|
86
|
+
<UButton
|
|
87
|
+
v-for="item in opt.allowed_values"
|
|
88
|
+
:key="String(item)"
|
|
89
|
+
size="xs"
|
|
90
|
+
:variant="isArrayItemSelected(key, item) ? 'solid' : 'outline'"
|
|
91
|
+
:color="isArrayItemSelected(key, item) ? 'primary' : 'neutral'"
|
|
92
|
+
:label="String(item)"
|
|
93
|
+
@click="toggleArrayItem(key, item)"
|
|
94
|
+
/>
|
|
95
|
+
</div>
|
|
96
|
+
</UFormField>
|
|
97
|
+
|
|
98
|
+
<!-- Array without allowed values → Comma input -->
|
|
99
|
+
<UFormField v-else-if="opt.type === 'array'" :label="formatLabel(key)">
|
|
100
|
+
<UInput
|
|
101
|
+
:model-value="Array.isArray(modelValue[key]) ? modelValue[key].join(', ') : (opt.default ?? []).join(', ')"
|
|
102
|
+
size="sm"
|
|
103
|
+
placeholder="Comma-separated values"
|
|
104
|
+
@update:model-value="update(key, $event.split(',').map((s) => s.trim()).filter(Boolean))"
|
|
105
|
+
/>
|
|
106
|
+
</UFormField>
|
|
107
|
+
</div>
|
|
108
|
+
|
|
109
|
+
<div v-if="!entries.length" class="text-xs text-muted">
|
|
110
|
+
No configurable options for this step.
|
|
111
|
+
</div>
|
|
112
|
+
</div>
|
|
113
|
+
</template>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { PipelineOptionSchema } from "../../../types/asset.js";
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
schema: Record<string, PipelineOptionSchema>;
|
|
4
|
+
modelValue: Record<string, any>;
|
|
5
|
+
/** Keys to exclude from rendering (handled elsewhere, e.g., timestamp in FramePicker) */
|
|
6
|
+
exclude?: string[];
|
|
7
|
+
};
|
|
8
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
9
|
+
"update:modelValue": (value: Record<string, any>) => any;
|
|
10
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
11
|
+
"onUpdate:modelValue"?: ((value: Record<string, any>) => any) | undefined;
|
|
12
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
13
|
+
declare const _default: typeof __VLS_export;
|
|
14
|
+
export default _default;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
assetId: string;
|
|
3
|
+
downloadUrl?: string | null;
|
|
4
|
+
/** Authoritative asset status (`processing` | `awaiting_input` | `ready` | `failed`). When provided, drives the headline status. */
|
|
5
|
+
assetStatus?: string | null;
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
8
|
+
failed: () => any;
|
|
9
|
+
complete: () => any;
|
|
10
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
11
|
+
onFailed?: (() => any) | undefined;
|
|
12
|
+
onComplete?: (() => any) | undefined;
|
|
13
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
14
|
+
declare const _default: typeof __VLS_export;
|
|
15
|
+
export default _default;
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
<script setup>
|
|
2
|
+
import { computed, watch } from "vue";
|
|
3
|
+
import { useOverlay, useToast } from "#imports";
|
|
4
|
+
import { useMLProcessingPipeline } from "../../composables/useMLProcessingPipeline";
|
|
5
|
+
import ConfigureStepModal from "./Forms/ConfigureStepModal.vue";
|
|
6
|
+
const props = defineProps({
|
|
7
|
+
assetId: { type: String, required: true },
|
|
8
|
+
downloadUrl: { type: [String, null], required: false },
|
|
9
|
+
assetStatus: { type: [String, null], required: false }
|
|
10
|
+
});
|
|
11
|
+
const emit = defineEmits(["complete", "failed"]);
|
|
12
|
+
const overlay = useOverlay();
|
|
13
|
+
const toast = useToast();
|
|
14
|
+
const {
|
|
15
|
+
tasks,
|
|
16
|
+
loading,
|
|
17
|
+
stream,
|
|
18
|
+
taskEventMap,
|
|
19
|
+
pipelineStatus,
|
|
20
|
+
pipelineElapsed,
|
|
21
|
+
completedCount,
|
|
22
|
+
totalSteps,
|
|
23
|
+
hasFailedSteps,
|
|
24
|
+
progressPercent,
|
|
25
|
+
expandedSteps,
|
|
26
|
+
pipelineSchema,
|
|
27
|
+
toggleStep,
|
|
28
|
+
configureTask,
|
|
29
|
+
triggerProcessing,
|
|
30
|
+
retryTask,
|
|
31
|
+
getBlocker,
|
|
32
|
+
groupedTasks,
|
|
33
|
+
firstPendingInputTask
|
|
34
|
+
} = useMLProcessingPipeline(() => props.assetId, () => props.assetStatus);
|
|
35
|
+
function humanize(name) {
|
|
36
|
+
return name.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
37
|
+
}
|
|
38
|
+
const pendingInputStepName = computed(
|
|
39
|
+
() => firstPendingInputTask.value ? humanize(firstPendingInputTask.value.task_type) : ""
|
|
40
|
+
);
|
|
41
|
+
async function onRetry(taskId) {
|
|
42
|
+
try {
|
|
43
|
+
await retryTask(taskId);
|
|
44
|
+
} catch (err) {
|
|
45
|
+
const message = err?.data?.detail ?? err?.data?.message ?? err?.statusMessage ?? "Could not retry task";
|
|
46
|
+
toast.add({ title: "Retry failed", description: String(message), color: "error" });
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
async function openConfigure(taskId) {
|
|
50
|
+
const task = tasks.value.find((t) => t.id === taskId);
|
|
51
|
+
if (!task) return;
|
|
52
|
+
const schema = pipelineSchema.value[task.task_type] ?? {};
|
|
53
|
+
const modal = overlay.create(ConfigureStepModal, {
|
|
54
|
+
props: {
|
|
55
|
+
taskType: task.task_type,
|
|
56
|
+
schema,
|
|
57
|
+
downloadUrl: props.downloadUrl
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
const result = await modal.open();
|
|
61
|
+
if (result) {
|
|
62
|
+
await configureTask(taskId, result);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
watch(pipelineStatus, (status) => {
|
|
66
|
+
if (status === "succeeded") emit("complete");
|
|
67
|
+
if (status === "failed") emit("failed");
|
|
68
|
+
});
|
|
69
|
+
</script>
|
|
70
|
+
|
|
71
|
+
<template>
|
|
72
|
+
<div class="space-y-0">
|
|
73
|
+
<MLProcessingTopBar title="Processing Pipeline" :status="pipelineStatus">
|
|
74
|
+
<template #subtitle>
|
|
75
|
+
{{ completedCount }} of {{ totalSteps }} steps completed
|
|
76
|
+
<template v-if="pipelineElapsed"> · {{ pipelineElapsed }}</template>
|
|
77
|
+
<template v-if="pipelineStatus === 'awaiting_input'"> · Awaiting configuration</template>
|
|
78
|
+
</template>
|
|
79
|
+
<template #actions>
|
|
80
|
+
<UButton
|
|
81
|
+
variant="outline"
|
|
82
|
+
:color="hasFailedSteps ? 'warning' : 'neutral'"
|
|
83
|
+
size="xs"
|
|
84
|
+
:icon="hasFailedSteps ? 'i-lucide-refresh-cw' : 'i-lucide-play'"
|
|
85
|
+
label="Reprocess"
|
|
86
|
+
@click="triggerProcessing()"
|
|
87
|
+
/>
|
|
88
|
+
</template>
|
|
89
|
+
</MLProcessingTopBar>
|
|
90
|
+
|
|
91
|
+
<MLProcessingProgressBar
|
|
92
|
+
v-if="pipelineStatus === 'running'"
|
|
93
|
+
:percent="progressPercent"
|
|
94
|
+
/>
|
|
95
|
+
|
|
96
|
+
<!-- AWAITING_INPUT banner: pipeline is paused on a configurable step -->
|
|
97
|
+
<UAlert
|
|
98
|
+
v-if="pipelineStatus === 'awaiting_input' && firstPendingInputTask"
|
|
99
|
+
icon="i-lucide-pencil-line"
|
|
100
|
+
color="warning"
|
|
101
|
+
variant="subtle"
|
|
102
|
+
:title="`Pipeline paused \u2014 configure ${pendingInputStepName} to continue`"
|
|
103
|
+
description="The pipeline will resume automatically once options are provided."
|
|
104
|
+
class="rounded-none border-x border-default"
|
|
105
|
+
>
|
|
106
|
+
<template #actions>
|
|
107
|
+
<UButton
|
|
108
|
+
size="xs"
|
|
109
|
+
color="warning"
|
|
110
|
+
icon="i-lucide-settings"
|
|
111
|
+
label="Configure"
|
|
112
|
+
@click="openConfigure(firstPendingInputTask.id)"
|
|
113
|
+
/>
|
|
114
|
+
</template>
|
|
115
|
+
</UAlert>
|
|
116
|
+
|
|
117
|
+
<!-- Timeline Body -->
|
|
118
|
+
<div class="border border-t-0 border-default rounded-b-lg">
|
|
119
|
+
<!-- Loading -->
|
|
120
|
+
<div v-if="loading && !tasks.length" class="space-y-3 p-4">
|
|
121
|
+
<USkeleton v-for="i in 4" :key="i" class="h-10 w-full" />
|
|
122
|
+
</div>
|
|
123
|
+
|
|
124
|
+
<!-- Task Timeline -->
|
|
125
|
+
<template v-else-if="tasks.length">
|
|
126
|
+
<!-- Asset pipeline -->
|
|
127
|
+
<div v-if="groupedTasks.assetTasks.length">
|
|
128
|
+
<MLProcessingPipelineStepItem
|
|
129
|
+
v-for="task in groupedTasks.assetTasks"
|
|
130
|
+
:key="task.id"
|
|
131
|
+
:task="task"
|
|
132
|
+
:expanded="expandedSteps.has(task.id)"
|
|
133
|
+
:sse-event="taskEventMap.get(task.id) ?? null"
|
|
134
|
+
:blocker="getBlocker(task.id)"
|
|
135
|
+
@toggle="toggleStep(task.id)"
|
|
136
|
+
@retry="onRetry"
|
|
137
|
+
@configure="openConfigure"
|
|
138
|
+
/>
|
|
139
|
+
</div>
|
|
140
|
+
|
|
141
|
+
<!-- Per-rendition pipelines -->
|
|
142
|
+
<div
|
|
143
|
+
v-for="group in groupedTasks.renditionGroups"
|
|
144
|
+
:key="group.renditionId"
|
|
145
|
+
class="border-t border-default"
|
|
146
|
+
>
|
|
147
|
+
<div class="flex items-center gap-2 px-4 py-2 bg-muted/20 text-xs text-muted">
|
|
148
|
+
<UIcon name="i-lucide-layers" class="size-3.5" />
|
|
149
|
+
<span class="font-medium">Rendition</span>
|
|
150
|
+
<span class="font-mono">{{ group.renditionId.slice(0, 8) }}</span>
|
|
151
|
+
</div>
|
|
152
|
+
<MLProcessingPipelineStepItem
|
|
153
|
+
v-for="task in group.tasks"
|
|
154
|
+
:key="task.id"
|
|
155
|
+
:task="task"
|
|
156
|
+
:expanded="expandedSteps.has(task.id)"
|
|
157
|
+
:sse-event="taskEventMap.get(task.id) ?? null"
|
|
158
|
+
:blocker="getBlocker(task.id)"
|
|
159
|
+
@toggle="toggleStep(task.id)"
|
|
160
|
+
@retry="onRetry"
|
|
161
|
+
@configure="openConfigure"
|
|
162
|
+
/>
|
|
163
|
+
</div>
|
|
164
|
+
</template>
|
|
165
|
+
|
|
166
|
+
<!-- Empty -->
|
|
167
|
+
<UEmpty
|
|
168
|
+
v-else
|
|
169
|
+
icon="i-lucide-cpu"
|
|
170
|
+
title="No processing tasks"
|
|
171
|
+
description="Processing tasks will appear here when the asset is being processed."
|
|
172
|
+
size="sm"
|
|
173
|
+
class="py-8"
|
|
174
|
+
/>
|
|
175
|
+
</div>
|
|
176
|
+
|
|
177
|
+
</div>
|
|
178
|
+
</template>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type __VLS_Props = {
|
|
2
|
+
assetId: string;
|
|
3
|
+
downloadUrl?: string | null;
|
|
4
|
+
/** Authoritative asset status (`processing` | `awaiting_input` | `ready` | `failed`). When provided, drives the headline status. */
|
|
5
|
+
assetStatus?: string | null;
|
|
6
|
+
};
|
|
7
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
8
|
+
failed: () => any;
|
|
9
|
+
complete: () => any;
|
|
10
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
11
|
+
onFailed?: (() => any) | undefined;
|
|
12
|
+
onComplete?: (() => any) | undefined;
|
|
13
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
14
|
+
declare const _default: typeof __VLS_export;
|
|
15
|
+
export default _default;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ProcessingTask } from "../../types/asset.js";
|
|
2
|
+
import type { ProcessingEvent } from "../../composables/useMLProcessingStatus.js";
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
task: ProcessingTask;
|
|
5
|
+
expanded: boolean;
|
|
6
|
+
sseEvent?: ProcessingEvent | null;
|
|
7
|
+
/** Upstream task currently blocking this row (only meaningful for `waiting` rows). */
|
|
8
|
+
blocker?: ProcessingTask | null;
|
|
9
|
+
};
|
|
10
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
11
|
+
toggle: () => any;
|
|
12
|
+
retry: (taskId: string) => any;
|
|
13
|
+
configure: (taskId: string) => any;
|
|
14
|
+
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
15
|
+
onToggle?: (() => any) | undefined;
|
|
16
|
+
onRetry?: ((taskId: string) => any) | undefined;
|
|
17
|
+
onConfigure?: ((taskId: string) => any) | undefined;
|
|
18
|
+
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
19
|
+
declare const _default: typeof __VLS_export;
|
|
20
|
+
export default _default;
|