diff --git a/frontend/resources/styles/main/partials/modal.scss b/frontend/resources/styles/main/partials/modal.scss index adb71207fd..7c6a631e18 100644 --- a/frontend/resources/styles/main/partials/modal.scss +++ b/frontend/resources/styles/main/partials/modal.scss @@ -215,6 +215,7 @@ background-color: $color-white; border: 1px solid $color-gray-20; width: 30rem; + min-height: 14rem; p { font-size: $fs14; @@ -276,10 +277,6 @@ .modal-content { padding: 1rem; } -} - -.import-dialog { - min-height: 215px; svg { max-width: 18px; @@ -451,8 +448,6 @@ } .export-dialog { - min-height: 24rem; - .export-option { border-radius: 4px; border: 1px solid $color-gray-10; diff --git a/frontend/src/app/main/ui/dashboard/export.cljs b/frontend/src/app/main/ui/dashboard/export.cljs index 059c91f057..81fdd7335c 100644 --- a/frontend/src/app/main/ui/dashboard/export.cljs +++ b/frontend/src/app/main/ui/dashboard/export.cljs @@ -11,6 +11,7 @@ [app.main.store :as st] [app.main.ui.icons :as i] [app.main.worker :as uw] + [app.util.data :refer [classnames]] [app.util.dom :as dom] [app.util.i18n :as i18n :refer [tr]] [beicon.core :as rx] @@ -18,12 +19,60 @@ (def ^:const options [:all :merge :detach]) +(mf/defc export-entry + [{:keys [file]}] + + [:div.file-entry + {:class (classnames :loading (:loading? file) + :success (:export-success? file) + :error (:export-error? file))} + [:div.file-name + [:div.file-icon + (cond (:export-success? file) i/tick + (:export-error? file) i/close + (:loading? file) i/loader-pencil)] + + [:div.file-name-label (:name file)]]]) + +(defn mark-file-error [files file-id] + (->> files + (mapv #(cond-> % + (= file-id (:id %)) + (assoc :export-error? true + :loading? false))))) + +(defn mark-file-success [files file-id] + (->> files + (mapv #(cond-> % + (= file-id (:id %)) + (assoc :export-success? true + :loading? false))))) + (mf/defc export-dialog {::mf/register modal/components ::mf/register-as :export} - [{:keys [team-id files]}] - (let [selected-option (mf/use-state :all) + [{:keys [team-id files has-libraries?]}] + (let [state (mf/use-state {:status :prepare + :files (->> files (mapv #(assoc % :loading? true)))}) + selected-option (mf/use-state :all) + start-export + (fn [] + (swap! state assoc :status :exporting) + (->> (uw/ask-many! + {:cmd :export-file + :team-id team-id + :export-type @selected-option + :files (->> files (mapv :id))}) + (rx/delay-emit 1000) + (rx/subs + (fn [msg] + (when (= :error (:type msg)) + (swap! state update :files mark-file-error (:file-id msg))) + + (when (= :finish (:type msg)) + (swap! state update :files mark-file-success (:file-id msg)) + (dom/trigger-download-uri (:filename msg) (:mtype msg) (:uri msg))))))) cancel-fn (mf/use-callback (fn [event] @@ -35,24 +84,19 @@ (mf/deps @selected-option) (fn [event] (dom/prevent-default event) - - (->> (uw/ask-many! - {:cmd :export-file - :team-id team-id - :export-type @selected-option - :files files}) - (rx/subs - (fn [msg] - (when (= :finish (:type msg)) - (dom/trigger-download-uri (:filename msg) (:mtype msg) (:uri msg)))))) - - (st/emit! (modal/hide)))) + (start-export))) on-change-handler (mf/use-callback (fn [_ type] (reset! selected-option type)))] + (mf/use-effect + (fn [] + (when-not has-libraries? + ;; Start download automaticaly + (start-export)))) + [:div.modal-overlay [:div.modal-container.export-dialog [:div.modal-header @@ -62,31 +106,49 @@ [:div.modal-close-button {:on-click cancel-fn} i/close]] - [:div.modal-content - [:p.explain (tr "dashboard.export.explain")] - [:p.detail (tr "dashboard.export.detail")] + (cond + (= (:status @state) :prepare) + [:* + [:div.modal-content + [:p.explain (tr "dashboard.export.explain")] + [:p.detail (tr "dashboard.export.detail")] - (for [type [:all :merge :detach]] - (let [selected? (= @selected-option type)] - [:div.export-option {:class (when selected? "selected")} - [:label.option-container - [:h3 (tr (str "dashboard.export.options." (d/name type) ".title"))] - [:p (tr (str "dashboard.export.options." (d/name type) ".message"))] - [:input {:type "radio" - :checked selected? - :on-change #(on-change-handler % type) - :name "export-option"}] - [:span {:class "option-radio-check"}]]]))] + (for [type [:all :merge :detach]] + (let [selected? (= @selected-option type)] + [:div.export-option {:class (when selected? "selected")} + [:label.option-container + [:h3 (tr (str "dashboard.export.options." (d/name type) ".title"))] + [:p (tr (str "dashboard.export.options." (d/name type) ".message"))] + [:input {:type "radio" + :checked selected? + :on-change #(on-change-handler % type) + :name "export-option"}] + [:span {:class "option-radio-check"}]]]))] - [:div.modal-footer - [:div.action-buttons - [:input.cancel-button - {:type "button" - :value (tr "labels.cancel") - :on-click cancel-fn}] + [:div.modal-footer + [:div.action-buttons + [:input.cancel-button + {:type "button" + :value (tr "labels.cancel") + :on-click cancel-fn}] - [:input.accept-button - {:class "primary" - :type "button" - :value (tr "labels.export") - :on-click accept-fn}]]]]])) + [:input.accept-button + {:class "primary" + :type "button" + :value (tr "labels.continue") + :on-click accept-fn}]]]] + + (= (:status @state) :exporting) + [:* + [:div.modal-content + (for [file (:files @state)] + [:& export-entry {:file file}])] + + [:div.modal-footer + [:div.action-buttons + [:input.accept-button + {:class "primary" + :type "button" + :value (tr "labels.close") + :disabled (->> @state :files (some :loading?)) + :on-click cancel-fn}]]]])]])) diff --git a/frontend/src/app/main/ui/dashboard/file_menu.cljs b/frontend/src/app/main/ui/dashboard/file_menu.cljs index 8a5556bb47..31207a0b93 100644 --- a/frontend/src/app/main/ui/dashboard/file_menu.cljs +++ b/frontend/src/app/main/ui/dashboard/file_menu.cljs @@ -171,7 +171,8 @@ (modal/show {:type :export :team-id current-team-id - :files (->> files (mapv :id))})))))))] + :has-libraries? (->> files (some :has-libraries?)) + :files files})))))))] (mf/use-effect (fn [] diff --git a/frontend/src/app/main/ui/workspace/header.cljs b/frontend/src/app/main/ui/workspace/header.cljs index ac9a6fd5f8..8f1bd7a047 100644 --- a/frontend/src/app/main/ui/workspace/header.cljs +++ b/frontend/src/app/main/ui/workspace/header.cljs @@ -153,7 +153,7 @@ (modal/show {:type :export :team-id team-id - :files (->> files (mapv :id))})))))))] + :files files})))))))] (mf/use-effect (mf/deps @editing?) diff --git a/frontend/src/app/worker/export.cljs b/frontend/src/app/worker/export.cljs index 43c2828d52..854911c9bf 100644 --- a/frontend/src/app/worker/export.cljs +++ b/frontend/src/app/worker/export.cljs @@ -450,14 +450,22 @@ [{:keys [team-id files export-type] :as message}] (->> (rx/from files) - (rx/mapcat #(export-file team-id % export-type)) - (rx/map - (fn [value] - (if (contains? value :type) - value - (let [[file export-blob] value] - {:type :finish - :filename (:name file) - :mtype "application/penpot" - :description "Penpot export (*.penpot)" - :uri (dom/create-uri export-blob)})))))) + (rx/mapcat + (fn [file] + (->> (export-file team-id file export-type) + (rx/map + (fn [value] + (if (contains? value :type) + value + (let [[file export-blob] value] + {:type :finish + :file-id (:id file) + :filename (:name file) + :mtype "application/penpot" + :description "Penpot export (*.penpot)" + :uri (dom/create-uri export-blob)})))) + (rx/catch + (fn [err] + (rx/of {:type :error + :error (str err) + :file-id file})))))))) diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 86b863577c..3c07c0e8a7 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -855,6 +855,9 @@ msgstr "You are seeing version %s" msgid "labels.accept" msgstr "Accept" +msgid "labels.close" +msgstr "Close" + msgid "labels.add-custom-font" msgstr "Add custom font" @@ -2746,4 +2749,4 @@ msgid "workspace.updates.update" msgstr "Update" msgid "workspace.viewport.click-to-close-path" -msgstr "Click to close the path" \ No newline at end of file +msgstr "Click to close the path" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 06611400ef..d6c2bc4e97 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -855,6 +855,9 @@ msgstr "Estás viendo la versión %s" msgid "labels.accept" msgstr "Aceptar" +msgid "labels.close" +msgstr "Cerrar" + msgid "labels.add-custom-font" msgstr "Añadir fuentes personalizada" @@ -2742,4 +2745,4 @@ msgid "workspace.updates.update" msgstr "Actualizar" msgid "workspace.viewport.click-to-close-path" -msgstr "Pulsar para cerrar la ruta" \ No newline at end of file +msgstr "Pulsar para cerrar la ruta"