fix(uploader): register FilePond component at module level and restore proper dropzone styling
deploy-chabokan / deploy (push) Canceled after 0s

This commit is contained in:
2026-08-19 05:14:03 +03:30
parent ba54647837
commit cf7e1ee45c
+52 -75
View File
@@ -5,7 +5,7 @@
name="filepond-image" name="filepond-image"
:max-files="maxFiles" :max-files="maxFiles"
:allow-multiple="allowMultiple" :allow-multiple="allowMultiple"
:accepted-file-types="acceptedFileTypes" store-as-file="true"
:server="{ :server="{
process: { process: {
url: resolvedUploadUrl, url: resolvedUploadUrl,
@@ -20,37 +20,38 @@
withCredentials: true, withCredentials: true,
headers: authHeaders, headers: authHeaders,
onload: (response) => handleRevertResponse(response) onload: (response) => handleRevertResponse(response)
},
load: (source, load, error, progress, abort, headers) => {
fetch(source)
.then((res) => res.blob())
.then(load)
.catch((err) => {
console.warn('FilePond failed to load existing image:', source, err);
error(err.message);
});
} }
}" }"
:files="initialFiles" :label-idle="'برای آپلود کلیک کنید یا فایل را بکشید و رها کنید <span class=\'filepond--label-action\'>انتخاب فایل</span>'"
@removefile="handleRemoveFile"
label-idle="برای آپلود کلیک کنید یا فایل را بکشید و رها کنید"
label-tap-to-undo="برای حذف کلیک کنید" label-tap-to-undo="برای حذف کلیک کنید"
label-file-processing="در حال آپلود" label-file-processing="در حال آپلود..."
label-file-processing-complete="آپلود فایل تکمیل شد" label-file-processing-complete="آپلود فایل تکمیل شد"
@removefile="handleRemoveFile"
/> />
</div> </div>
</template> </template>
<script setup> <script>
import { ref, computed } from 'vue';
import Cookies from 'js-cookie';
import vueFilePond from 'vue-filepond'; import vueFilePond from 'vue-filepond';
import 'filepond/dist/filepond.min.css'; import 'filepond/dist/filepond.min.css';
import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css'; import 'filepond-plugin-image-preview/dist/filepond-plugin-image-preview.min.css';
import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type'; import FilePondPluginFileValidateType from 'filepond-plugin-file-validate-type';
import FilePondPluginImagePreview from 'filepond-plugin-image-preview'; import FilePondPluginImagePreview from 'filepond-plugin-image-preview';
// Define props // Create FilePond component at module level
const FilePond = vueFilePond(FilePondPluginFileValidateType, FilePondPluginImagePreview);
export default {
components: {
FilePond
}
};
</script>
<script setup>
import { ref, computed } from 'vue';
import Cookies from 'js-cookie';
const props = defineProps({ const props = defineProps({
bucketName: { bucketName: {
type: String, type: String,
@@ -95,16 +96,8 @@ const props = defineProps({
}); });
const emit = defineEmits(['update:modelValue', 'upload', 'uploaded', 'delete']); const emit = defineEmits(['update:modelValue', 'upload', 'uploaded', 'delete']);
// Define FilePond component
const FilePond = vueFilePond(FilePondPluginFileValidateType, FilePondPluginImagePreview);
const pond = ref(null); const pond = ref(null);
const acceptedFileTypes = computed(() => {
if (!props.acceptedFiles) return undefined;
return props.acceptedFiles.split(',').map((s) => s.trim());
});
const API_URL = (import.meta.env.VITE_API_URL || '').replace(/\/$/, ''); const API_URL = (import.meta.env.VITE_API_URL || '').replace(/\/$/, '');
const authHeaders = computed(() => { const authHeaders = computed(() => {
@@ -136,33 +129,6 @@ const resolvedDeleteUrl = computed(() => {
return `${API_URL}${cleanEndpoint}`; return `${API_URL}${cleanEndpoint}`;
}); });
const initialFiles = ref([]);
let isInitialLoaded = false;
watch(
() => props.modelValue,
(val) => {
// Only populate initialFiles on first load with existing items (e.g. edit mode)
// to avoid resetting active FilePond state during live uploads
if (!isInitialLoaded && Array.isArray(val) && val.length > 0) {
isInitialLoaded = true;
initialFiles.value = val
.map((item) => {
const url = typeof item === 'string' ? item : item.url || item.source || '';
if (!url) return null;
return {
source: url,
options: {
type: 'local'
}
};
})
.filter(Boolean);
}
},
{ immediate: true }
);
// Handle server responses for file processing // Handle server responses for file processing
function handleProcessResponse(response) { function handleProcessResponse(response) {
let parsed; let parsed;
@@ -249,39 +215,50 @@ function removeFromFileList(identifier) {
</script> </script>
<style> <style>
/* Apply dark mode styles to FilePond component */ /* FilePond Container & Theme Styling */
.image-uploader-wrapper {
width: 100%;
}
.filepond--root { .filepond--root {
font-family: 'Estedad FD', sans-serif; font-family: inherit;
background-color: var(--surface-ground); margin-bottom: 0 !important;
color: var(--text-color);
border-radius: 8px;
} }
.app-dark .filepond--root { .filepond--panel-root {
background-color: var(--code-background); border-radius: 0.75rem !important;
border-radius: 8px; background-color: var(--surface-100, #f1f5f9) !important;
border: 2px dashed var(--surface-300, #cbd5e1) !important;
transition: all 0.2s ease;
} }
.filepond--label { .app-dark .filepond--panel-root,
color: var(--text-color-secondary); .dark .filepond--panel-root {
background-color: var(--surface-800, #1e293b) !important;
border-color: var(--surface-700, #334155) !important;
} }
.app-dark .filepond--label { .filepond--drop-label {
color: var(--code-color); min-height: 5.5rem !important;
color: var(--text-color-secondary, #64748b) !important;
cursor: pointer;
font-size: 0.875rem !important;
} }
.app-dark .filepond--drop-label { .app-dark .filepond--drop-label,
background-color: var(--code-background); .dark .filepond--drop-label {
color: var(--code-color); color: var(--text-color-secondary, #94a3b8) !important;
border: 1px solid var(--surface-border); }
border-radius: 8px;
.filepond--label-action {
color: var(--primary-color, #10b981) !important;
font-weight: 600;
text-decoration: underline;
text-underline-offset: 3px;
} }
.filepond--item-panel { .filepond--item-panel {
background-color: var(--surface-card); background-color: var(--primary-color, #10b981) !important;
}
.app-dark .filepond--item-panel {
background-color: var(--code-background);
} }
</style> </style>