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

This commit is contained in:
Andrey Antukh 2026-04-21 21:42:03 +02:00
commit f331325941
6 changed files with 76 additions and 9 deletions

View File

@ -1,6 +1,6 @@
# CHANGELOG
## 2.15.0 (Unreleased)
## 2.16.0 (Unreleased)
### :boom: Breaking changes & Deprecations
@ -24,6 +24,19 @@
- Fix text editor v1 focus [Taiga #13961](https://tree.taiga.io/project/penpot/issue/13961)
## 2.15.0 (Unreleased)
### :sparkles: New features & Enhancements
- Add MCP server integration [Taiga #13112](https://tree.taiga.io/project/penpot/us/13112)
- Add chunked upload API for large media and binary files (removes previous upload size limits) [Github #8909](https://github.com/penpot/penpot/pull/8909)
### :bug: Bugs fixed
- Fix incorrect handling of version restore operation [Github #9041](https://github.com/penpot/penpot/pull/9041)
- Fix removeChild errors from unmount race conditions [Github #8927](https://github.com/penpot/penpot/pull/8927)
## 2.14.3
### :sparkles: New features & Enhancements
@ -116,6 +129,8 @@
- Optimize sidebar performance for deeply nested shapes [Taiga #13017](https://tree.taiga.io/project/penpot/task/13017)
- Remove tokens path node and bulk remove tokens [Taiga #13007](https://tree.taiga.io/project/penpot/us/13007)
- Replace themes management modal radio buttons for switches [Taiga #9215](https://tree.taiga.io/project/penpot/us/9215)
- [MCP server] Integrations section [Taiga #13112](https://tree.taiga.io/project/penpot/us/13112)
- [Access Tokens] Look & feel refinement [Taiga #13114](https://tree.taiga.io/project/penpot/us/13114)
### :bug: Bugs fixed

View File

@ -380,7 +380,6 @@
(rx/take 1)
(rx/tap (fn [_] (perf/setup)))))
(->> stream
(rx/filter (ptk/type? ::dps/persistence-notification))
(rx/take 1)
@ -485,8 +484,8 @@
:tags tags}]
(rx/of (dwu/append-undo entry stack-undo?)))
(rx/empty))))))
(rx/take-until stoper-s))
(rx/take-until stoper-s))
(rx/of (mcp/notify-other-tabs-disconnect)))))
ptk/EffectEvent

View File

@ -607,6 +607,46 @@
:state state})]
(apply rx/of (map #(%) actions)))))))))
(def attributes->shape-update
"Maps each attribute-set to the update function that applies it to a shape.
Used both here (to resolve the correct update fn when explicit attrs are
passed to toggle-token) and in propagation.cljs (re-exported from there)."
{ctt/border-radius-keys update-shape-radius-for-corners
ctt/color-keys update-fill-stroke
ctt/stroke-width-keys update-stroke-width
ctt/sizing-keys apply-dimensions-token
ctt/opacity-keys update-opacity
ctt/rotation-keys update-rotation
;; Typography
ctt/font-family-keys update-font-family
ctt/font-size-keys update-font-size
ctt/font-weight-keys update-font-weight
ctt/letter-spacing-keys update-letter-spacing
ctt/text-case-keys update-text-case
ctt/text-decoration-keys update-text-decoration
ctt/typography-token-keys update-typography
ctt/shadow-keys update-shadow
ctt/line-height-keys update-line-height
;; Layout
#{:x :y} update-shape-position
#{:p1 :p2 :p3 :p4} update-layout-padding
#{:m1 :m2 :m3 :m4} update-layout-item-margin
#{:column-gap :row-gap} update-layout-gap
#{:width :height} apply-dimensions-token
#{:layout-item-min-w :layout-item-min-h
:layout-item-max-w :layout-item-max-h} update-layout-sizing-limits})
;; Flattened per-individual-key version of attributes->shape-update.
;; Allows O(1) lookup of the update function for any single attribute.
(def ^:private attr->shape-update
(reduce
(fn [acc [attr-set update-fn]]
(into acc (map (fn [k] [k update-fn]) attr-set)))
{}
attributes->shape-update))
;; Events to apply / unapply tokens to shapes ------------------------------------------------------------
(def attributes->shape-update

View File

@ -481,6 +481,17 @@
(and (= (.-name ^js cause) "NotFoundError")
(str/includes? message "removeChild")))))
(defn- from-plugin?
"Check if the error is marked as originating from plugin code. The
plugin runtime tracks plugin errors in a WeakMap, which works even
in SES hardened environments where error objects may be frozen."
[cause]
(try
(is-plugin-error? cause)
(catch :default _
false)))
(defonce uncaught-error-handler
(letfn [(on-unhandled-error [event]
(.preventDefault ^js event)
@ -535,7 +546,6 @@
(ex/print-throwable cause :prefix "Uncaught Rejection")
(ts/asap #(flash :cause cause :type :unhandled))))))))]
(.addEventListener g/window "error" on-unhandled-error)
(.addEventListener g/window "unhandledrejection" on-unhandled-rejection)
(fn []

View File

@ -7421,11 +7421,14 @@ msgid "workspace.plugins.empty-plugins"
msgstr "No plugins installed yet"
#: src/app/main/ui/workspace/plugins.cljs:193
msgid "workspace.plugins.error.manifest"
msgstr "The plugin manifest is incorrect."
msgid "workspace.plugins.error.manifest"
msgstr "The plugin manifest is incorrect."
msgid "plugins.validation.message"
msgstr "Field %s is invalid: %s"
#: src/app/main/data/plugins.cljs:105, src/app/main/ui/workspace/main_menu.cljs:766, src/app/main/ui/workspace/plugins.cljs:84
msgid "workspace.plugins.error.need-editor"
msgid "workspace.plugins.error.need-editor"
msgstr "You need to be an editor to use this plugin"
#: src/app/main/ui/workspace/plugins.cljs:189