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.
Files changed (164) hide show
  1. package/README.md +243 -0
  2. package/dist/module.d.mts +31 -0
  3. package/dist/module.d.ts +31 -0
  4. package/dist/module.json +9 -0
  5. package/dist/module.mjs +118 -0
  6. package/dist/runtime/components/MLAssetManager/AssetActivity.d.vue.ts +6 -0
  7. package/dist/runtime/components/MLAssetManager/AssetActivity.vue +13 -0
  8. package/dist/runtime/components/MLAssetManager/AssetActivity.vue.d.ts +6 -0
  9. package/dist/runtime/components/MLAssetManager/AssetCard.d.vue.ts +14 -0
  10. package/dist/runtime/components/MLAssetManager/AssetCard.vue +100 -0
  11. package/dist/runtime/components/MLAssetManager/AssetCard.vue.d.ts +14 -0
  12. package/dist/runtime/components/MLAssetManager/AssetDetail.d.vue.ts +14 -0
  13. package/dist/runtime/components/MLAssetManager/AssetDetail.vue +156 -0
  14. package/dist/runtime/components/MLAssetManager/AssetDetail.vue.d.ts +14 -0
  15. package/dist/runtime/components/MLAssetManager/AssetList.d.vue.ts +15 -0
  16. package/dist/runtime/components/MLAssetManager/AssetList.vue +41 -0
  17. package/dist/runtime/components/MLAssetManager/AssetList.vue.d.ts +15 -0
  18. package/dist/runtime/components/MLAssetManager/AssetOverview.d.vue.ts +8 -0
  19. package/dist/runtime/components/MLAssetManager/AssetOverview.vue +321 -0
  20. package/dist/runtime/components/MLAssetManager/AssetOverview.vue.d.ts +8 -0
  21. package/dist/runtime/components/MLAssetManager/AssetPreview.d.vue.ts +10 -0
  22. package/dist/runtime/components/MLAssetManager/AssetPreview.vue +18 -0
  23. package/dist/runtime/components/MLAssetManager/AssetPreview.vue.d.ts +10 -0
  24. package/dist/runtime/components/MLAssetManager/AssetPreviewAudio.d.vue.ts +9 -0
  25. package/dist/runtime/components/MLAssetManager/AssetPreviewAudio.vue +21 -0
  26. package/dist/runtime/components/MLAssetManager/AssetPreviewAudio.vue.d.ts +9 -0
  27. package/dist/runtime/components/MLAssetManager/AssetPreviewDocument.d.vue.ts +9 -0
  28. package/dist/runtime/components/MLAssetManager/AssetPreviewDocument.vue +39 -0
  29. package/dist/runtime/components/MLAssetManager/AssetPreviewDocument.vue.d.ts +9 -0
  30. package/dist/runtime/components/MLAssetManager/AssetPreviewFallback.d.vue.ts +7 -0
  31. package/dist/runtime/components/MLAssetManager/AssetPreviewFallback.vue +41 -0
  32. package/dist/runtime/components/MLAssetManager/AssetPreviewFallback.vue.d.ts +7 -0
  33. package/dist/runtime/components/MLAssetManager/AssetPreviewImage.d.vue.ts +9 -0
  34. package/dist/runtime/components/MLAssetManager/AssetPreviewImage.vue +30 -0
  35. package/dist/runtime/components/MLAssetManager/AssetPreviewImage.vue.d.ts +9 -0
  36. package/dist/runtime/components/MLAssetManager/AssetPreviewSidebar.d.vue.ts +15 -0
  37. package/dist/runtime/components/MLAssetManager/AssetPreviewSidebar.vue +69 -0
  38. package/dist/runtime/components/MLAssetManager/AssetPreviewSidebar.vue.d.ts +15 -0
  39. package/dist/runtime/components/MLAssetManager/AssetPreviewVideo.d.vue.ts +9 -0
  40. package/dist/runtime/components/MLAssetManager/AssetPreviewVideo.vue +148 -0
  41. package/dist/runtime/components/MLAssetManager/AssetPreviewVideo.vue.d.ts +9 -0
  42. package/dist/runtime/components/MLAssetManager/AssetRenditions.d.vue.ts +8 -0
  43. package/dist/runtime/components/MLAssetManager/AssetRenditions.vue +148 -0
  44. package/dist/runtime/components/MLAssetManager/AssetRenditions.vue.d.ts +8 -0
  45. package/dist/runtime/components/MLAssetManager/Processing.d.vue.ts +8 -0
  46. package/dist/runtime/components/MLAssetManager/Processing.vue +84 -0
  47. package/dist/runtime/components/MLAssetManager/Processing.vue.d.ts +8 -0
  48. package/dist/runtime/components/MLAssetManager/SlotCard.d.vue.ts +17 -0
  49. package/dist/runtime/components/MLAssetManager/SlotCard.vue +94 -0
  50. package/dist/runtime/components/MLAssetManager/SlotCard.vue.d.ts +17 -0
  51. package/dist/runtime/components/MLAssetManager/Widget.d.vue.ts +14 -0
  52. package/dist/runtime/components/MLAssetManager/Widget.vue +328 -0
  53. package/dist/runtime/components/MLAssetManager/Widget.vue.d.ts +14 -0
  54. package/dist/runtime/components/MLPreviewProvider.d.vue.ts +31 -0
  55. package/dist/runtime/components/MLPreviewProvider.vue +51 -0
  56. package/dist/runtime/components/MLPreviewProvider.vue.d.ts +31 -0
  57. package/dist/runtime/components/MLProcessing/Forms/ConfigureStepModal.d.vue.ts +13 -0
  58. package/dist/runtime/components/MLProcessing/Forms/ConfigureStepModal.vue +47 -0
  59. package/dist/runtime/components/MLProcessing/Forms/ConfigureStepModal.vue.d.ts +13 -0
  60. package/dist/runtime/components/MLProcessing/Forms/FramePicker.d.vue.ts +11 -0
  61. package/dist/runtime/components/MLProcessing/Forms/FramePicker.vue +162 -0
  62. package/dist/runtime/components/MLProcessing/Forms/FramePicker.vue.d.ts +11 -0
  63. package/dist/runtime/components/MLProcessing/Forms/StepOptionsForm.d.vue.ts +14 -0
  64. package/dist/runtime/components/MLProcessing/Forms/StepOptionsForm.vue +113 -0
  65. package/dist/runtime/components/MLProcessing/Forms/StepOptionsForm.vue.d.ts +14 -0
  66. package/dist/runtime/components/MLProcessing/Pipeline.d.vue.ts +15 -0
  67. package/dist/runtime/components/MLProcessing/Pipeline.vue +178 -0
  68. package/dist/runtime/components/MLProcessing/Pipeline.vue.d.ts +15 -0
  69. package/dist/runtime/components/MLProcessing/PipelineStepItem.d.vue.ts +20 -0
  70. package/dist/runtime/components/MLProcessing/PipelineStepItem.vue +309 -0
  71. package/dist/runtime/components/MLProcessing/PipelineStepItem.vue.d.ts +20 -0
  72. package/dist/runtime/components/MLProcessing/ProgressBar.d.vue.ts +9 -0
  73. package/dist/runtime/components/MLProcessing/ProgressBar.vue +27 -0
  74. package/dist/runtime/components/MLProcessing/ProgressBar.vue.d.ts +9 -0
  75. package/dist/runtime/components/MLProcessing/StepLayout.d.vue.ts +31 -0
  76. package/dist/runtime/components/MLProcessing/StepLayout.vue +36 -0
  77. package/dist/runtime/components/MLProcessing/StepLayout.vue.d.ts +31 -0
  78. package/dist/runtime/components/MLProcessing/Stepper.d.vue.ts +16 -0
  79. package/dist/runtime/components/MLProcessing/Stepper.vue +87 -0
  80. package/dist/runtime/components/MLProcessing/Stepper.vue.d.ts +16 -0
  81. package/dist/runtime/components/MLProcessing/StepperItem.d.vue.ts +16 -0
  82. package/dist/runtime/components/MLProcessing/StepperItem.vue +150 -0
  83. package/dist/runtime/components/MLProcessing/StepperItem.vue.d.ts +16 -0
  84. package/dist/runtime/components/MLProcessing/TopBar.d.vue.ts +21 -0
  85. package/dist/runtime/components/MLProcessing/TopBar.vue +46 -0
  86. package/dist/runtime/components/MLProcessing/TopBar.vue.d.ts +21 -0
  87. package/dist/runtime/components/MLUploader/ButtonUploader.d.vue.ts +55 -0
  88. package/dist/runtime/components/MLUploader/ButtonUploader.vue +211 -0
  89. package/dist/runtime/components/MLUploader/ButtonUploader.vue.d.ts +55 -0
  90. package/dist/runtime/components/MLUploader/Item.d.vue.ts +34 -0
  91. package/dist/runtime/components/MLUploader/Item.vue +242 -0
  92. package/dist/runtime/components/MLUploader/Item.vue.d.ts +34 -0
  93. package/dist/runtime/components/MLUploader/PolicyPopover.d.vue.ts +7 -0
  94. package/dist/runtime/components/MLUploader/PolicyPopover.vue +160 -0
  95. package/dist/runtime/components/MLUploader/PolicyPopover.vue.d.ts +7 -0
  96. package/dist/runtime/components/MLUploader/Widget.d.vue.ts +44 -0
  97. package/dist/runtime/components/MLUploader/Widget.vue +251 -0
  98. package/dist/runtime/components/MLUploader/Widget.vue.d.ts +44 -0
  99. package/dist/runtime/composables/resourcePolicy/mimeUtils.d.ts +4 -0
  100. package/dist/runtime/composables/resourcePolicy/mimeUtils.js +71 -0
  101. package/dist/runtime/composables/resourcePolicy/useMLResourcePolicy.d.ts +17 -0
  102. package/dist/runtime/composables/resourcePolicy/useMLResourcePolicy.js +150 -0
  103. package/dist/runtime/composables/useElapsedTimer.d.ts +13 -0
  104. package/dist/runtime/composables/useElapsedTimer.js +46 -0
  105. package/dist/runtime/composables/useMLAssetLibrary.d.ts +31 -0
  106. package/dist/runtime/composables/useMLAssetLibrary.js +53 -0
  107. package/dist/runtime/composables/useMLAssetManager.d.ts +30 -0
  108. package/dist/runtime/composables/useMLAssetManager.js +229 -0
  109. package/dist/runtime/composables/useMLAssetManagerPreview.d.ts +28 -0
  110. package/dist/runtime/composables/useMLAssetManagerPreview.js +232 -0
  111. package/dist/runtime/composables/useMLAssetPreview.d.ts +23 -0
  112. package/dist/runtime/composables/useMLAssetPreview.js +153 -0
  113. package/dist/runtime/composables/useMLChunkUploader.d.ts +9 -0
  114. package/dist/runtime/composables/useMLChunkUploader.js +22 -0
  115. package/dist/runtime/composables/useMLProcessingPipeline.d.ts +38 -0
  116. package/dist/runtime/composables/useMLProcessingPipeline.js +258 -0
  117. package/dist/runtime/composables/useMLProcessingStatus.d.ts +34 -0
  118. package/dist/runtime/composables/useMLProcessingStatus.js +100 -0
  119. package/dist/runtime/composables/useMLProcessingStepper.d.ts +32 -0
  120. package/dist/runtime/composables/useMLProcessingStepper.js +280 -0
  121. package/dist/runtime/composables/useMLProcessingStrategies.d.ts +7 -0
  122. package/dist/runtime/composables/useMLProcessingStrategies.js +47 -0
  123. package/dist/runtime/composables/useMLRepeater.d.ts +5 -0
  124. package/dist/runtime/composables/useMLRepeater.js +11 -0
  125. package/dist/runtime/css/index.css +1 -0
  126. package/dist/runtime/index.d.ts +13 -0
  127. package/dist/runtime/index.js +13 -0
  128. package/dist/runtime/plugins/asset-direcetive-client.d.ts +2 -0
  129. package/dist/runtime/plugins/asset-direcetive-client.js +64 -0
  130. package/dist/runtime/plugins/config.d.ts +13 -0
  131. package/dist/runtime/plugins/config.js +23 -0
  132. package/dist/runtime/schemas/resource-policy.schema.d.ts +607 -0
  133. package/dist/runtime/schemas/resource-policy.schema.js +117 -0
  134. package/dist/runtime/server/assets-proxy.d.ts +2 -0
  135. package/dist/runtime/server/assets-proxy.js +81 -0
  136. package/dist/runtime/server/create-ml-proxy.d.ts +47 -0
  137. package/dist/runtime/server/create-ml-proxy.js +232 -0
  138. package/dist/runtime/server/delivery-proxy.d.ts +2 -0
  139. package/dist/runtime/server/delivery-proxy.js +74 -0
  140. package/dist/runtime/server/index.d.ts +2 -0
  141. package/dist/runtime/server/index.js +1 -0
  142. package/dist/runtime/server/processing-proxy.d.ts +2 -0
  143. package/dist/runtime/server/processing-proxy.js +55 -0
  144. package/dist/runtime/server/resource-policy-proxy.d.ts +2 -0
  145. package/dist/runtime/server/resource-policy-proxy.js +80 -0
  146. package/dist/runtime/server/tsconfig.json +0 -0
  147. package/dist/runtime/server/uploads-proxy.d.ts +2 -0
  148. package/dist/runtime/server/uploads-proxy.js +99 -0
  149. package/dist/runtime/types/asset.d.ts +174 -0
  150. package/dist/runtime/types/asset.js +7 -0
  151. package/dist/runtime/types/preview.d.ts +20 -0
  152. package/dist/runtime/types/preview.js +0 -0
  153. package/dist/runtime/types/resourcePolicy.d.ts +77 -0
  154. package/dist/runtime/types/resourcePolicy.js +25 -0
  155. package/dist/runtime/types/uploader.d.ts +71 -0
  156. package/dist/runtime/types/uploader.js +0 -0
  157. package/dist/runtime/utils/uploader/checksum.d.ts +21 -0
  158. package/dist/runtime/utils/uploader/checksum.js +23 -0
  159. package/dist/runtime/utils/uploader/chunking.d.ts +8 -0
  160. package/dist/runtime/utils/uploader/chunking.js +21 -0
  161. package/dist/runtime/utils/uploader/uploader.d.ts +20 -0
  162. package/dist/runtime/utils/uploader/uploader.js +206 -0
  163. package/dist/types.d.mts +11 -0
  164. package/package.json +81 -0
