diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs index fb67b63544..c11237c73b 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs @@ -176,7 +176,7 @@ {::mf/wrap-props false} [{:keys [file-id prefix groups open-groups force-open? renaming listing-thumbs? selected on-asset-click on-drag-start do-rename cancel-rename on-rename-group on-group on-ungroup on-context-menu - selected-full is-local count-variants]}] + selected-full is-local count-variants on-group-combine-variants]}] (let [group-open? (if (false? (get open-groups prefix)) ;; if the user has closed it specifically, respect that false @@ -190,6 +190,12 @@ (into #{} (comp (map :path) (d/nilv "")) selected-full)) + + components (not-empty (get groups "" [])) + can-combine? (and is-local + (> (count components) 1) + (not-any? ctc/is-variant? components) + (apply = (map :main-instance-page components))) on-drag-enter (mf/use-fn (mf/deps dragging* prefix selected-paths is-local drag-data*) @@ -221,47 +227,48 @@ :section :components :path prefix :group-open? group-open? + :can-combine? can-combine? :on-rename on-rename-group - :on-ungroup on-ungroup}] + :on-ungroup on-ungroup + :on-group-combine-variants on-group-combine-variants}] (when group-open? [:* - (let [components (not-empty (get groups "" []))] - [:div {:class-name (stl/css-case :asset-grid listing-thumbs? - :asset-enum (not listing-thumbs?)) - :on-drag-enter on-drag-enter - :on-drag-leave on-drag-leave - :on-drag-over dom/prevent-default - :on-drop on-drop} + [:div {:class (stl/css-case :asset-grid listing-thumbs? + :asset-enum (not listing-thumbs?)) + :on-drag-enter on-drag-enter + :on-drag-leave on-drag-leave + :on-drag-over dom/prevent-default + :on-drop on-drop} - (when ^boolean dragging? - [:div {:class (stl/css :grid-placeholder)} "\u00A0"]) + (when ^boolean dragging? + [:div {:class (stl/css :grid-placeholder)} "\u00A0"]) - (when (and (empty? components) - (some? groups) - is-local) - [:div {:class (stl/css-case :drop-space true - :drop-space-small (not dragging?))}]) + (when (and (empty? components) + (some? groups) + is-local) + [:div {:class (stl/css-case :drop-space true + :drop-space-small (not dragging?))}]) - (for [component components] - [:& components-item - {:component component - :key (dm/str "component-" (:id component)) - :renaming renaming - :listing-thumbs? listing-thumbs? - :file-id file-id - :selected selected - :selected-full selected-full - :selected-paths selected-paths - :on-asset-click on-asset-click - :on-context-menu on-context-menu - :on-drag-start on-drag-start - :on-group on-group - :do-rename do-rename - :cancel-rename cancel-rename - :is-local is-local - :num-variants (count-variants (:variant-id component))}])]) + (for [component components] + [:& components-item + {:component component + :key (dm/str "component-" (:id component)) + :renaming renaming + :listing-thumbs? listing-thumbs? + :file-id file-id + :selected selected + :selected-full selected-full + :selected-paths selected-paths + :on-asset-click on-asset-click + :on-context-menu on-context-menu + :on-drag-start on-drag-start + :on-group on-group + :do-rename do-rename + :cancel-rename cancel-rename + :is-local is-local + :num-variants (count-variants (:variant-id component))}])] (for [[path-item content] groups] (when-not (empty? path-item) @@ -281,6 +288,7 @@ :on-rename-group on-rename-group :on-ungroup on-ungroup :on-context-menu on-context-menu + :on-group-combine-variants on-group-combine-variants :selected-full selected-full :is-local is-local :count-variants count-variants}]))])])) @@ -427,7 +435,7 @@ rename-group (mf/use-fn - (mf/deps components) + (mf/deps components on-clear-selection) (fn [path last-path] (on-clear-selection) (let [undo-id (js/Symbol)] @@ -458,7 +466,7 @@ on-ungroup (mf/use-fn - (mf/deps components) + (mf/deps components on-clear-selection) (fn [path] (on-clear-selection) (let [undo-id (js/Symbol)] @@ -469,6 +477,19 @@ (map #(dwv/rename-comp-or-variant-and-main (:id %) (cmm/ungroup % path))))) (st/emit! (dwu/commit-undo-transaction undo-id))))) + on-group-combine-variants + (mf/use-fn + (mf/deps components on-clear-selection) + (fn [path] + (on-clear-selection) + (let [comps (->> components + (filter #(str/starts-with? (:path %) path))) + ids (into #{} (map :main-instance-id comps)) + page-id (->> comps first :main-instance-page)] + + (st/emit! (dwv/combine-as-variants ids {:page-id page-id}))))) + + on-drag-start (mf/use-fn (mf/deps file-id) @@ -564,6 +585,7 @@ :on-rename-group on-rename-group :on-group on-group :on-ungroup on-ungroup + :on-group-combine-variants on-group-combine-variants :on-context-menu on-context-menu :selected-full selected-full :is-local ^boolean is-local diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs index aa68fc20dd..9ef16fae5b 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs @@ -14,6 +14,7 @@ [app.main.store :as st] [app.main.ui.components.forms :as fm] [app.main.ui.components.title-bar :refer [title-bar]] + [app.main.ui.ds.buttons.icon-button :refer [icon-button*]] [app.main.ui.icons :as i] [app.main.ui.workspace.sidebar.assets.common :as cmm] [app.util.dom :as dom] @@ -21,7 +22,7 @@ [rumext.v2 :as mf])) (mf/defc asset-group-title - [{:keys [file-id section path group-open? on-rename on-ungroup]}] + [{:keys [file-id section path group-open? on-rename on-ungroup on-group-combine-variants can-combine?]}] (when-not (empty? path) (let [[other-path last-path truncated] (cfh/compact-path path 35 true) menu-state (mf/use-state cmm/initial-context-menu-state) @@ -38,33 +39,50 @@ (mf/use-fn (fn [event] (dom/prevent-default event) + (dom/stop-propagation event) (let [pos (dom/get-client-position event)] (swap! menu-state cmm/open-context-menu pos)))) on-close-menu (mf/use-fn #(swap! menu-state cmm/close-context-menu))] - [:div {:class (stl/css :group-title) - :on-context-menu on-context-menu} - [:& title-bar {:collapsable true - :collapsed (not group-open?) - :all-clickable true - :on-collapsed on-fold-group - :title (mf/html [:* (when-not (empty? other-path) - [:span {:class (stl/css :pre-path) - :title (when truncated path)} - other-path "\u00A0\u2022\u00A0"]) - [:span {:class (stl/css :path) - :title (when truncated path)} - last-path]])}] - [:& cmm/assets-context-menu - {:on-close on-close-menu - :state @menu-state - :options [{:name (tr "workspace.assets.rename") - :id "assets-rename-group" - :handler #(on-rename % path last-path)} - {:name (tr "workspace.assets.ungroup") - :id "assets-ungroup-group" - :handler #(on-ungroup path)}]}]]))) + [:div {:class (stl/css :group-title-wrapper)} + [:div {:class (stl/css :group-title) + :on-context-menu on-context-menu} + [:& title-bar {:collapsable true + :collapsed (not group-open?) + :all-clickable true + :on-collapsed on-fold-group + :title (mf/html [:* (when-not (empty? other-path) + [:span {:class (stl/css :pre-path) + :title (when truncated path)} + other-path "\u00A0\u2022\u00A0"]) + [:span {:class (stl/css :path) + :title (when truncated path)} + last-path] + #_[:span {:class (stl/css :title-menu) + :on-click on-context-menu} + "aaa"]])}] + + [:& cmm/assets-context-menu + {:on-close on-close-menu + :state @menu-state + :options (cond-> [{:name (tr "workspace.assets.rename") + :id "assets-rename-group" + :handler #(on-rename % path last-path)} + {:name (tr "workspace.assets.ungroup") + :id "assets-ungroup-group" + :handler #(on-ungroup path)}] + can-combine? + (conj + {:name (tr "workspace.shape.menu.combine-as-variants") + :id "assets-combine-as-variants" + :handler #(on-group-combine-variants path)}))}]] + + [:div {:class (stl/css :title-menu)} + [:> icon-button* {:variant "ghost" + :aria-label (tr "workspace.assets.component-group-options") + :on-click on-context-menu + :icon "menu"}]]]))) (defn group-assets "Convert a list of assets in a nested structure like this: diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/groups.scss b/frontend/src/app/main/ui/workspace/sidebar/assets/groups.scss index 42327c8afa..7b1b9ff740 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/groups.scss +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/groups.scss @@ -6,6 +6,28 @@ @import "refactor/common-refactor.scss"; +.group-title-wrapper { + width: 100%; + display: flex; + justify-content: space-between; + + &:hover { + cursor: pointer; + + .title-menu { + display: block; + } + } +} + +.group-title-wrapper > :first-child { + flex: 1 1 auto; +} + +.title-menu { + display: none; +} + .group-title { padding-left: $s-4; } @@ -39,6 +61,7 @@ @include uppercaseTitleTipography; color: var(--modal-title-foreground-color); } + .modal-close-btn { @extend .modal-close-btn-base; } @@ -47,20 +70,24 @@ @include bodySmallTypography; margin-bottom: $s-24; } + .input-wrapper { @extend .input-with-label; @include bodySmallTypography; margin-bottom: $s-8; } + .action-buttons { @extend .modal-action-btns; } + .cancel-button { @extend .modal-cancel-btn; } .accept-btn { @extend .modal-accept-btn; + &.danger { @extend .modal-danger-btn; } diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 8543980822..4223a043e7 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -4929,6 +4929,10 @@ msgstr "Text Transform" msgid "workspace.assets.ungroup" msgstr "Ungroup" +#: src/app/main/ui/workspace/sidebar/assets/groups.cljs:83 +msgid "workspace.assets.component-group-options" +msgstr "Component group options" + #: src/app/main/ui/workspace/context_menu.cljs:769 msgid "workspace.context-menu.grid-cells.area" msgstr "Create area" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 04b5e3ab6f..a295a0f5ab 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -4939,6 +4939,9 @@ msgstr "Transformar texto" msgid "workspace.assets.ungroup" msgstr "Desagrupar" +msgid "workspace.assets.component-group-options" +msgstr "Opciones del grupo de componentes" + #: src/app/main/ui/workspace/context_menu.cljs:769 msgid "workspace.context-menu.grid-cells.area" msgstr "Crear area"