index.coffee 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. # app/components/Admin/FileUpload/index.coffee
  2. # Добавление стилей компонента
  3. if globalThis.stylFns and globalThis.stylFns['app/components/Admin/FileUpload/index.styl']
  4. styleElement = document.createElement('style')
  5. styleElement.type = 'text/css'
  6. styleElement.textContent = globalThis.stylFns['app/components/Admin/FileUpload/index.styl']
  7. document.head.appendChild(styleElement)
  8. else
  9. log '⚠️ Стили FileUpload не найдены'
  10. module.exports =
  11. name: 'file-upload'
  12. props:
  13. accept:
  14. type: String
  15. default: '.csv,.xlsx,.xls'
  16. multiple:
  17. type: Boolean
  18. default: false
  19. maxSize:
  20. type: Number
  21. default: 10485760 # 10MB
  22. data: ->
  23. {
  24. isDragging: false
  25. selectedFiles: []
  26. uploadProgress: 0
  27. isUploading: false
  28. }
  29. methods:
  30. onDragOver: (event) ->
  31. event.preventDefault()
  32. @isDragging = true
  33. onDragLeave: (event) ->
  34. event.preventDefault()
  35. @isDragging = false
  36. onDrop: (event) ->
  37. event.preventDefault()
  38. @isDragging = false
  39. files = Array.from(event.dataTransfer.files)
  40. @handleFiles(files)
  41. onFileSelect: (event) ->
  42. files = Array.from(event.target.files)
  43. @handleFiles(files)
  44. handleFiles: (files) ->
  45. validFiles = files.filter (file) =>
  46. if file.size > @maxSize
  47. @$emit('error', 'Файл '+file.name+' слишком большой. Максимальный размер: '+(@maxSize / 1048576)+'MB')
  48. return false
  49. if @accept and !@isFileTypeAccepted(file)
  50. @$emit('error', 'Файл '+file.name+' имеет недопустимый тип')
  51. return false
  52. return true
  53. if @multiple
  54. @selectedFiles = [...@selectedFiles, ...validFiles]
  55. else
  56. @selectedFiles = validFiles.slice(0, 1)
  57. @$emit('select', @selectedFiles)
  58. isFileTypeAccepted: (file) ->
  59. acceptTypes = @accept.split(',').map (type) -> type.trim()
  60. return acceptTypes.some (type) =>
  61. if type.startsWith('.')
  62. return file.name.toLowerCase().endsWith(type.toLowerCase())
  63. else
  64. return file.type.match(type)
  65. removeFile: (index) ->
  66. @selectedFiles.splice(index, 1)
  67. @$emit('select', @selectedFiles)
  68. uploadFiles: ->
  69. if @selectedFiles.length == 0
  70. @$emit('error', 'Нет файлов для загрузки')
  71. return
  72. @isUploading = true
  73. @uploadProgress = 0
  74. # Имитация загрузки с использованием Promise вместо async/await
  75. uploadSimulation = =>
  76. interval = setInterval (=>
  77. @uploadProgress += 10
  78. if @uploadProgress >= 100
  79. clearInterval(interval)
  80. @isUploading = false
  81. @$emit('upload', @selectedFiles)
  82. @selectedFiles = []
  83. ), 100
  84. uploadSimulation()
  85. getFileIcon: (file) ->
  86. if file.type.includes('spreadsheet') or file.name.includes('.csv')
  87. return '📊'
  88. else if file.type.includes('image')
  89. return '🖼️'
  90. else
  91. return '📄'
  92. render: (new Function '_ctx', '_cache', globalThis.renderFns['app/components/Admin/FileUpload/index.pug'])()