From 90d2293cfda19cf427baabe76564cbabd2d6d55e Mon Sep 17 00:00:00 2001 From: mutantsan Date: Wed, 3 Jul 2024 14:20:12 +0300 Subject: [PATCH] add display_snippet, add separate progress bar, implement mass upload, update media gallery etc --- .../file_upload_widget/assets/css/styles.css | 169 +----------------- .../assets/js/file-upload-widget.js | 167 ++++++++++++++--- ckanext/file_upload_widget/helpers.py | 8 - .../display_snippets/files_upload_widget.html | 14 ++ .../form_snippets/files_upload_widget.html | 24 +-- ckanext/file_upload_widget/theme/styles.scss | 7 +- 6 files changed, 167 insertions(+), 222 deletions(-) create mode 100644 ckanext/file_upload_widget/templates/scheming/display_snippets/files_upload_widget.html diff --git a/ckanext/file_upload_widget/assets/css/styles.css b/ckanext/file_upload_widget/assets/css/styles.css index 38c508a..a620d8c 100644 --- a/ckanext/file_upload_widget/assets/css/styles.css +++ b/ckanext/file_upload_widget/assets/css/styles.css @@ -1,168 +1 @@ -.file-upload-widget .fuw-main-window { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - text-align: center; - width: 100%; -} -.file-upload-widget .fuw-main-window .fuw-or { - margin: 1rem 0; -} -.file-upload-widget .fuw-main-window .fuw-main-window__dropzone { - padding: 2rem; - border-radius: 0.5rem; - border: 2px dashed #ccc; - width: 100%; -} -.file-upload-widget .fuw-main-window .fuw-main-window__dropzone.active { - border-color: black; -} -.file-upload-widget .fuw-main-window .fuw-main-window__alternative label.btn-file-input:after { - display: none; -} -.file-upload-widget .fuw-url-input { - width: 100%; -} -.file-upload-widget .fuw-media-input { - width: 100%; -} -.file-upload-widget .fuw-media-input .search-input { - margin-bottom: 1rem; - position: relative; -} -.file-upload-widget .fuw-media-input .search-input input { - padding-left: 2rem; -} -.file-upload-widget .fuw-media-input .search-input .input-group-btn { - position: absolute; - left: 10px; - top: 10px; -} -.file-upload-widget .fuw-media-input .search-input .input-group-btn i { - color: #6c757d; -} -.file-upload-widget .fuw-media-input .fuw-media-input--files { - display: flex; - flex-direction: column; - padding: 0; - border-radius: 0.5rem; - height: 250px; - overflow-y: scroll; -} -.file-upload-widget .fuw-media-input .fuw-media-input--files .files--file-item { - display: flex; - padding: 7px 15px; - gap: 1rem; -} -.file-upload-widget .fuw-media-input .fuw-media-input--files .files--file-item label { - display: flex; - align-items: center; - gap: 0.5rem; - width: 100%; -} -.file-upload-widget .fuw-media-input .fuw-media-input--files .files--file-item label:after { - display: none; -} -.file-upload-widget .fuw-media-input .fuw-media-input--files .files--file-item label .highlight { - background-color: yellow; -} -.file-upload-widget .fuw-media-input .fuw-media-input--empty { - align-items: center; - color: #939393; - display: flex; - height: 250px; - flex: 1; - flex-flow: column wrap; - justify-content: center; -} -.file-upload-widget .fuw-selected-files { - position: absolute; -} -.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list { - width: 100%; - height: 310px; - overflow-y: scroll; - padding-right: 1rem; - padding-top: 1rem; -} -.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list li.fuw-selected-files--file-item-wrapper { - display: flex; - align-items: center; - gap: 0.5rem; - border-bottom: 1px solid #eaeaea; - padding: 0.5rem 0; - position: relative; -} -.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list li.fuw-selected-files--file-item-wrapper .fuw-selected-files--file-preview { - height: 50px; - width: 50px; - position: relative; - background: aliceblue; - box-shadow: 0 1px 2px rgba(119, 119, 119, 0.4588235294); - border-radius: 3px; - display: flex; - flex-direction: column; - justify-content: center; -} -.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list li.fuw-selected-files--file-item-wrapper .fuw-selected-files--file-preview .file-tile--file-icon { - display: flex; - align-items: center; - justify-content: center; -} -.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list li.fuw-selected-files--file-item-wrapper .fuw-selected-files--file-info .fuw-selected-files--file-name { - -webkit-font-smoothing: antialiased; - word-wrap: anywhere; - font-size: 1rem; - font-weight: bold; - line-height: 1.3; - word-break: break-all; -} -.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list li.fuw-selected-files--file-item-wrapper .fuw-selected-files--file-info .fuw-selected-files--file-size { - font-size: 0.8rem; - color: #757575; - font-weight: 400; - line-height: 1; -} -.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list li.fuw-selected-files--file-item-wrapper .file-tile--file-remove, -.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list li.fuw-selected-files--file-item-wrapper .file-tile--file-upload { - cursor: pointer; - position: absolute; - right: 0; - background: black; - color: white; - border: 1px solid black; - border-radius: 50%; - width: 25px; - height: 25px; - display: flex; - align-items: center; - justify-content: center; -} -.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list li.fuw-selected-files--file-item-wrapper .file-tile--file-upload { - right: 30px; -} -.file-upload-widget .fuw-cancel-btn, -.file-upload-widget .fuw-close-selected-btn { - cursor: pointer; -} -.file-upload-widget .hidden { - display: none !important; -} -.file-upload-widget .modal .modal-header { - gap: 0.5rem; -} -.file-upload-widget .modal .modal-body { - min-height: 145px; - display: flex; - align-items: center; - justify-content: center; - flex-direction: column; -} -.file-upload-widget .modal .modal-inner-footer { - padding: 0.75rem 0 0 0; -} -.file-upload-widget.form-group .btn { - position: static; -} -/*# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInN0eWxlcy5zY3NzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUlJO0VBQ0k7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOztBQUVBO0VBQ0k7O0FBR0o7RUFDSTtFQUNBO0VBQ0E7RUFDQTs7QUFFQTtFQUNJOztBQU1BO0VBQ0k7O0FBTWhCO0VBQ0k7O0FBR0o7RUFDSTs7QUFFQTtFQUNJO0VBQ0E7O0FBRUE7RUFDSTs7QUFHSjtFQUNJO0VBQ0E7RUFDQTs7QUFFQTtFQUNJOztBQUtaO0VBQ0k7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOztBQUVBO0VBQ0k7RUFDQTtFQUNBOztBQUVBO0VBQ0k7RUFDQTtFQUNBO0VBQ0E7O0FBRUE7RUFDSTs7QUFHSjtFQUNJOztBQU1oQjtFQUNJO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOztBQUlSO0VBQ0k7O0FBRUE7RUFDSTtFQUNBO0VBQ0E7RUFDQTtFQUNBOztBQUVBO0VBQ0k7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOztBQUVBO0VBQ0k7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOztBQUVBO0VBQ0k7RUFDQTtFQUNBOztBQUtKO0VBQ0k7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBOztBQUdKO0VBQ0k7RUFDQTtFQUNBO0VBQ0E7O0FBSVI7QUFBQTtFQUVJO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTtFQUNBO0VBQ0E7RUFDQTs7QUFHSjtFQUNJOztBQU1oQjtBQUFBO0VBRUk7O0FBR0o7RUFDSTs7QUFJQTtFQUNJOztBQUVKO0VBQ0k7RUFDQTtFQUNBO0VBQ0E7RUFDQTs7QUFHSjtFQUNJOztBQUlSO0VBQ0kiLCJmaWxlIjoic3R5bGVzLmNzcyIsInNvdXJjZXNDb250ZW50IjpbIkBpbXBvcnQgXCJ2YXJpYWJsZXNcIjtcbkBpbXBvcnQgXCJtaXhpbnNcIjtcblxuLmZpbGUtdXBsb2FkLXdpZGdldCB7XG4gICAgLmZ1dy1tYWluLXdpbmRvdyB7XG4gICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgICB0ZXh0LWFsaWduOiBjZW50ZXI7XG4gICAgICAgIHdpZHRoOiAxMDAlO1xuXG4gICAgICAgIC5mdXctb3Ige1xuICAgICAgICAgICAgbWFyZ2luOiAxcmVtIDA7XG4gICAgICAgIH1cblxuICAgICAgICAuZnV3LW1haW4td2luZG93X19kcm9wem9uZSB7XG4gICAgICAgICAgICBwYWRkaW5nOiAycmVtO1xuICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMC41cmVtO1xuICAgICAgICAgICAgYm9yZGVyOiAycHggZGFzaGVkICNjY2M7XG4gICAgICAgICAgICB3aWR0aDogMTAwJTtcblxuICAgICAgICAgICAgJi5hY3RpdmUge1xuICAgICAgICAgICAgICAgIGJvcmRlci1jb2xvcjogYmxhY2s7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAuZnV3LW1haW4td2luZG93X19hbHRlcm5hdGl2ZSB7XG4gICAgICAgICAgICBsYWJlbC5idG4tZmlsZS1pbnB1dCB7XG4gICAgICAgICAgICAgICAgJjphZnRlciB7XG4gICAgICAgICAgICAgICAgICAgIGRpc3BsYXk6IG5vbmU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLmZ1dy11cmwtaW5wdXQge1xuICAgICAgICB3aWR0aDogMTAwJTtcbiAgICB9XG5cbiAgICAuZnV3LW1lZGlhLWlucHV0IHtcbiAgICAgICAgd2lkdGg6IDEwMCU7XG5cbiAgICAgICAgLnNlYXJjaC1pbnB1dCB7XG4gICAgICAgICAgICBtYXJnaW4tYm90dG9tOiAxcmVtO1xuICAgICAgICAgICAgcG9zaXRpb246IHJlbGF0aXZlO1xuXG4gICAgICAgICAgICBpbnB1dCB7XG4gICAgICAgICAgICAgICAgcGFkZGluZy1sZWZ0OiAycmVtO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAuaW5wdXQtZ3JvdXAtYnRuIHtcbiAgICAgICAgICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG4gICAgICAgICAgICAgICAgbGVmdDogMTBweDtcbiAgICAgICAgICAgICAgICB0b3A6IDEwcHg7XG5cbiAgICAgICAgICAgICAgICBpIHtcbiAgICAgICAgICAgICAgICAgICAgY29sb3I6ICM2Yzc1N2Q7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLmZ1dy1tZWRpYS1pbnB1dC0tZmlsZXMge1xuICAgICAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgICAgICBwYWRkaW5nOiAwO1xuICAgICAgICAgICAgYm9yZGVyLXJhZGl1czogMC41cmVtO1xuICAgICAgICAgICAgaGVpZ2h0OiAyNTBweDtcbiAgICAgICAgICAgIG92ZXJmbG93LXk6IHNjcm9sbDtcblxuICAgICAgICAgICAgLmZpbGVzLS1maWxlLWl0ZW0ge1xuICAgICAgICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgICAgICAgICAgcGFkZGluZzogN3B4IDE1cHg7XG4gICAgICAgICAgICAgICAgZ2FwOiAxcmVtO1xuXG4gICAgICAgICAgICAgICAgbGFiZWwge1xuICAgICAgICAgICAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICAgICAgICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgICAgICAgICAgICAgICBnYXA6IDAuNXJlbTtcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6IDEwMCU7XG5cbiAgICAgICAgICAgICAgICAgICAgJjphZnRlciB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5OiBub25lO1xuICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgLmhpZ2hsaWdodCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBiYWNrZ3JvdW5kLWNvbG9yOiB5ZWxsb3c7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAuZnV3LW1lZGlhLWlucHV0LS1lbXB0eSB7XG4gICAgICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgICAgICAgY29sb3I6ICM5MzkzOTM7XG4gICAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICAgICAgaGVpZ2h0OiAyNTBweDtcbiAgICAgICAgICAgIGZsZXg6IDE7XG4gICAgICAgICAgICBmbGV4LWZsb3c6IGNvbHVtbiB3cmFwO1xuICAgICAgICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXJcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC5mdXctc2VsZWN0ZWQtZmlsZXMge1xuICAgICAgICBwb3NpdGlvbjogYWJzb2x1dGU7XG5cbiAgICAgICAgdWwuZnV3LXNlbGVjdGVkLWZpbGVzLS1saXN0IHtcbiAgICAgICAgICAgIHdpZHRoOiAxMDAlO1xuICAgICAgICAgICAgaGVpZ2h0OiAzMTBweDtcbiAgICAgICAgICAgIG92ZXJmbG93LXk6IHNjcm9sbDtcbiAgICAgICAgICAgIHBhZGRpbmctcmlnaHQ6IDFyZW07XG4gICAgICAgICAgICBwYWRkaW5nLXRvcDogMXJlbTtcblxuICAgICAgICAgICAgbGkuZnV3LXNlbGVjdGVkLWZpbGVzLS1maWxlLWl0ZW0td3JhcHBlciB7XG4gICAgICAgICAgICAgICAgZGlzcGxheTogZmxleDtcbiAgICAgICAgICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgICAgICAgICAgIGdhcDogMC41cmVtO1xuICAgICAgICAgICAgICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjZWFlYWVhO1xuICAgICAgICAgICAgICAgIHBhZGRpbmc6IDAuNXJlbSAwO1xuICAgICAgICAgICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcblxuICAgICAgICAgICAgICAgIC5mdXctc2VsZWN0ZWQtZmlsZXMtLWZpbGUtcHJldmlldyB7XG4gICAgICAgICAgICAgICAgICAgIGhlaWdodDogNTBweDtcbiAgICAgICAgICAgICAgICAgICAgd2lkdGg6IDUwcHg7XG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcbiAgICAgICAgICAgICAgICAgICAgYmFja2dyb3VuZDogYWxpY2VibHVlO1xuICAgICAgICAgICAgICAgICAgICBib3gtc2hhZG93OiAwIDFweCAycHggIzc3Nzc3Nzc1O1xuICAgICAgICAgICAgICAgICAgICBib3JkZXItcmFkaXVzOiAzcHg7XG4gICAgICAgICAgICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgICAgICAgICAgICAgIGZsZXgtZGlyZWN0aW9uOiBjb2x1bW47XG4gICAgICAgICAgICAgICAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuXG4gICAgICAgICAgICAgICAgICAgIC5maWxlLXRpbGUtLWZpbGUtaWNvbiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBkaXNwbGF5OiBmbGV4O1xuICAgICAgICAgICAgICAgICAgICAgICAgYWxpZ24taXRlbXM6IGNlbnRlcjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLmZ1dy1zZWxlY3RlZC1maWxlcy0tZmlsZS1pbmZvIHtcbiAgICAgICAgICAgICAgICAgICAgLmZ1dy1zZWxlY3RlZC1maWxlcy0tZmlsZS1uYW1lIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIC13ZWJraXQtZm9udC1zbW9vdGhpbmc6IGFudGlhbGlhc2VkO1xuICAgICAgICAgICAgICAgICAgICAgICAgd29yZC13cmFwOiBhbnl3aGVyZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnQtc2l6ZTogMXJlbTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvbnQtd2VpZ2h0OiBib2xkO1xuICAgICAgICAgICAgICAgICAgICAgICAgbGluZS1oZWlnaHQ6IDEuMztcbiAgICAgICAgICAgICAgICAgICAgICAgIHdvcmQtYnJlYWs6IGJyZWFrLWFsbDtcbiAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgIC5mdXctc2VsZWN0ZWQtZmlsZXMtLWZpbGUtc2l6ZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb250LXNpemU6IDAuOHJlbTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbG9yOiAjNzU3NTc1O1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9udC13ZWlnaHQ6IDQwMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxpbmUtaGVpZ2h0OiAxO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLmZpbGUtdGlsZS0tZmlsZS1yZW1vdmUsXG4gICAgICAgICAgICAgICAgLmZpbGUtdGlsZS0tZmlsZS11cGxvYWQge1xuICAgICAgICAgICAgICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XG4gICAgICAgICAgICAgICAgICAgIHBvc2l0aW9uOiBhYnNvbHV0ZTtcbiAgICAgICAgICAgICAgICAgICAgcmlnaHQ6IDA7XG4gICAgICAgICAgICAgICAgICAgIGJhY2tncm91bmQ6IGJsYWNrO1xuICAgICAgICAgICAgICAgICAgICBjb2xvcjogd2hpdGU7XG4gICAgICAgICAgICAgICAgICAgIGJvcmRlcjogMXB4IHNvbGlkIGJsYWNrO1xuICAgICAgICAgICAgICAgICAgICBib3JkZXItcmFkaXVzOiA1MCU7XG4gICAgICAgICAgICAgICAgICAgIHdpZHRoOiAyNXB4O1xuICAgICAgICAgICAgICAgICAgICBoZWlnaHQ6IDI1cHg7XG4gICAgICAgICAgICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgICAgICAgICAgICAgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XG4gICAgICAgICAgICAgICAgICAgIGp1c3RpZnktY29udGVudDogY2VudGVyO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC5maWxlLXRpbGUtLWZpbGUtdXBsb2FkIHtcbiAgICAgICAgICAgICAgICAgICAgcmlnaHQ6IDMwcHg7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgLmZ1dy1jYW5jZWwtYnRuLFxuICAgIC5mdXctY2xvc2Utc2VsZWN0ZWQtYnRuIHtcbiAgICAgICAgY3Vyc29yOiBwb2ludGVyO1xuICAgIH1cblxuICAgIC5oaWRkZW4ge1xuICAgICAgICBkaXNwbGF5OiBub25lICFpbXBvcnRhbnQ7XG4gICAgfVxuXG4gICAgLm1vZGFsIHtcbiAgICAgICAgLm1vZGFsLWhlYWRlciB7XG4gICAgICAgICAgICBnYXA6IDAuNXJlbTtcbiAgICAgICAgfVxuICAgICAgICAubW9kYWwtYm9keSB7XG4gICAgICAgICAgICBtaW4taGVpZ2h0OiAxNDVweDtcbiAgICAgICAgICAgIGRpc3BsYXk6IGZsZXg7XG4gICAgICAgICAgICBhbGlnbi1pdGVtczogY2VudGVyO1xuICAgICAgICAgICAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XG4gICAgICAgICAgICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1xuICAgICAgICB9XG5cbiAgICAgICAgLm1vZGFsLWlubmVyLWZvb3RlciB7XG4gICAgICAgICAgICBwYWRkaW5nOiAwLjc1cmVtIDAgMCAwO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgJi5mb3JtLWdyb3VwIC5idG4ge1xuICAgICAgICBwb3NpdGlvbjogc3RhdGljO1xuICAgIH1cbn1cbiJdfQ== */ +.file-upload-widget .fuw-main-window{display:flex;flex-direction:column;justify-content:center;align-items:center;text-align:center;width:100%}.file-upload-widget .fuw-main-window .fuw-or{margin:1rem 0}.file-upload-widget .fuw-main-window .fuw-main-window__dropzone{padding:2rem;border-radius:.5rem;border:2px dashed #ccc;width:100%}.file-upload-widget .fuw-main-window .fuw-main-window__dropzone.active{border-color:#000}.file-upload-widget .fuw-main-window .fuw-main-window__alternative label.btn-file-input:after{display:none}.file-upload-widget .fuw-url-input{width:100%}.file-upload-widget .fuw-media-input{width:100%}.file-upload-widget .fuw-media-input .search-input{margin-bottom:1rem;position:relative}.file-upload-widget .fuw-media-input .search-input input{padding-left:2rem}.file-upload-widget .fuw-media-input .search-input .input-group-btn{position:absolute;left:10px;top:10px}.file-upload-widget .fuw-media-input .search-input .input-group-btn i{color:#6c757d}.file-upload-widget .fuw-media-input .fuw-media-input--files{display:flex;flex-direction:column;padding:0;border-radius:.5rem;height:250px;overflow-y:scroll}.file-upload-widget .fuw-media-input .fuw-media-input--files .files--file-item{display:flex;padding:7px 15px;gap:1rem}.file-upload-widget .fuw-media-input .fuw-media-input--files .files--file-item label{display:flex;align-items:center;gap:.5rem;width:100%}.file-upload-widget .fuw-media-input .fuw-media-input--files .files--file-item label:after{display:none}.file-upload-widget .fuw-media-input .fuw-media-input--files .files--file-item label .highlight{background-color:#ff0}.file-upload-widget .fuw-media-input .fuw-media-input--empty{align-items:center;color:#939393;display:flex;height:250px;flex:1;flex-flow:column wrap;justify-content:center}.file-upload-widget .fuw-selected-files{position:absolute}.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list{width:100%;height:310px;overflow-y:scroll;padding-right:1rem}.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list li.fuw-selected-files--file-item-wrapper{display:flex;align-items:center;gap:.5rem;border-bottom:1px solid #eaeaea;padding:.5rem 0;position:relative}.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list li.fuw-selected-files--file-item-wrapper .fuw-selected-files--file-preview{height:50px;width:50px;position:relative;background:#f0f8ff;box-shadow:0 1px 2px rgba(119,119,119,.4588235294);border-radius:3px;display:flex;flex-direction:column;justify-content:center}.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list li.fuw-selected-files--file-item-wrapper .fuw-selected-files--file-preview .file-tile--file-icon{display:flex;align-items:center;justify-content:center}.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list li.fuw-selected-files--file-item-wrapper .fuw-selected-files--file-info .fuw-selected-files--file-name{-webkit-font-smoothing:antialiased;word-wrap:anywhere;font-size:1rem;font-weight:bold;line-height:1.3;word-break:break-all}.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list li.fuw-selected-files--file-item-wrapper .fuw-selected-files--file-info .fuw-selected-files--file-size{font-size:.8rem;color:#757575;font-weight:400;line-height:1}.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list li.fuw-selected-files--file-item-wrapper .file-tile--file-remove,.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list li.fuw-selected-files--file-item-wrapper .file-tile--file-upload{cursor:pointer;position:absolute;right:0;background:#000;color:#fff;border:1px solid #000;border-radius:50%;width:25px;height:25px;display:flex;align-items:center;justify-content:center}.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list li.fuw-selected-files--file-item-wrapper .file-tile--file-upload{right:30px}.file-upload-widget .fuw-selected-files ul.fuw-selected-files--list .fuw-selected-files--progress{position:absolute;bottom:0;width:100%}.file-upload-widget .fuw-cancel-btn,.file-upload-widget .fuw-close-selected-btn{cursor:pointer}.file-upload-widget .hidden{display:none !important}.file-upload-widget .modal .modal-header{gap:.5rem}.file-upload-widget .modal .modal-body{min-height:145px;display:flex;align-items:center;justify-content:center;flex-direction:column}.file-upload-widget .modal .modal-inner-footer{padding:.75rem 0 0 0}.file-upload-widget.form-group .btn{position:static} \ No newline at end of file diff --git a/ckanext/file_upload_widget/assets/js/file-upload-widget.js b/ckanext/file_upload_widget/assets/js/file-upload-widget.js index 23b2e0d..b74ba9a 100644 --- a/ckanext/file_upload_widget/assets/js/file-upload-widget.js +++ b/ckanext/file_upload_widget/assets/js/file-upload-widget.js @@ -46,8 +46,11 @@ ckan.module("file-upload-widget", function ($, _) { mediaSelectBtn: '.fuw-media-select-btn', dropZone: '.fuw-main-window__dropzone', selectedFiles: '.fuw-selected-files--list', + mediaFilesContainer: '.fuw-media-input--files', + mediaFilesEmptyContainer: '.fuw-media-input--empty', mediaWindowFooter: '.modal-footer--media', selectedFileItem: 'li.fuw-selected-file', + fileProgressContainer: '.fuw-selected-files--progress', attrFileName: 'fuw-file-name', attrFileId: 'fuw-file-id', @@ -72,6 +75,8 @@ ckan.module("file-upload-widget", function ($, _) { return }; + window.fuwProgressBars = window.fuwProgressBars || {}; + this.fileAdapter = new ckan.CKANEXT_FILES.adapters.Standard(); this.urlAdapter = new ckan.CKANEXT_FILES.adapters.Standard({ "storage": "link" @@ -99,6 +104,8 @@ ckan.module("file-upload-widget", function ($, _) { this.fileInput = this.el.find('input[type="file"]'); this.selectedFilesContainer = this.el.find(this.const.selectedFiles); this.urlImportBtn = this.urlWindow.find(".btn-url-import"); + this.mediaFilesContainer = this.el.find(this.const.mediaFilesContainer); + this.mediaFilesEmptyContainer = this.el.find(this.const.mediaFilesEmptyContainer); this.cancelBtn = this.el.find(this.const.cancelBtn); this.discardBtn = this.el.find(this.const.discardBtn); @@ -126,6 +133,8 @@ ckan.module("file-upload-widget", function ($, _) { this.urlAdapter.addEventListener("progress", this._onUploadProgress); this.fileAdapter.addEventListener("finish", this._onFinishUpload); this.urlAdapter.addEventListener("finish", this._onFinishUpload); + this.fileAdapter.addEventListener("fail", this._onFailUpload); + this.urlAdapter.addEventListener("fail", this._onFailUpload); // Bind events on non existing elements $("body").on("click", ".file-tile--file-remove", this._onRemoveSelectedFile); @@ -133,25 +142,20 @@ ckan.module("file-upload-widget", function ($, _) { // Dropzone events this.dropZoneArea.on("drop", this._onDropFile); - - // Prevent default drag behaviors - ; ["dragenter", "dragover", "dragleave", "drop"].forEach(eventName => { this.dropZoneArea.on(eventName, this._preventDropDefaults) $(document.body).on(eventName, this._preventDropDefaults) }); - - // Highlight drop area when item is dragged over it - ; ["dragenter", "dragover"].forEach(eventName => { this.dropZoneArea.on(eventName, this._highlightDropZone) }); - - // Unhighlight drop area when item is dragged out of it - ; ["dragleave", "drop"].forEach(eventName => { this.dropZoneArea.on(eventName, this._unhighlightDropZone) }) + + // ON INIT + this._recreateSelectedFiles(); + this._updateMediaGallery(); }, /** @@ -259,10 +263,10 @@ ckan.module("file-upload-widget", function ($, _) { if (isEmpty && !visibleFilesNum) { this.el.find(".fuw-media-input--empty").showEl(); - this.el.find(".fuw-media-input--files").hideEl(); + this.mediaFilesContainer.hideEl(); } else { this.el.find(".fuw-media-input--empty").hideEl(); - this.el.find(".fuw-media-input--files").showEl(); + this.mediaFilesContainer.showEl(); } }, @@ -380,7 +384,6 @@ ckan.module("file-upload-widget", function ($, _) { }, _onFileSelected: function (e) { - console.log(e); Array.from(e.target.files).forEach(file => { file.id = generateUUID4(); file.fuw_type = this.const.type.file; @@ -412,7 +415,7 @@ ckan.module("file-upload-widget", function ($, _) { this._disableUrlWindow(); this._disableMediaWindow(); - this._toggleSelectedFilesButton(1); + this._toggleSelectedFilesButton(); this.selectionWindow.showEl(); }, @@ -512,7 +515,7 @@ ckan.module("file-upload-widget", function ($, _) { let selectedFiles = this._calculateSelectedFilesNum() > 0; this._toggleFileSelectionWindow(selectedFiles); - this._toggleSelectedFilesButton(selectedFiles); + this._toggleSelectedFilesButton(); this._updateFileIdsInput(); }, @@ -529,8 +532,11 @@ ckan.module("file-upload-widget", function ($, _) { } }, - _toggleSelectedFilesButton: function (flag) { - this.openSelectedFilesBtn.toggleEl(flag); + _toggleSelectedFilesButton: function (fileNum = null) { + let selectedFiles = fileNum ? fileNum : this._calculateSelectedFilesNum(); + + this.openSelectedFilesBtn.find("span").text(selectedFiles); + this.openSelectedFilesBtn.toggleEl(selectedFiles); }, _onUploadSelectedFile: function (e) { @@ -551,11 +557,12 @@ ckan.module("file-upload-widget", function ($, _) { _uploadFile(fileItem) { let fileType = fileItem.attr(this.const.attrFileType); let fileId = fileItem.attr(this.const.attrFileId); + let fileProgressContainer = fileItem.find(this.const.fileProgressContainer); - this.uploadBar = new ProgressBar.Line('.upload-progress-bar', { + window.fuwProgressBars[fileId] = new ProgressBar.Line(fileProgressContainer.get(0), { easing: 'easeInOut' - }); - this.uploadBar.animate(0); + }) + window.fuwProgressBars[fileId].animate(0); if (fileType === this.const.type.url) { let url = fileItem.attr(this.const.attrFileName); @@ -582,8 +589,6 @@ ckan.module("file-upload-widget", function ($, _) { this.fileAdapter.upload(file, {}) } - - this._updateFileIdsInput(); }, /** @@ -659,6 +664,7 @@ ckan.module("file-upload-widget", function ($, _) { ${!fileUploaded ? '' : ""} +
` }, @@ -672,7 +678,7 @@ ckan.module("file-upload-widget", function ($, _) { this.el.find(this.const.selectedFileItem).remove(); this._onCloseSelectedFiles(); - this._toggleSelectedFilesButton(0); + this._toggleSelectedFilesButton(); }, _onUploadAllSelectedFiles: function (e) { @@ -708,18 +714,28 @@ ckan.module("file-upload-widget", function ($, _) { }, _onUploadProgress: function (e) { - let progress = e.detail.loaded / e.detail.total; + let progressbar = window.fuwProgressBars[e.detail.file.id]; - this.uploadBar.animate(progress); + if (progressbar) { + progressbar.animate(e.detail.loaded / e.detail.total); + } }, _onFinishUpload: function (e) { console.log(e.detail); - this.uploadBar.destroy(); + + let progressBar = window.fuwProgressBars[e.detail.file.id]; + + if (progressBar) { + progressBar.destroy(); + } this._removeUploadButtonForFile(e.detail.file.id); this._replaceWithUploadedFileId(e.detail.file.id, e.detail.result.id); this._updateUploadedFileSize(e.detail.result.id, e.detail.result.size); + + this._updateFileIdsInput(); + this._updateMediaGallery(); }, _removeUploadButtonForFile: function (fileId) { @@ -756,5 +772,106 @@ ckan.module("file-upload-widget", function ($, _) { console.log(fileIds.get().join(",")); this.fileIdsInput.val(fileIds.get().join(",")); }, + + _recreateSelectedFiles: function () { + let fileIdsVal = this.fileIdsInput.val(); + + if (!fileIdsVal) { + return; + } + + let fileIds = this.fileIdsInput.val().split(","); + + fileIds.forEach(fileId => { + this.sandbox.client.call( + "GET", + "files_file_show", + `?id=${fileId}`, + (data) => { + this._addFileItem( + data.result.id, + data.result.name, + data.result.size, + this.const.type.file, + true) + }, (resp) => { + if (resp.responseJSON.error.message === "Not found: file") { + this._removeMissingFile(fileId); + } + // TODO: some toast message? + } + ); + }) + + this._toggleSelectedFilesButton(fileIds.length); + }, + + _onFailUpload: function (e) { + // implement some toast message system + Object.entries(e.detail.reasons).forEach(([key, value]) => { + if (key.startsWith("__")) { + return; + } + console.log(`${key}: ${value}`); + }) + + this.uploadBar.destroy(); + }, + + _removeMissingFile: function (fileId) { + let fileIds = this.fileIdsInput.val().split(","); + + fileIds = fileIds.filter(id => id !== fileId); + + this.fileIdsInput.val(fileIds.join(",")); + + let fileEl = this.el.find(`li[fuw-file-id="${fileId}"]`); + fileEl.remove(); + this._toggleSelectedFilesButton(); + }, + + _updateMediaGallery: function () { + this.sandbox.client.call( + "GET", + "files_file_scan", + "", + (data) => { + let mediaFiles = data.result.results; + + this.mediaFilesContainer.toggleEl(mediaFiles.length); + this.mediaFilesEmptyContainer.toggleEl(mediaFiles.length === 0); + + this.mediaFilesContainer.empty(); + + data.result.results.forEach(file => { + this.mediaFilesContainer.append($(this._mediaFileItemTemplate( + file.id, + file.name, + file.size + ))); + }); + }, (resp) => { + console.error(resp); + // TODO: some toast message? + } + ); + }, + + _mediaFileItemTemplate: function (fileId, fileName, fileSize) { + let fileIconType = "data"; + let mungedFileName = this._truncateFileName(fileName); + let formattedFileSize = this._formatFileSize(fileSize); + + return ` +
  • + + +
  • + ` + }, }; }); diff --git a/ckanext/file_upload_widget/helpers.py b/ckanext/file_upload_widget/helpers.py index 50e8a91..d77e623 100644 --- a/ckanext/file_upload_widget/helpers.py +++ b/ckanext/file_upload_widget/helpers.py @@ -1,14 +1,6 @@ from __future__ import annotations import math -from typing import Any - -import ckan.plugins.toolkit as tk - - -def fuw_get_user_files(user: str) -> list[dict[str, Any]]: - return tk.get_action("files_file_scan")({}, {}).get("results", []) - def fuw_printable_file_size(size_bytes: int) -> str: if size_bytes == 0: diff --git a/ckanext/file_upload_widget/templates/scheming/display_snippets/files_upload_widget.html b/ckanext/file_upload_widget/templates/scheming/display_snippets/files_upload_widget.html new file mode 100644 index 0000000..9ffa08c --- /dev/null +++ b/ckanext/file_upload_widget/templates/scheming/display_snippets/files_upload_widget.html @@ -0,0 +1,14 @@ + +{% if data[field.field_name] %} + +{% endif %} diff --git a/ckanext/file_upload_widget/templates/scheming/form_snippets/files_upload_widget.html b/ckanext/file_upload_widget/templates/scheming/form_snippets/files_upload_widget.html index ee58738..523f576 100644 --- a/ckanext/file_upload_widget/templates/scheming/form_snippets/files_upload_widget.html +++ b/ckanext/file_upload_widget/templates/scheming/form_snippets/files_upload_widget.html @@ -32,7 +32,7 @@ -