- content_for :head do meta name="turbo-cache-control" content="no-cache" ruby: all_languages = Language.pluck(:code, :name).to_h asr_models = AsrModel.all model_mapping = asr_models.includes(:languages).each_with_object({}) { |m, h| h[m.value] = m.languages.pluck(:code) } translatable_models = asr_models.where(supports_translate: true).pluck(:value) model_options = asr_models.map { |m| [m.name, m.value] } = turbo_frame_tag "modal_frame", target: "_top" do div#respondentBulkPopup v-cloak="" data-controller="respondent-bulk-popup" data-languages="#{all_languages.to_json}" data-model-mapping="#{model_mapping.to_json}" data-translatable-models="#{translatable_models.to_json}" data-model-options="#{model_options.to_json}" data-project-id="#{@project.id}" data-respondent-category-id="#{@respondent_category.id}" .container h4 Upload multiple conversations div .form-group label.fs-12 Upload Files .file-upload-area :class="{ active: isDragging }" @dragover.prevent="dragOver" @dragleave.prevent="dragLeave" @drop.prevent="handleDrop" input type="file" name="files[]" multiple="multiple" accept="audio/*,video/*,.docx" class="form-control" @change="handleFileInput" ref="fileInput" .file-upload-content i.bi.bi-cloud-arrow-up.file-upload-icon h5 Drag & drop files here p.mb-1 or click to browse files small.text-muted Supported formats: Audio, Video, and Word documents (.docx) .file-list v-if="selectedFiles.length > 0" h6.mb-3 Selected Files ({{ selectedFiles.length }}) .file-list-item v-for="(file, index) in selectedFiles" :key="index" .file-details i.bi.bi-file-earmark.file-icon v-if="file.type.includes('application')" i.bi.bi-file-earmark-music.file-icon v-else-if="file.type.includes('audio')" i.bi.bi-camera-video.file-icon v-else-if="file.type.includes('video')" i.bi.bi-file-earmark.file-icon v-else="" .file-info .file-name-row span.file-name v-text="file.name" span.file-size v-text="formatFileSize(file.size)" i.bi.bi-x-circle.remove-file @click="removeFile(index)" v-if="!isUploading" // Progress bar and status for each file div v-if="uploadProgress.fileProgresses[index]" class="file-progress-section mt-2" .d-flex.align-items-center.mb-1 i :class="getFileStatusIcon(uploadProgress.fileProgresses[index].status)" class="me-2" small.text-muted span v-if="uploadProgress.fileProgresses[index].status === 'pending'" Waiting... span v-else-if="uploadProgress.fileProgresses[index].status === 'uploading'" | Uploading... {{ Math.round(uploadProgress.fileProgresses[index].progress) }}% span v-else-if="uploadProgress.fileProgresses[index].status === 'completed'" class="text-success" Completed span v-else-if="uploadProgress.fileProgresses[index].status === 'error'" class="text-danger" | Failed .progress v-if="uploadProgress.fileProgresses[index].status === 'uploading' || uploadProgress.fileProgresses[index].status === 'completed'" style="height: 4px;" .progress-bar.progress-bar-striped :class="{ 'progress-bar-animated bg-primary': uploadProgress.fileProgresses[index].status === 'uploading', 'bg-success': uploadProgress.fileProgresses[index].status === 'completed' }" role="progressbar" :style="'width: ' + uploadProgress.fileProgresses[index].progress + '%'" // Error message for failed files .alert.alert-danger.mt-1.py-1.px-2 v-if="uploadProgress.fileProgresses[index].status === 'error' && uploadProgress.fileProgresses[index].error" style="font-size: 0.75rem;" | {{ uploadProgress.fileProgresses[index].error }} - if current_user.organization.feature_enabled?(:model_selection) .form-group.mt-3 label.fs-12 Model select.form-control.border-0.bg-light.fs-12 name="model" v-model="selectedModel" :disabled="isUploading" option v-for="([label, value]) in visibleModelOptions" :value="value" v-text="label" .form-group.mt-3.dropdown-container label.fs-12 Audio Language select.form-control.border-0.bg-light.fs-12 name="language" v-model="selectedLanguage" :disabled="isUploading" option v-for="lang in availableLanguages" :value="lang.value" v-text="lang.text" .form-group.mt-3 v-show="translatableModels.includes(selectedModel)" .input-group.mb-2 label.fs-12.col-sm-2.col-form-label | Translate span.custom-tooltip i.ms-2.bi.bi-info-circle.tooltip-icon span.tooltip-text | The generated transcription will be in English .col-sm-10.form-switch.mt-1 input.form-check-input type="checkbox" name="translate" id="bulk_translate" role="switch" :disabled="isUploading" // Overall progress section when uploading div v-if="isUploading" class="mt-4 p-3 bg-light rounded" .d-flex.align-items-center.justify-content-between.mb-2 .fw-bold.text-primary i.bi.bi-upload.me-2 | Uploading Files... small.text-muted | {{ uploadProgress.completedFiles }}/{{ uploadProgress.totalFiles }} completed .mb-2 .progress style="height: 6px;" .progress-bar.progress-bar-striped.progress-bar-animated.bg-primary role="progressbar" :style="'width: ' + uploadProgress.overallProgress + '%'" .text-center small.text-muted | Overall Progress: {{ Math.round(uploadProgress.overallProgress) }}% - Please don't close this window .form-actions.mt-4 .d-flex.gap-2 button.btn.btn-primary type="button" @click="submitForm($event)" :disabled="isUploading || selectedFiles.length === 0 || uploadCompleted" i.bi.bi-cloud-upload-fill.me-2 v-if="isUploading" span v-if="isUploading" Uploading... span v-else-if="uploadCompleted" Upload Complete span v-else="" Upload {{ selectedFiles.length > 0 ? selectedFiles.length : '' }} {{ selectedFiles.length === 1 ? 'File' : 'Files' }} button.btn.btn-secondary type="button" @click="closeDialog" v-if="!isUploading" | Close - if @respondent_category.index_name.present? || @project.index_name.present? .d-flex.align-items-center.mt-3 i.bi.bi-exclamation-octagon.text-orange.fs-20 span.text-orange.ms-2 This will reset the assistant and the chats!