Merge remote-tracking branch 'origin/staging' into develop

This commit is contained in:
Andrey Antukh 2025-12-03 18:52:28 +01:00
commit f76710296c
5 changed files with 86 additions and 24 deletions

View File

@ -20,7 +20,9 @@
[app.common.path-names :as cpn] [app.common.path-names :as cpn]
[app.common.transit :as t] [app.common.transit :as t]
[app.common.types.component :as ctc] [app.common.types.component :as ctc]
[app.common.types.components-list :as ctkl]
[app.common.types.shape :as cts] [app.common.types.shape :as cts]
[app.common.types.variant :as ctv]
[app.common.uuid :as uuid] [app.common.uuid :as uuid]
[app.main.data.changes :as dch] [app.main.data.changes :as dch]
[app.main.data.comments :as dcmt] [app.main.data.comments :as dcmt]
@ -551,7 +553,6 @@
component-id (:component-id shape) component-id (:component-id shape)
undo-id (js/Symbol)] undo-id (js/Symbol)]
(when valid? (when valid?
(if (ctc/is-variant-container? shape) (if (ctc/is-variant-container? shape)
;; Rename the full variant when it is a variant container ;; Rename the full variant when it is a variant container
@ -566,6 +567,43 @@
(dwl/rename-component component-id clean-name)) (dwl/rename-component component-id clean-name))
(dwu/commit-undo-transaction undo-id)))))))))) (dwu/commit-undo-transaction undo-id))))))))))
(defn rename-shape-or-variant
([id name]
(rename-shape-or-variant nil nil id name))
([file-id page-id id name]
(ptk/reify ::rename-shape-or-variant
ptk/WatchEvent
(watch [_ state _]
(let [file-id (d/nilv file-id (:current-file-id state))
page-id (d/nilv page-id (:current-page-id state))
file-data (dsh/lookup-file-data state file-id)
shape
(-> (dsh/lookup-page-objects state file-id page-id)
(get id))
is-variant? (ctc/is-variant? shape)
variant-id (when is-variant? (:variant-id shape))
variant-name (when is-variant? (:variant-name shape))
component-id (:component-id shape)
component (ctkl/get-component file-data (:component-id shape))
variant-properties (:variant-properties component)]
(cond
(and variant-name (ctv/valid-properties-formula? name))
(rx/of (dwva/update-properties-names-and-values
component-id variant-id variant-properties (ctv/properties-formula->map name))
(dwva/remove-empty-properties variant-id)
(dwva/update-error component-id))
variant-name
(rx/of (dwva/update-properties-names-and-values
component-id variant-id variant-properties {})
(dwva/remove-empty-properties variant-id)
(dwva/update-error component-id name))
:else
(rx/of (end-rename-shape id name))))))))
;; --- Update Selected Shapes attrs ;; --- Update Selected Shapes attrs
(defn update-selected-shapes (defn update-selected-shapes

View File

@ -14,6 +14,7 @@
[app.main.ui.components.dropdown :refer [dropdown-content*]] [app.main.ui.components.dropdown :refer [dropdown-content*]]
[app.main.ui.icons :as deprecated-icon] [app.main.ui.icons :as deprecated-icon]
[app.util.dom :as dom] [app.util.dom :as dom]
[app.util.globals :as ug]
[app.util.i18n :as i18n :refer [tr]] [app.util.i18n :as i18n :refer [tr]]
[app.util.keyboard :as kbd] [app.util.keyboard :as kbd]
[app.util.timers :as tm] [app.util.timers :as tm]
@ -53,14 +54,13 @@
(def ^:private valid-option? (def ^:private valid-option?
(sm/lazy-validator schema:option)) (sm/lazy-validator schema:option))
(mf/defc context-menu* (mf/defc context-menu-inner*
[{:keys [show on-close options selectable selected [{:keys [on-close options selectable selected
top left fixed min-width origin width] top left fixed min-width origin width]
:as props}] :as props}]
(assert (every? valid-option? options) "expected valid options") (assert (every? valid-option? options) "expected valid options")
(assert (fn? on-close) "missing `on-close` prop") (assert (fn? on-close) "missing `on-close` prop")
(assert (boolean? show) "missing `show` prop")
(assert (vector? options) "missing `options` prop") (assert (vector? options) "missing `options` prop")
(let [width (d/nilv width "initial") (let [width (d/nilv width "initial")
@ -80,14 +80,15 @@
offset-x (get state :offset-x) offset-x (get state :offset-x)
offset-y (get state :offset-y) offset-y (get state :offset-y)
levels (get state :levels) levels (get state :levels)
internal-id (mf/use-id)
on-local-close on-local-close
(mf/use-fn (mf/use-fn
(mf/deps on-close) (mf/deps on-close)
(fn [] (fn []
(swap! state* assoc :levels [{:parent nil (swap! state* assoc :levels [{:parent nil :options options}])
:options options}]) (when (fn? on-close)
(on-close))) (on-close))))
props props
(mf/spread-props props {:on-close on-local-close}) (mf/spread-props props {:on-close on-local-close})
@ -216,11 +217,22 @@
(swap! state* assoc :levels [{:parent nil (swap! state* assoc :levels [{:parent nil
:options options}])) :options options}]))
(mf/with-effect [internal-id]
(ug/dispatch! (ug/event "penpot:context-menu:open" #js {:id internal-id})))
(mf/with-effect [internal-id on-local-close]
(letfn [(on-event [event]
(when-let [detail (unchecked-get event "detail")]
(when (not= internal-id (unchecked-get detail "id"))
(on-local-close event))))]
(ug/listen "penpot:context-menu:open" on-event)
(partial ug/unlisten "penpot:context-menu:open" on-event)))
(mf/with-effect [ids] (mf/with-effect [ids]
(tm/schedule-on-idle (tm/schedule-on-idle
#(dom/focus! (dom/get-element (first ids))))) #(dom/focus! (dom/get-element (first ids)))))
(when (and show (some? levels)) (when (some? levels)
[:> dropdown-content* props [:> dropdown-content* props
(let [level (peek levels) (let [level (peek levels)
options (:options level) options (:options level)
@ -229,7 +241,7 @@
[:div {:class (stl/css-case [:div {:class (stl/css-case
:is-selectable selectable :is-selectable selectable
:context-menu true :context-menu true
:is-open show :is-open true
:fixed fixed) :fixed fixed)
:style {:top (+ top offset-y) :style {:top (+ top offset-y)
:left (+ left offset-x)} :left (+ left offset-x)}
@ -241,7 +253,7 @@
:role "menu" :role "menu"
:ref check-menu-offscreen} :ref check-menu-offscreen}
(when-let [parent (:parent level)] (when parent
[:* [:*
[:li {:id "go-back-sub-option" [:li {:id "go-back-sub-option"
:class (stl/css :context-menu-item) :class (stl/css :context-menu-item)
@ -256,7 +268,7 @@
[:li {:class (stl/css :separator)}]]) [:li {:class (stl/css :separator)}]])
(for [[index option] (d/enumerate (:options level))] (for [[index option] (d/enumerate options)]
(let [name (:name option) (let [name (:name option)
id (:id option) id (:id option)
sub-options (:options option) sub-options (:options option)
@ -297,3 +309,12 @@
:data-testid id} :data-testid id}
name name
[:span {:class (stl/css :submenu-icon)} deprecated-icon/arrow]])]))))]])]))) [:span {:class (stl/css :submenu-icon)} deprecated-icon/arrow]])]))))]])])))
(mf/defc context-menu*
{::mf/private true}
[{:keys [show] :as props}]
(assert (boolean? show) "expected `show` prop to be a boolean")
(when ^boolean show
[:> context-menu-inner* props]))

View File

@ -11,7 +11,6 @@
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.types.variant :as ctv] [app.common.types.variant :as ctv]
[app.main.data.workspace :as dw] [app.main.data.workspace :as dw]
[app.main.data.workspace.variants :as dwv]
[app.main.store :as st] [app.main.store :as st]
[app.util.debug :as dbg] [app.util.debug :as dbg]
[app.util.dom :as dom] [app.util.dom :as dom]
@ -69,15 +68,7 @@
name (str/trim (dom/get-value name-input))] name (str/trim (dom/get-value name-input))]
(on-stop-edit) (on-stop-edit)
(reset! edition* false) (reset! edition* false)
(if variant-name (st/emit! (dw/rename-shape-or-variant shape-id name)))))
(if (ctv/valid-properties-formula? name)
(st/emit! (dwv/update-properties-names-and-values component-id variant-id variant-properties (ctv/properties-formula->map name))
(dwv/remove-empty-properties variant-id)
(dwv/update-error component-id))
(st/emit! (dwv/update-properties-names-and-values component-id variant-id variant-properties {})
(dwv/remove-empty-properties variant-id)
(dwv/update-error component-id name)))
(st/emit! (dw/end-rename-shape shape-id name))))))
cancel-edit cancel-edit
(mf/use-fn (mf/use-fn

View File

@ -217,7 +217,7 @@
(u/display-not-valid :name value) (u/display-not-valid :name value)
:else :else
(st/emit! (dw/end-rename-shape id value)))))} (st/emit! (dw/rename-shape-or-variant file-id page-id id value)))))}
:blocked :blocked
{:this true {:this true

View File

@ -35,14 +35,26 @@ goog.scope(function () {
}; };
} }
self.event = function(...args) { self.event = function(name, detail) {
return new CustomEvent(...args); const options = {};
if (detail !== undefined) {
options.detail = detail;
}
return new CustomEvent(name, options);
}; };
self.dispatch_BANG_ = function(...args) { self.dispatch_BANG_ = function(...args) {
self.document.dispatchEvent(...args); self.document.dispatchEvent(...args);
}; };
self.listen = function(...args) {
self.document.addEventListener(...args);
};
self.unlisten = function(...args) {
self.document.removeEventListener(...args);
}
self.window = (function () { self.window = (function () {
if (typeof goog.global.window !== "undefined") { if (typeof goog.global.window !== "undefined") {
return goog.global.window; return goog.global.window;