Skip to content

Commit

Permalink
feat: file uploader
Browse files Browse the repository at this point in the history
  • Loading branch information
shariquerik committed Oct 14, 2024
1 parent 068edf8 commit 3752d58
Show file tree
Hide file tree
Showing 6 changed files with 659 additions and 0 deletions.
18 changes: 18 additions & 0 deletions crm/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from frappe.translate import get_all_translations
from frappe.utils import validate_email_address, split_emails, cstr
from frappe.utils.telemetry import POSTHOG_HOST_FIELD, POSTHOG_PROJECT_FIELD
from frappe.core.api.file import get_max_file_size


@frappe.whitelist(allow_guest=True)
Expand Down Expand Up @@ -107,3 +108,20 @@ def invite_by_email(emails: str, role: str):

for email in to_invite:
frappe.get_doc(doctype="CRM Invitation", email=email, role=role).insert(ignore_permissions=True)


@frappe.whitelist()
def get_file_uploader_defaults(doctype: str):
max_number_of_files = None
make_attachments_public = False
if doctype:
meta = frappe.get_meta(doctype)
max_number_of_files = meta.get("max_attachments")
make_attachments_public = meta.get("make_attachments_public")

return {
'allowed_file_types': frappe.get_system_settings("allowed_file_extensions"),
'max_file_size': get_max_file_size(),
'max_number_of_files': max_number_of_files,
'make_attachments_public': bool(make_attachments_public),
}
152 changes: 152 additions & 0 deletions frontend/src/components/FilesUploader/FilesUploader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
<template>
<Dialog
v-model="show"
:options="{
title: __('Attach'),
size: 'xl',
}"
>
<template #body-content>
<FilesUploaderArea
v-model="files"
:doctype="doctype"
:options="options"
/>
</template>
<template #actions>
<div class="flex justify-between">
<div>
<Button
v-if="files.length"
variant="subtle"
:label="__('Remove all')"
:disabled="fileUploadStarted"
@click="removeAllFiles"
/>
</div>
<div class="flex gap-2">
<Button
v-if="isAllPrivate && files.length"
variant="subtle"
:label="__('Set all as public')"
:disabled="fileUploadStarted"
@click="setAllPublic"
/>
<Button
v-else-if="files.length"
variant="subtle"
:label="__('Set all as private')"
:disabled="fileUploadStarted"
@click="setAllPrivate"
/>
<Button
variant="solid"
:loading="fileUploadStarted"
:disabled="!files.length"
@click="attachFiles"
:label="__('Attach')"
/>
</div>
</div>
</template>
</Dialog>
</template>

<script setup>
import FilesUploaderArea from '@/components/FilesUploader/FilesUploaderArea.vue'
import FilesUploadHandler from './filesUploaderHandler'
import { ref, computed } from 'vue'
const props = defineProps({
doctype: {
type: String,
required: true,
},
docname: {
type: String,
required: true,
},
options: {
type: Object,
default: () => ({
folder: 'Home/Attachments',
}),
},
})
const show = defineModel()
const files = ref([])
const isAllPrivate = computed(() => files.value.every((a) => a.private))
function setAllPrivate() {
files.value.forEach((file) => (file.private = true))
}
function setAllPublic() {
files.value.forEach((file) => (file.private = false))
}
function removeAllFiles() {
files.value = []
}
function attachFiles() {
files.value.forEach((file, i) => attachFile(file, i))
}
const uploader = ref(null)
const fileUploadStarted = ref(false)
function attachFile(file, i) {
const args = {
file: file?.fileObj || {},
type: file.type,
private: file.private,
fileUrl: file.fileUrl,
folder: props.options.folder,
doctype: props.doctype,
docname: props.docname,
}
uploader.value = new FilesUploadHandler()
uploader.value.on('start', () => {
file.uploading = true
fileUploadStarted.value = true
})
uploader.value.on('progress', (data) => {
file.uploaded = data.uploaded
file.total = data.total
})
uploader.value.on('error', (error) => {
file.uploading = false
file.errorMessage = error || 'Error Uploading File'
})
uploader.value.on('finish', () => {
file.uploading = false
})
uploader.value
.upload(file, args || {})
.then(() => {
if (i === files.value.length - 1) {
files.value = []
show.value = false
fileUploadStarted.value = false
}
})
.catch((error) => {
file.uploading = false
let errorMessage = 'Error Uploading File'
if (error?._server_messages) {
errorMessage = JSON.parse(JSON.parse(error._server_messages)[0]).message
} else if (error?.exc) {
errorMessage = JSON.parse(error.exc)[0].split('\n').slice(-2, -1)[0]
} else if (typeof error === 'string') {
errorMessage = error
}
file.errorMessage = errorMessage
})
}
</script>
Loading

0 comments on commit 3752d58

Please sign in to comment.