mirror of
https://github.com/penpot/penpot.git
synced 2026-05-02 06:38:20 +00:00
✨ Add create variants in bulk interactions from assets tab (#7102)
* ✨ Add create variants in bulk interactions from assets tab * ✨ MR changes
This commit is contained in:
parent
537c5ca7b8
commit
f7746b8f94
@ -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
|
||||
|
||||
@ -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:
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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"
|
||||
|
||||
@ -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"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user