@@ -0,0 +1,150 @@
1
+ <script setup>
2
+ import { computed } from "vue";
3
+ const props = defineProps({
4
+ step: { type: Object, required: true },
5
+ downloadUrl: { type: [String, null], required: false }
6
+ });
7
+ const emit = defineEmits(["update:options", "run", "retry"]);
8
+ const isDone = computed(() => props.step.status === "succeeded");
9
+ const isRunning = computed(() => props.step.status === "running");
10
+ const isFailed = computed(() => props.step.status === "failed");
11
+ const isConfiguring = computed(() => props.step.status === "configuring");
12
+ const isPending = computed(() => props.step.status === "pending");
13
+ const isLocked = computed(() => props.step.isLocked);
14
+ const canRun = computed(
15
+ () => !isLocked.value && (isConfiguring.value || isPending.value)
16
+ );
17
+ const showOptions = computed(
18
+ () => (isConfiguring.value || isFailed.value) && props.step.hasOptions && !isLocked.value
19
+ );
20
+ const showFramePicker = computed(
21
+ () => showOptions.value && props.step.name === "video_thumbnail"
22
+ );
23
+ const titleClasses = computed(() => {
24
+ if (isDone.value) return "font-semibold text-default";
25
+ if (isRunning.value || isConfiguring.value) return "font-bold text-primary";
26
+ if (isFailed.value) return "font-semibold text-error";
27
+ return "text-muted";
28
+ });
29
+ const stepIcon = computed(() => {
30
+ if (isDone.value) return "i-lucide-circle-check";
31
+ if (isRunning.value) return "i-lucide-loader";
32
+ if (isFailed.value) return "i-lucide-circle-x";
33
+ if (isConfiguring.value) return "i-lucide-settings-2";
34
+ if (isLocked.value) return "i-lucide-lock";
35
+ return "i-lucide-circle-dot";
36
+ });
37
+ const iconClasses = computed(() => {
38
+ if (isDone.value) return "text-green-500";
39
+ if (isRunning.value || isConfiguring.value) return "text-primary";
40
+ if (isFailed.value) return "text-red-500";
41
+ if (isLocked.value) return "text-muted/50";
42
+ return "text-muted";
43
+ });
44
+ const statusLabel = computed(() => {
45
+ if (isDone.value) return "DONE";
46
+ if (isRunning.value) return "RUNNING";
47
+ if (isFailed.value) return "FAILED";
48
+ if (isConfiguring.value) return "CONFIGURE";
49
+ if (isLocked.value) return "LOCKED";
50
+ return "PENDING";
51
+ });
52
+ const badgeColor = computed(() => {
53
+ if (isDone.value) return "success";
54
+ if (isRunning.value) return "warning";
55
+ if (isFailed.value) return "error";
56
+ if (isConfiguring.value) return "info";
57
+ return "neutral";
58
+ });
59
+ const hasBody = computed(
60
+ () => isRunning.value || isFailed.value && !!props.step.error || showOptions.value || isConfiguring.value && !props.step.hasOptions || canRun.value || isFailed.value || isDone.value && !!props.step.task?.metadata_payload && Object.keys(props.step.task.metadata_payload).length > 0
61
+ );
62
+ </script>
63
+
64
+ <template>
65
+ <MLProcessingStepLayout
66
+ :title="step.displayName"
67
+ :title-class="titleClasses"
68
+ :icon="stepIcon"
69
+ :icon-class="iconClasses"
70
+ :spinning="isRunning"
71
+ class="transition-opacity duration-200"
72
+ :class="{ 'opacity-40 pointer-events-none': isLocked }"
73
+ >
74
+ <template #header-actions>
75
+ <UBadge :label="statusLabel" :color="badgeColor" variant="subtle" size="sm"/>
76
+ </template>
77
+
78
+ <div
79
+ v-if="hasBody"
80
+ class="ps-8 py-2 pe-2">
81
+ <!-- Running state -->
82
+ <div v-if="isRunning" class="mt-2 flex items-center gap-2 text-xs text-muted">
83
+ <UIcon name="i-lucide-loader" class="size-3.5 animate-spin text-primary"/>
84
+ <span>Processing...</span>
85
+ </div>
86
+ <!-- Error display -->
87
+ <div v-if="isFailed && step.error"
88
+ class="mt-2 bg-error/5 border border-error/20 rounded-md p-3 text-error text-xs">
89
+ <pre class="whitespace-pre-wrap font-mono text-[11px]">{{ step.error }}</pre>
90
+ </div>
91
+
92
+ <!-- Options Form (configuring state) -->
93
+ <div v-if="showOptions" class="mt-3">
94
+ <!-- Frame picker for video_thumbnail -->
95
+ <MLProcessingFormsFramePicker
96
+ v-if="showFramePicker"
97
+ :download-url="downloadUrl ?? null"
98
+ :model-value="step.userOptions"
99
+ @update:model-value="emit('update:options', $event)"
100
+ />
101
+ <!-- Generic options form -->
102
+ <MLProcessingFormsStepOptionsForm
103
+ v-else
104
+ :schema="step.optionsSchema"
105
+ :model-value="step.userOptions"
106
+ @update:model-value="emit('update:options', $event)"
107
+ />
108
+ </div>
109
+
110
+ <!-- No options message -->
111
+ <div v-if="isConfiguring && !step.hasOptions" class="mt-2 text-xs text-muted">
112
+ No configuration needed for this step.
113
+ </div>
114
+
115
+ <!-- Action buttons -->
116
+ <div v-if="canRun || isFailed" class="mt-3 flex gap-2">
117
+ <UButton
118
+ v-if="canRun"
119
+ size="xs"
120
+ icon="i-lucide-play"
121
+ label="Run Step"
122
+ @click="emit('run')"
123
+ />
124
+ <UButton
125
+ v-if="isFailed"
126
+ size="xs"
127
+ color="warning"
128
+ icon="i-lucide-settings-2"
129
+ label="Reconfigure"
130
+ @click="emit('retry')"
131
+ />
132
+ </div>
133
+
134
+ <!-- Completed metadata -->
135
+ <div
136
+ v-if="isDone && step.task?.metadata_payload && Object.keys(step.task.metadata_payload).length"
137
+ class="mt-2 text-xs text-muted"
138
+ >
139
+ <span
140
+ v-for="([k, v]) in Object.entries(step.task.metadata_payload).filter(([k2]) => k2 !== 'skipped')"
141
+ :key="k"
142
+ class="mr-3"
143
+ >
144
+ {{ k.replace(/_/g, " ") }}: <span
145
+ class="font-medium text-default">{{ typeof v === "boolean" ? v ? "Yes" : "No" : v }}</span>
146
+ </span>
147
+ </div>
148
+ </div>
149
+ </MLProcessingStepLayout>
150
+ </template>
@@ -0,0 +1,16 @@
1
+ import type { StepState } from "../../composables/useMLProcessingStepper.js";
2
+ type __VLS_Props = {
3
+ step: StepState;
4
+ downloadUrl?: string | null;
5
+ };
6
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
7
+ retry: () => any;
8
+ "update:options": (value: Record<string, any>) => any;
9
+ run: () => any;
10
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
11
+ onRetry?: (() => any) | undefined;
12
+ "onUpdate:options"?: ((value: Record<string, any>) => any) | undefined;
13
+ onRun?: (() => any) | undefined;
14
+ }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;
@@ -0,0 +1,21 @@
1
+ type __VLS_Props = {
2
+ title: string;
3
+ status?: 'queued' | 'running' | 'succeeded' | 'failed' | null;
4
+ };
5
+ declare var __VLS_1: {}, __VLS_3: {};
6
+ type __VLS_Slots = {} & {
7
+ subtitle?: (props: typeof __VLS_1) => any;
8
+ } & {
9
+ actions?: (props: typeof __VLS_3) => any;
10
+ };
11
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
12
+ status: "queued" | "running" | "succeeded" | "failed" | null;
13
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;
17
+ type __VLS_WithSlots<T, S> = T & {
18
+ new (): {
19
+ $slots: S;
20
+ };
21
+ };
@@ -0,0 +1,46 @@
1
+ <script setup>
2
+ import { computed } from "vue";
3
+ const props = defineProps({
4
+ title: { type: String, required: true },
5
+ status: { type: [String, null], required: false, default: null }
6
+ });
7
+ const bgClasses = computed(() => {
8
+ if (props.status === "succeeded") return "bg-green-500/5";
9
+ if (props.status === "failed") return "bg-red-500/5";
10
+ return "";
11
+ });
12
+ const dotClasses = computed(() => {
13
+ switch (props.status) {
14
+ case "queued":
15
+ return "bg-muted border border-default";
16
+ case "running":
17
+ return "bg-primary border border-primary animate-pulse";
18
+ case "succeeded":
19
+ return "bg-green-500 border border-green-500";
20
+ case "failed":
21
+ return "bg-red-500 border border-red-500";
22
+ default:
23
+ return "";
24
+ }
25
+ });
26
+ </script>
27
+
28
+ <template>
29
+ <div
30
+ class="flex items-center justify-between px-4 py-3 border border-default rounded-t-lg"
31
+ :class="bgClasses"
32
+ >
33
+ <div class="flex items-center gap-3 min-w-0">
34
+ <div v-if="status" class="w-3 h-3 rounded-full shrink-0" :class="dotClasses" />
35
+ <div class="min-w-0">
36
+ <div class="text-sm font-semibold text-default">{{ title }}</div>
37
+ <div class="text-xs text-muted">
38
+ <slot name="subtitle" />
39
+ </div>
40
+ </div>
41
+ </div>
42
+ <div class="flex items-center gap-2 shrink-0">
43
+ <slot name="actions" />
44
+ </div>
45
+ </div>
46
+ </template>
@@ -0,0 +1,21 @@
1
+ type __VLS_Props = {
2
+ title: string;
3
+ status?: 'queued' | 'running' | 'succeeded' | 'failed' | null;
4
+ };
5
+ declare var __VLS_1: {}, __VLS_3: {};
6
+ type __VLS_Slots = {} & {
7
+ subtitle?: (props: typeof __VLS_1) => any;
8
+ } & {
9
+ actions?: (props: typeof __VLS_3) => any;
10
+ };
11
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
12
+ status: "queued" | "running" | "succeeded" | "failed" | null;
13
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;
17
+ type __VLS_WithSlots<T, S> = T & {
18
+ new (): {
19
+ $slots: S;
20
+ };
21
+ };
@@ -0,0 +1,55 @@
1
+ type __VLS_Props = {
2
+ resourceType: string;
3
+ collectionName?: string | null;
4
+ chunkUploader?: Record<string, any> | string;
5
+ label?: string;
6
+ uploadingLabel?: string;
7
+ uploadedLabel?: string;
8
+ processingLabel?: string;
9
+ readyLabel?: string;
10
+ errorLabel?: string;
11
+ fileTypeErrorText?: string;
12
+ fileTooLargeText?: string;
13
+ fileTooSmallText?: string;
14
+ uploadFailedText?: string;
15
+ };
16
+ type __VLS_ModelProps = {
17
+ modelValue?: string[];
18
+ };
19
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
20
+ declare var __VLS_13: {}, __VLS_32: {};
21
+ type __VLS_Slots = {} & {
22
+ default?: (props: typeof __VLS_13) => any;
23
+ } & {
24
+ default?: (props: typeof __VLS_32) => any;
25
+ };
26
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
27
+ error: (message: string) => any;
28
+ progress: (percent: number) => any;
29
+ uploaded: (assetIds: string[]) => any;
30
+ "update:modelValue": (value: string[]) => any;
31
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
32
+ onError?: ((message: string) => any) | undefined;
33
+ onProgress?: ((percent: number) => any) | undefined;
34
+ onUploaded?: ((assetIds: string[]) => any) | undefined;
35
+ "onUpdate:modelValue"?: ((value: string[]) => any) | undefined;
36
+ }>, {
37
+ label: string;
38
+ uploadingLabel: string;
39
+ uploadedLabel: string;
40
+ processingLabel: string;
41
+ readyLabel: string;
42
+ errorLabel: string;
43
+ fileTypeErrorText: string;
44
+ fileTooLargeText: string;
45
+ fileTooSmallText: string;
46
+ uploadFailedText: string;
47
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
48
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
49
+ declare const _default: typeof __VLS_export;
50
+ export default _default;
51
+ type __VLS_WithSlots<T, S> = T & {
52
+ new (): {
53
+ $slots: S;
54
+ };
55
+ };
@@ -0,0 +1,211 @@
1
+ <script setup>
2
+ import { computed, onMounted, onUnmounted, ref } from "vue";
3
+ import { useMLChunkUploader, useMLResourcePolicy } from "../../index";
4
+ import { useMLProcessingStatus } from "../../composables/useMLProcessingStatus";
5
+ import { buildAcceptAttribute, isFileMimeAllowed } from "../../composables/resourcePolicy/mimeUtils";
6
+ defineOptions({ inheritAttrs: false });
7
+ const props = defineProps({
8
+ resourceType: { type: String, required: true },
9
+ collectionName: { type: [String, null], required: false },
10
+ chunkUploader: { type: [Object, String], required: false },
11
+ label: { type: String, required: false, default: "Upload" },
12
+ uploadingLabel: { type: String, required: false, default: "{percent}%" },
13
+ uploadedLabel: { type: String, required: false, default: "Uploaded" },
14
+ processingLabel: { type: String, required: false, default: "Processing\u2026" },
15
+ readyLabel: { type: String, required: false, default: "Ready" },
16
+ errorLabel: { type: String, required: false, default: "Error" },
17
+ fileTypeErrorText: { type: String, required: false, default: "File type is not allowed." },
18
+ fileTooLargeText: { type: String, required: false, default: "File is larger than the maximum allowed size." },
19
+ fileTooSmallText: { type: String, required: false, default: "File is smaller than the minimum allowed size." },
20
+ uploadFailedText: { type: String, required: false, default: "Upload failed." }
21
+ });
22
+ const model = defineModel({ type: Array, ...{ default: () => [] } });
23
+ const emit = defineEmits(["uploaded", "error", "progress"]);
24
+ const fileInput = ref(null);
25
+ const policy = ref(null);
26
+ const status = ref("idle");
27
+ const percent = ref(0);
28
+ const uploadedAssetId = ref(null);
29
+ const popoverOpen = ref(false);
30
+ const { track } = useMLProcessingStatus();
31
+ let processingStream = null;
32
+ let checkInterval = null;
33
+ const parsedChunkUploader = computed(() => {
34
+ if (!props.chunkUploader) return void 0;
35
+ if (typeof props.chunkUploader === "string") {
36
+ try {
37
+ return JSON.parse(props.chunkUploader);
38
+ } catch {
39
+ return void 0;
40
+ }
41
+ }
42
+ return props.chunkUploader;
43
+ });
44
+ const { uploadFile, abort } = useMLChunkUploader(parsedChunkUploader.value);
45
+ onMounted(async () => {
46
+ try {
47
+ const resourcePolicy = useMLResourcePolicy();
48
+ policy.value = await resourcePolicy.refreshByTypeCollection(
49
+ props.resourceType,
50
+ props.collectionName
51
+ );
52
+ } catch (err) {
53
+ console.error("Failed to load resource policy", err);
54
+ }
55
+ });
56
+ onUnmounted(() => {
57
+ processingStream?.close();
58
+ if (checkInterval) clearInterval(checkInterval);
59
+ });
60
+ const acceptTypes = computed(() => {
61
+ const allowed = policy.value?.file_constraints?.allowed_mime_types;
62
+ return allowed?.length ? buildAcceptAttribute(allowed) : void 0;
63
+ });
64
+ const isUploading = computed(() => status.value === "uploading");
65
+ const isProcessing = computed(() => status.value === "processing");
66
+ const showPopover = computed(
67
+ () => !!uploadedAssetId.value && (status.value === "processing" || status.value === "ready" || status.value === "error")
68
+ );
69
+ const currentLabel = computed(() => {
70
+ switch (status.value) {
71
+ case "uploading":
72
+ return props.uploadingLabel.replace("{percent}", percent.value.toFixed(0));
73
+ case "uploaded":
74
+ return props.uploadedLabel;
75
+ case "processing":
76
+ return props.processingLabel;
77
+ case "ready":
78
+ return props.readyLabel;
79
+ case "error":
80
+ return props.errorLabel;
81
+ default:
82
+ return props.label;
83
+ }
84
+ });
85
+ const buttonColor = computed(() => {
86
+ if (status.value === "ready") return "success";
87
+ if (status.value === "error") return "error";
88
+ if (status.value === "processing") return "warning";
89
+ return "primary";
90
+ });
91
+ const buttonIcon = computed(() => {
92
+ if (status.value === "processing") return "i-lucide-loader";
93
+ if (status.value === "ready") return "i-lucide-check";
94
+ if (status.value === "error") return "i-lucide-alert-circle";
95
+ return void 0;
96
+ });
97
+ const validateFile = (file) => {
98
+ const constraints = policy.value?.file_constraints;
99
+ if (!constraints) return null;
100
+ if (constraints.allowed_mime_types?.length) {
101
+ if (!isFileMimeAllowed(file, constraints.allowed_mime_types)) {
102
+ return props.fileTypeErrorText;
103
+ }
104
+ }
105
+ if (constraints.max_size_bytes != null && file.size > constraints.max_size_bytes) {
106
+ return props.fileTooLargeText;
107
+ }
108
+ if (constraints.min_size_bytes != null && file.size < constraints.min_size_bytes) {
109
+ return props.fileTooSmallText;
110
+ }
111
+ return null;
112
+ };
113
+ const triggerFileSelect = () => {
114
+ fileInput.value?.click();
115
+ };
116
+ const onPick = async (e) => {
117
+ const input = e.target;
118
+ const file = input?.files?.[0];
119
+ if (!file) return;
120
+ input.value = "";
121
+ if (!policy.value) {
122
+ status.value = "error";
123
+ emit("error", "Resource policy not loaded yet.");
124
+ return;
125
+ }
126
+ const validationError = validateFile(file);
127
+ if (validationError) {
128
+ status.value = "error";
129
+ emit("error", validationError);
130
+ return;
131
+ }
132
+ status.value = "uploading";
133
+ percent.value = 0;
134
+ try {
135
+ const res = await uploadFile(file, {
136
+ create: {
137
+ resource_type: props.resourceType,
138
+ collection_name: props.collectionName ?? null
139
+ },
140
+ onProgress(p) {
141
+ percent.value = p.percent;
142
+ emit("progress", p.percent);
143
+ },
144
+ onState(_s) {
145
+ }
146
+ });
147
+ const assetIds = Array.isArray(res?.finalize?.asset_ids) ? res.finalize.asset_ids : res?.finalize?.asset_id ? [res.finalize.asset_id] : [];
148
+ model.value = assetIds;
149
+ emit("uploaded", assetIds);
150
+ if (assetIds.length > 0) {
151
+ uploadedAssetId.value = assetIds[0];
152
+ status.value = "processing";
153
+ processingStream = track(assetIds[0]);
154
+ popoverOpen.value = true;
155
+ checkInterval = setInterval(() => {
156
+ if (processingStream?.isComplete.value) {
157
+ status.value = "ready";
158
+ if (checkInterval) clearInterval(checkInterval);
159
+ }
160
+ if (processingStream?.isFailed.value) {
161
+ status.value = "error";
162
+ if (checkInterval) clearInterval(checkInterval);
163
+ }
164
+ }, 500);
165
+ } else {
166
+ status.value = "uploaded";
167
+ }
168
+ } catch (err) {
169
+ status.value = "error";
170
+ emit("error", props.uploadFailedText);
171
+ }
172
+ };
173
+ </script>
174
+
175
+ <template>
176
+ <UPopover
177
+ v-if="showPopover"
178
+ v-model:open="popoverOpen"
179
+ mode="click"
180
+ :content="{ side: 'bottom', align: 'start', sideOffset: 8 }"
181
+ >
182
+ <UButton
183
+ v-bind="$attrs"
184
+ :loading="isUploading"
185
+ :label="currentLabel"
186
+ :color="buttonColor"
187
+ :icon="buttonIcon"
188
+ >
189
+ <slot />
190
+ </UButton>
191
+ <template #content>
192
+ <div class="w-96 max-h-112 overflow-y-auto p-1">
193
+ <MLProcessingPipeline
194
+ :asset-id="uploadedAssetId"
195
+ @complete="status = 'ready'"
196
+ @failed="status = 'error'"
197
+ />
198
+ </div>
199
+ </template>
200
+ </UPopover>
201
+ <UButton
202
+ v-else
203
+ v-bind="$attrs"
204
+ :loading="isUploading"
205
+ :label="currentLabel"
206
+ @click="triggerFileSelect"
207
+ >
208
+ <slot />
209
+ </UButton>
210
+ <input ref="fileInput" type="file" class="hidden" :accept="acceptTypes" @change="onPick" />
211
+ </template>
@@ -0,0 +1,55 @@
1
+ type __VLS_Props = {
2
+ resourceType: string;
3
+ collectionName?: string | null;
4
+ chunkUploader?: Record<string, any> | string;
5
+ label?: string;
6
+ uploadingLabel?: string;
7
+ uploadedLabel?: string;
8
+ processingLabel?: string;
9
+ readyLabel?: string;
10
+ errorLabel?: string;
11
+ fileTypeErrorText?: string;
12
+ fileTooLargeText?: string;
13
+ fileTooSmallText?: string;
14
+ uploadFailedText?: string;
15
+ };
16
+ type __VLS_ModelProps = {
17
+ modelValue?: string[];
18
+ };
19
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
20
+ declare var __VLS_13: {}, __VLS_32: {};
21
+ type __VLS_Slots = {} & {
22
+ default?: (props: typeof __VLS_13) => any;
23
+ } & {
24
+ default?: (props: typeof __VLS_32) => any;
25
+ };
26
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
27
+ error: (message: string) => any;
28
+ progress: (percent: number) => any;
29
+ uploaded: (assetIds: string[]) => any;
30
+ "update:modelValue": (value: string[]) => any;
31
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
32
+ onError?: ((message: string) => any) | undefined;
33
+ onProgress?: ((percent: number) => any) | undefined;
34
+ onUploaded?: ((assetIds: string[]) => any) | undefined;
35
+ "onUpdate:modelValue"?: ((value: string[]) => any) | undefined;
36
+ }>, {
37
+ label: string;
38
+ uploadingLabel: string;
39
+ uploadedLabel: string;
40
+ processingLabel: string;
41
+ readyLabel: string;
42
+ errorLabel: string;
43
+ fileTypeErrorText: string;
44
+ fileTooLargeText: string;
45
+ fileTooSmallText: string;
46
+ uploadFailedText: string;
47
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
48
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
49
+ declare const _default: typeof __VLS_export;
50
+ export default _default;
51
+ type __VLS_WithSlots<T, S> = T & {
52
+ new (): {
53
+ $slots: S;
54
+ };
55
+ };
@@ -0,0 +1,34 @@
1
+ import type { ResourcePolicyResponse } from "../../index.js";
2
+ type __VLS_Props = {
3
+ file: File;
4
+ resourceType: string;
5
+ collectionName?: string | null;
6
+ policy: ResourcePolicyResponse;
7
+ chunkUploader?: Record<string, any> | string;
8
+ noPreviewText?: string;
9
+ uploadedText?: string;
10
+ errorText?: string;
11
+ uploadingText?: string;
12
+ uploadFailedText?: string;
13
+ };
14
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
15
+ remove: () => any;
16
+ error: (message: string) => any;
17
+ progress: (percent: number) => any;
18
+ uploaded: (assetIds: string[]) => any;
19
+ canceled: () => any;
20
+ }, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
21
+ onRemove?: (() => any) | undefined;
22
+ onError?: ((message: string) => any) | undefined;
23
+ onProgress?: ((percent: number) => any) | undefined;
24
+ onUploaded?: ((assetIds: string[]) => any) | undefined;
25
+ onCanceled?: (() => any) | undefined;
26
+ }>, {
27
+ uploadFailedText: string;
28
+ noPreviewText: string;
29
+ uploadedText: string;
30
+ errorText: string;
31
+ uploadingText: string;
32
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
33
+ declare const _default: typeof __VLS_export;
34
+ export default _default;