From 0ec49e5e95f06bb6964781dd5271669c966cbf24 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Mon, 31 Jul 2023 12:55:53 +0200 Subject: [PATCH 01/29] :bug: Fix remove content from boolean --- frontend/src/app/main/data/workspace/shapes.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/main/data/workspace/shapes.cljs b/frontend/src/app/main/data/workspace/shapes.cljs index 11420cee3f..e02f720a0b 100644 --- a/frontend/src/app/main/data/workspace/shapes.cljs +++ b/frontend/src/app/main/data/workspace/shapes.cljs @@ -288,7 +288,7 @@ (let [all-ids (into empty-parents ids) contains? (partial contains? all-ids) xform (comp (map lookup) - (filter cph/group-shape?) + (filter #(or (cph/group-shape? %) (cph/bool-shape? %))) (remove #(->> (:shapes %) (remove contains?) seq)) (map :id)) parents (into #{} xform all-parents)] From 13312dc4679a07b9e5f65cd2b1a9a11d3f3d41f7 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 31 Jul 2023 13:36:28 +0200 Subject: [PATCH 02/29] :bug: Allow nil values for x,y,width and height on paths --- common/src/app/common/types/shape.cljc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/common/src/app/common/types/shape.cljc b/common/src/app/common/types/shape.cljc index d43deb5735..3f2e3113cf 100644 --- a/common/src/app/common/types/shape.cljc +++ b/common/src/app/common/types/shape.cljc @@ -215,6 +215,10 @@ [:map {:title "PathAttrs"} [:type [:= :path]] [:id ::sm/uuid] + [:x {:optional true} [:maybe ::sm/safe-number]] + [:y {:optional true} [:maybe ::sm/safe-number]] + [:width {:optional true} [:maybe ::sm/safe-number]] + [:height {:optional true} [:maybe ::sm/safe-number]] [:content [:vector [:map From aac044fa0afdb1da437c488fcf4f68da5e8ae5ee Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 31 Jul 2023 15:49:08 +0200 Subject: [PATCH 03/29] :bug: Fix incorrect schema on bool-content --- common/src/app/common/types/shape.cljc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/common/src/app/common/types/shape.cljc b/common/src/app/common/types/shape.cljc index 3f2e3113cf..ae1687e91e 100644 --- a/common/src/app/common/types/shape.cljc +++ b/common/src/app/common/types/shape.cljc @@ -177,13 +177,14 @@ ;; FIXME: improve this schema [:bool-type :keyword] - ;; FIXME: improve this schema [:bool-content [:vector {:gen/max 2} [:map [:command :keyword] [:relative {:optional true} :boolean] - [:params [:map-of {:gen/max 5} :keyword ::sm/safe-number]]]]]]) + [:prev-pos {:optional true} ::gpt/point] + [:params {:optional true} + [:map-of {:gen/max 5} :keyword ::sm/safe-number]]]]]]) (sm/def! ::rect-attrs [:map {:title "RectAttrs"} From 17ea8300ed888cdaec2e9f6f68948526ce280081 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 31 Jul 2023 15:58:32 +0200 Subject: [PATCH 04/29] :bug: Accept nil values for :fill-color-gradient attr --- common/src/app/common/types/shape.cljc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/src/app/common/types/shape.cljc b/common/src/app/common/types/shape.cljc index ae1687e91e..3127883d99 100644 --- a/common/src/app/common/types/shape.cljc +++ b/common/src/app/common/types/shape.cljc @@ -75,7 +75,7 @@ [:map {:title "Fill"} [:fill-color {:optional true} ::ctc/rgb-color] [:fill-opacity {:optional true} ::sm/safe-number] - [:fill-color-gradient {:optional true} ::ctc/gradient] + [:fill-color-gradient {:optional true} [:maybe ::ctc/gradient]] [:fill-color-ref-file {:optional true} [:maybe ::sm/uuid]] [:fill-color-ref-id {:optional true} [:maybe ::sm/uuid]]]) From f72206bba31590bb4632ec3ef532584b22a9cbc3 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 31 Jul 2023 16:24:03 +0200 Subject: [PATCH 05/29] :bug: Ensure :shapes attr on importing an svg with an empty group This commit should not not be backported to, because the affected code is already refactored and the issue is already fixed on develop branch --- frontend/src/app/main/data/workspace/shapes.cljs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/frontend/src/app/main/data/workspace/shapes.cljs b/frontend/src/app/main/data/workspace/shapes.cljs index e02f720a0b..6341a07375 100644 --- a/frontend/src/app/main/data/workspace/shapes.cljs +++ b/frontend/src/app/main/data/workspace/shapes.cljs @@ -57,6 +57,11 @@ cts/default-frame-attrs cts/default-shape-attrs) + default-attrs (if (or (= :group (:type attrs)) + (= :bool (:type attrs))) + (assoc default-attrs :shapes []) + default-attrs) + selected-non-frames (into #{} (comp (map (d/getf objects)) (remove cph/frame-shape?)) From e3f69bcc982c7755b45b7d362fa5ef00ff8b5581 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 1 Aug 2023 07:40:52 +0200 Subject: [PATCH 06/29] :bug: Fix path validation --- common/src/app/common/types/shape.cljc | 1 + 1 file changed, 1 insertion(+) diff --git a/common/src/app/common/types/shape.cljc b/common/src/app/common/types/shape.cljc index 3127883d99..961e8e2ed5 100644 --- a/common/src/app/common/types/shape.cljc +++ b/common/src/app/common/types/shape.cljc @@ -221,6 +221,7 @@ [:width {:optional true} [:maybe ::sm/safe-number]] [:height {:optional true} [:maybe ::sm/safe-number]] [:content + {:optional true} [:vector [:map [:command :keyword] From 958931d26492f67accad1fed96268d03040df6e7 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 1 Aug 2023 13:09:51 +0200 Subject: [PATCH 07/29] :sparkles: Improve ws-conn handling on session expiration --- frontend/src/app/main.cljs | 26 ++++++++++++++++++++++++-- frontend/src/app/main/data/users.cljs | 25 ++----------------------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/frontend/src/app/main.cljs b/frontend/src/app/main.cljs index 33e019b993..50690807d2 100644 --- a/frontend/src/app/main.cljs +++ b/frontend/src/app/main.cljs @@ -50,6 +50,23 @@ (mf/mount (mf/element ui/app) (dom/get-element "app")) (mf/mount (mf/element modal) (dom/get-element "modal"))) +(defn- initialize-profile + "Event used mainly on application bootstrap; it fetches the profile + and if and only if the fetched profile corresponds to an + authenticated user; proceed to fetch teams." + [stream] + (rx/merge + (rx/of (du/fetch-profile)) + (->> stream + (rx/filter (ptk/type? ::profile-fetched)) + (rx/take 1) + (rx/map deref) + (rx/mapcat (fn [profile] + (if (du/is-authenticated? profile) + (rx/of (du/fetch-teams)) + (rx/empty)))) + (rx/observe-on :async)))) + (defn initialize [] (ptk/reify ::initialize @@ -61,14 +78,19 @@ (watch [_ _ stream] (rx/merge (rx/of (ev/initialize) - (feat/initialize) - (du/initialize-profile)) + (feat/initialize)) + (initialize-profile stream) + + ;; Once profile is fetched, initialize all penpot application + ;; routes (->> stream (rx/filter du/profile-fetched?) (rx/take 1) (rx/map #(rt/init-routes))) + ;; Once profile fetched and the current user is authenticated, + ;; proceed to initialize the websockets connection. (->> stream (rx/filter du/profile-fetched?) (rx/map deref) diff --git a/frontend/src/app/main/data/users.cljs b/frontend/src/app/main/data/users.cljs index 92d2e8bb18..06ff506423 100644 --- a/frontend/src/app/main/data/users.cljs +++ b/frontend/src/app/main/data/users.cljs @@ -117,28 +117,6 @@ (->> (rp/cmd! :get-profile) (rx/map profile-fetched))))) -;; --- EVENT: INITIALIZE PROFILE - -(defn initialize-profile - "Event used mainly on application bootstrap; it fetches the profile - and if and only if the fetched profile corresponds to an - authenticated user; proceed to fetch teams." - [] - (ptk/reify ::initialize-profile - ptk/WatchEvent - (watch [_ _ stream] - (rx/merge - (rx/of (fetch-profile)) - (->> stream - (rx/filter (ptk/type? ::profile-fetched)) - (rx/take 1) - (rx/map deref) - (rx/mapcat (fn [profile] - (if (= uuid/zero (:id profile)) - (rx/empty) - (rx/of (fetch-teams))))) - (rx/observe-on :async)))))) - ;; --- EVENT: login (defn- logged-in @@ -164,7 +142,8 @@ (when (is-authenticated? profile) (->> (rx/of (profile-fetched profile) (fetch-teams) - (get-redirect-event)) + (get-redirect-event) + (ws/initialize)) (rx/observe-on :async))))))) (declare login-from-register) From 67f56dd0f887190d8277bcc54af5258cffe3c4ed Mon Sep 17 00:00:00 2001 From: Aitor Date: Wed, 2 Aug 2023 10:18:40 +0200 Subject: [PATCH 08/29] :bug: Fix color picker not working when using shortcut --- frontend/src/app/main/data/workspace/colors.cljs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/main/data/workspace/colors.cljs b/frontend/src/app/main/data/workspace/colors.cljs index fbd330b2dd..32de9cf96c 100644 --- a/frontend/src/app/main/data/workspace/colors.cljs +++ b/frontend/src/app/main/data/workspace/colors.cljs @@ -353,9 +353,12 @@ (-> state (assoc-in [:workspace-global :picking-color?] true) (assoc ::md/modal {:id (random-uuid) - :data {:color colors/black :opacity 1} :type :colorpicker - :props {:on-change handle-change-color} + :props {:data {:color colors/black + :opacity 1} + :disable-opacity false + :disable-gradient false + :on-change handle-change-color} :allow-click-outside true}))))))) (defn color-att->text From 7efeeec9b16f2f51c62b937bef1afcae075e5279 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 1 Aug 2023 17:37:55 +0200 Subject: [PATCH 09/29] :sparkles: Add workspace initialization fix for broken shape references Is the code that executes at workspace initialization that checks all the shape children for broken references and proceed to emit a special event that fixes the shape children references. --- common/src/app/common/pages/changes.cljc | 15 +++++++- common/src/app/common/types/shape_tree.cljc | 19 +++++++--- frontend/src/app/main/data/workspace.cljs | 7 +++- .../workspace/fix_broken_shape_links.cljs | 38 +++++++++++++++++++ 4 files changed, 71 insertions(+), 8 deletions(-) create mode 100644 frontend/src/app/main/data/workspace/fix_broken_shape_links.cljs diff --git a/common/src/app/common/pages/changes.cljc b/common/src/app/common/pages/changes.cljc index 97be5e91b1..c116498544 100644 --- a/common/src/app/common/pages/changes.cljc +++ b/common/src/app/common/pages/changes.cljc @@ -93,6 +93,13 @@ [:component-id {:optional true} ::sm/uuid] [:ignore-touched {:optional true} :boolean]]] + [:fix-obj + [:map {:title "FixObjChange"} + [:type [:= :fix-obj]] + [:id ::sm/uuid] + [:page-id {:optional true} ::sm/uuid] + [:component-id {:optional true} ::sm/uuid]]] + [:mov-objects [:map {:title "MovObjectsChange"} [:type [:= :mov-objects]] @@ -218,7 +225,7 @@ (sm/def! ::changes [:sequential {:gen/max 2} ::change]) - + (def change? (sm/pred-fn ::change)) @@ -337,6 +344,12 @@ (d/update-in-when data [:pages-index page-id] ctst/delete-shape id ignore-touched) (d/update-in-when data [:components component-id] ctst/delete-shape id ignore-touched))) +(defmethod process-change :fix-obj + [data {:keys [page-id component-id] :as params}] + (if page-id + (d/update-in-when data [:pages-index page-id] ctst/fix-shape-children params) + (d/update-in-when data [:components component-id] ctst/fix-shape-children params))) + ;; FIXME: remove, seems like this method is already unused ;; reg-objects operation "regenerates" the geometry and selrect of the parent groups (defmethod process-change :reg-objects diff --git a/common/src/app/common/types/shape_tree.cljc b/common/src/app/common/types/shape_tree.cljc index f84db3e4d2..b872bd73c3 100644 --- a/common/src/app/common/types/shape_tree.cljc +++ b/common/src/app/common/types/shape_tree.cljc @@ -90,16 +90,24 @@ (delete-from-objects [objects] (if-let [target (get objects shape-id)] - (let [parent-id (or (:parent-id target) - (:frame-id target)) - children-ids (cph/get-children-ids objects shape-id)] - (-> (reduce dissoc objects children-ids) - (dissoc shape-id) + (let [parent-id (or (:parent-id target) + (:frame-id target)) + children-ids (cph/get-children-ids objects shape-id)] + (-> (reduce dissoc objects (cons shape-id children-ids)) (d/update-when parent-id delete-from-parent))) objects))] (update container :objects delete-from-objects)))) +(defn fix-shape-children + "Checks and fix the children relations of the shape. If a children does not + exists on the objects tree, it will be removed from shape." + [{:keys [objects] :as container} {:keys [id] :as params}] + (let [contains? (partial contains? objects)] + (d/update-in-when container [:objects id :shapes] + (fn [shapes] + (into [] (filter contains?) shapes))))) + (defn get-frames "Retrieves all frame objects as vector" ([objects] (get-frames objects nil)) @@ -350,6 +358,7 @@ (some? force-id) force-id keep-ids? (:id object) :else (uuid/next))] + (loop [child-ids (seq (:shapes object)) new-direct-children [] new-children [] diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 95a975fb39..7d744a65ba 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -44,6 +44,7 @@ [app.main.data.workspace.drawing.common :as dwdc] [app.main.data.workspace.edition :as dwe] [app.main.data.workspace.fix-bool-contents :as fbc] + [app.main.data.workspace.fix-broken-shape-links :as fbs] [app.main.data.workspace.fix-deleted-fonts :as fdf] [app.main.data.workspace.groups :as dwg] [app.main.data.workspace.guides :as dwgu] @@ -130,8 +131,10 @@ has-graphics? (-> file :media seq) components-v2 (features/active-feature? state :components-v2)] (rx/merge - (rx/of (fbc/fix-bool-contents)) - (rx/of (fdf/fix-deleted-fonts)) + (rx/of (fbc/fix-bool-contents) + (fdf/fix-deleted-fonts) + (fbs/fix-broken-shapes)) + (if (and has-graphics? components-v2) (rx/of (remove-graphics (:id file) (:name file))) (rx/empty))))))) diff --git a/frontend/src/app/main/data/workspace/fix_broken_shape_links.cljs b/frontend/src/app/main/data/workspace/fix_broken_shape_links.cljs new file mode 100644 index 0000000000..2866d97417 --- /dev/null +++ b/frontend/src/app/main/data/workspace/fix_broken_shape_links.cljs @@ -0,0 +1,38 @@ +;; This Source Code Form is subject to the terms of the Mozilla Public +;; License, v. 2.0. If a copy of the MPL was not distributed with this +;; file, You can obtain one at http://mozilla.org/MPL/2.0/. +;; +;; Copyright (c) KALEIDOS INC + +(ns app.main.data.workspace.fix-broken-shape-links + (:require + [app.main.data.workspace.changes :as dch] + [beicon.core :as rx] + [potok.core :as ptk])) + +(defn- generate-changes + [attr {:keys [objects id]}] + (let [base {:type :fix-obj attr id} + contains? (partial contains? objects) + xform (comp + (remove #(every? contains? (:shapes %))) + (map #(assoc base :id (:id %))))] + (sequence xform (vals objects)))) + +(defn fix-broken-shapes + [] + (ptk/reify ::fix-broken-shape-links + ptk/WatchEvent + (watch [it state _] + (let [data (get state :workspace-data) + changes (concat + (mapcat (partial generate-changes :page-id) + (vals (:pages-index data))) + (mapcat (partial generate-changes :component-id) + (vals (:components data))))] + + (rx/of (dch/commit-changes + {:origin it + :redo-changes (vec changes) + :undo-changes [] + :save-undo? false})))))) From 3eb25694652d2fb8e73240327e65a43f76fac400 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Tue, 1 Aug 2023 17:40:23 +0200 Subject: [PATCH 10/29] :sparkles: Add better exception reporting on commit-changes --- frontend/src/app/main/data/workspace/changes.cljs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/main/data/workspace/changes.cljs b/frontend/src/app/main/data/workspace/changes.cljs index 166538860c..ceaef9e4bc 100644 --- a/frontend/src/app/main/data/workspace/changes.cljs +++ b/frontend/src/app/main/data/workspace/changes.cljs @@ -8,6 +8,7 @@ (:require [app.common.data :as d] [app.common.data.macros :as dm] + [app.common.exceptions :as ex] [app.common.logging :as log] [app.common.pages :as cp] [app.common.pages.changes :as cpc] @@ -205,6 +206,7 @@ path (if (= file-id current-file-id) [:workspace-data] [:workspace-libraries file-id :data])] + (try (dm/assert! "expect valid vector of changes" @@ -217,7 +219,11 @@ (ctst/update-object-indices page-id)))) (catch :default err - (log/error :js/error err) + (when-let [data (ex-data err)] + (js/console.log (ex/explain data))) + + (when (ex/error? err) + (js/console.log (.-stack ^js err))) (vreset! error err) state)))) From e7a82579c132f67721bdf37a77dd05ca263ec90b Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 1 Aug 2023 18:56:17 +0200 Subject: [PATCH 11/29] :bug: Fix paste groups without shapes attr --- common/src/app/common/types/shape.cljc | 4 ++-- frontend/src/app/main/data/workspace.cljs | 7 ++++++- frontend/src/app/main/data/workspace/selection.cljs | 10 ++++++++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/common/src/app/common/types/shape.cljc b/common/src/app/common/types/shape.cljc index 961e8e2ed5..8f297c4819 100644 --- a/common/src/app/common/types/shape.cljc +++ b/common/src/app/common/types/shape.cljc @@ -156,7 +156,7 @@ [:map {:title "GroupAttrs"} [:type [:= :group]] [:id ::sm/uuid] - [:shapes [:vector {:gen/max 10 :gen/min 1} ::sm/uuid]]]) + [:shapes {:optional true} [:maybe [:vector {:gen/max 10 :gen/min 1} ::sm/uuid]]]]) (sm/def! ::frame-attrs [:map {:title "FrameAttrs"} @@ -172,7 +172,7 @@ [:map {:title "BoolAttrs"} [:type [:= :bool]] [:id ::sm/uuid] - [:shapes [:vector {:gen/max 10 :gen/min 1} ::sm/uuid]] + [:shapes {:optional true} [:maybe [:vector {:gen/max 10 :gen/min 1} ::sm/uuid]]] ;; FIXME: improve this schema [:bool-type :keyword] diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index 7d744a65ba..777a034379 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -1820,9 +1820,14 @@ detach? (or (foreign-instance? shape paste-objects state) (and (ctk/in-component-copy-not-root? shape) (not= (:id component-shape) - (:id component-shape-parent))))] + (:id component-shape-parent)))) + assign-shapes? (and (or (cph/group-shape? shape) + (cph/bool-shape? shape)) + (nil? (:shapes shape)))] (-> shape (assoc :frame-id frame-id :parent-id parent-id) + (cond-> assign-shapes? + (assoc :shapes [])) (cond-> detach? (-> ;; this is used later, if the paste needs to create a new component from the detached shape diff --git a/frontend/src/app/main/data/workspace/selection.cljs b/frontend/src/app/main/data/workspace/selection.cljs index efffe23655..eac3221338 100644 --- a/frontend/src/app/main/data/workspace/selection.cljs +++ b/frontend/src/app/main/data/workspace/selection.cljs @@ -409,6 +409,8 @@ :else (let [frame? (cph/frame-shape? obj) + group? (cph/group-shape? obj) + bool? (cph/bool-shape? obj) new-id (ids-map (:id obj)) parent-id (or parent-id frame-id) name (:name obj) @@ -427,8 +429,12 @@ :name name :parent-id parent-id :frame-id frame-id) - (dissoc :shapes - :main-instance? + + (cond-> + (or group? bool?) + (assoc :shapes [])) + + (dissoc :main-instance? :use-for-thumbnail?) (gsh/move delta) (d/update-when :interactions #(ctsi/remap-interactions % ids-map objects))) From 1bfc28f63d20dd1a60e000d72013e62854e411aa Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 2 Aug 2023 12:17:48 +0200 Subject: [PATCH 12/29] :sparkles: Add missing index on server_error_report table --- backend/src/app/http/debug.clj | 2 +- backend/src/app/migrations.clj | 3 +++ .../app/migrations/sql/0105-mod-server-error-report-table.sql | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 backend/src/app/migrations/sql/0105-mod-server-error-report-table.sql diff --git a/backend/src/app/http/debug.clj b/backend/src/app/http/debug.clj index b4ff0c8ab2..da99552935 100644 --- a/backend/src/app/http/debug.clj +++ b/backend/src/app/http/debug.clj @@ -264,7 +264,7 @@ content->>'~:hint' AS hint FROM server_error_report ORDER BY created_at DESC - LIMIT 100") + LIMIT 200") (defn error-list-handler [{:keys [::db/pool]} request] diff --git a/backend/src/app/migrations.clj b/backend/src/app/migrations.clj index 787d344509..00407df219 100644 --- a/backend/src/app/migrations.clj +++ b/backend/src/app/migrations.clj @@ -324,6 +324,9 @@ {:name "0104-mod-file-thumbnail-table" :fn (mg/resource "app/migrations/sql/0104-mod-file-thumbnail-table.sql")} + {:name "0105-mod-server-error-report-table" + :fn (mg/resource "app/migrations/sql/0105-mod-server-error-report-table.sql")} + ]) (defn apply-migrations! diff --git a/backend/src/app/migrations/sql/0105-mod-server-error-report-table.sql b/backend/src/app/migrations/sql/0105-mod-server-error-report-table.sql new file mode 100644 index 0000000000..3609cece9f --- /dev/null +++ b/backend/src/app/migrations/sql/0105-mod-server-error-report-table.sql @@ -0,0 +1,2 @@ +CREATE INDEX server_error_report__created_at__idx + ON server_error_report ( created_at ); From 88261c2ec3feac69274566db7f4b07fd611a66e8 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 2 Aug 2023 13:33:39 +0200 Subject: [PATCH 13/29] :sparkles: Increase network timeout on exporter dockerfile --- docker/images/Dockerfile.exporter | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docker/images/Dockerfile.exporter b/docker/images/Dockerfile.exporter index 7bc3f89d22..9ddd9ecc78 100644 --- a/docker/images/Dockerfile.exporter +++ b/docker/images/Dockerfile.exporter @@ -104,7 +104,7 @@ WORKDIR /opt/penpot/exporter USER penpot:penpot RUN set -ex; \ - yarn; \ - yarn run playwright install chromium; + yarn --network-timeout 1000000; \ + yarn --network-timeout 1000000 run playwright install chromium; CMD ["node", "app.js"] From eae5dfc8289862a5efc444bd6d471527a58885ec Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 2 Aug 2023 13:36:43 +0200 Subject: [PATCH 14/29] :bug: Don't send empty changes on fix broken shape links --- .../main/data/workspace/fix_broken_shape_links.cljs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/frontend/src/app/main/data/workspace/fix_broken_shape_links.cljs b/frontend/src/app/main/data/workspace/fix_broken_shape_links.cljs index 2866d97417..a9443b2fab 100644 --- a/frontend/src/app/main/data/workspace/fix_broken_shape_links.cljs +++ b/frontend/src/app/main/data/workspace/fix_broken_shape_links.cljs @@ -31,8 +31,10 @@ (mapcat (partial generate-changes :component-id) (vals (:components data))))] - (rx/of (dch/commit-changes - {:origin it - :redo-changes (vec changes) - :undo-changes [] - :save-undo? false})))))) + (if (seq changes) + (rx/of (dch/commit-changes + {:origin it + :redo-changes (vec changes) + :undo-changes [] + :save-undo? false})) + (rx/empty)))))) From 00f7c94377d3b09cfb277eb490d3df2f15cbe260 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 2 Aug 2023 13:37:44 +0200 Subject: [PATCH 15/29] :sparkles: Improve database error reporter --- backend/src/app/loggers/database.clj | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/backend/src/app/loggers/database.clj b/backend/src/app/loggers/database.clj index 5fbee80e98..e3021a6c77 100644 --- a/backend/src/app/loggers/database.clj +++ b/backend/src/app/loggers/database.clj @@ -50,9 +50,9 @@ (assoc :logger-name logger) (assoc :logger-level level) (dissoc :params) - (pp/pprint-str :width 200)) + (pp/pprint-str :width 200 :length 50 :level 10)) - :props (pp/pprint-str props :width 200) + :props (pp/pprint-str props :width 200 :length 50) :hint (or (ex-message cause) @message) :trace (ex/format-throwable cause :data? false :explain? false :header? false :summary? false)} @@ -62,10 +62,7 @@ (when-let [data (some-> data (dissoc ::s/problems ::s/value ::s/spec ::sm/explain :hint))] {:data (pp/pprint-str data :width 200)}) - (when-let [value (-> data ::sm/explain :value)] - {:value (pp/pprint-str value :width 200)}) - - (when-let [explain (ex/explain data)] + (when-let [explain (ex/explain data {:level 10 :length 50})] {:explain explain})))) From 046f501152161d6426c367ada2de8dda15503210 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Wed, 2 Aug 2023 14:51:12 +0200 Subject: [PATCH 16/29] :sparkles: Improve error reporting context --- backend/src/app/http/errors.clj | 17 +++++++++-------- backend/src/app/loggers/database.clj | 21 ++++++++++----------- backend/src/app/loggers/mattermost.clj | 20 ++++++++++++-------- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/backend/src/app/http/errors.clj b/backend/src/app/http/errors.clj index 3829abfaa7..24f9891d35 100644 --- a/backend/src/app/http/errors.clj +++ b/backend/src/app/http/errors.clj @@ -10,6 +10,7 @@ [app.common.exceptions :as ex] [app.common.logging :as l] [app.common.schema :as sm] + [app.config :as cf] [app.http :as-alias http] [app.http.access-token :as-alias actoken] [app.http.session :as-alias session] @@ -30,14 +31,14 @@ (let [claims (-> {} (into (::session/token-claims request)) (into (::actoken/token-claims request)))] - {:path (:path request) - :method (:method request) - :params (:params request) - :ip-addr (parse-client-ip request) - :user-agent (yrq/get-header request "user-agent") - :profile-id (:uid claims) - :version (or (yrq/get-header request "x-frontend-version") - "unknown")})) + {:request/path (:path request) + :request/method (:method request) + :request/params (:params request) + :request/user-agent (yrq/get-header request "user-agent") + :request/ip-addr (parse-client-ip request) + :request/profile-id (:uid claims) + :version/frontend (or (yrq/get-header request "x-frontend-version") "unknown") + :version/backend (:full cf/version)})) (defmulti handle-exception (fn [err & _rest] diff --git a/backend/src/app/loggers/database.clj b/backend/src/app/loggers/database.clj index e3021a6c77..a295783740 100644 --- a/backend/src/app/loggers/database.clj +++ b/backend/src/app/loggers/database.clj @@ -40,23 +40,22 @@ [{:keys [::l/context ::l/message ::l/props ::l/logger ::l/level ::l/cause] :as record}] (us/assert! ::l/record record) - (let [data (ex-data cause)] + (let [data (ex-data cause) + context (-> context + (assoc :tenant (cf/get :tenant)) + (assoc :host (cf/get :host)) + (assoc :public-uri (cf/get :public-uri)) + (assoc :logger/name logger) + (assoc :logger/level level) + (dissoc :request/params))] (merge - {:context (-> context - (assoc :tenant (cf/get :tenant)) - (assoc :host (cf/get :host)) - (assoc :public-uri (cf/get :public-uri)) - (assoc :version (:full cf/version)) - (assoc :logger-name logger) - (assoc :logger-level level) - (dissoc :params) + {:context (-> (into (sorted-map) context) (pp/pprint-str :width 200 :length 50 :level 10)) - :props (pp/pprint-str props :width 200 :length 50) :hint (or (ex-message cause) @message) :trace (ex/format-throwable cause :data? false :explain? false :header? false :summary? false)} - (when-let [params (:params context)] + (when-let [params (:request/params context)] {:params (pp/pprint-str params :width 200)}) (when-let [data (some-> data (dissoc ::s/problems ::s/value ::s/spec ::sm/explain :hint))] diff --git a/backend/src/app/loggers/mattermost.clj b/backend/src/app/loggers/mattermost.clj index 93db476a79..8a2117e23c 100644 --- a/backend/src/app/loggers/mattermost.clj +++ b/backend/src/app/loggers/mattermost.clj @@ -30,7 +30,9 @@ "```\n" "- host: `" (:host report) "`\n" "- tenant: `" (:tenant report) "`\n" - "- version: `" (:version report) "`\n" + "- request-path: `" (:request-path report) "`\n" + "- frontend-version: `" (:frontend-version report) "`\n" + "- backend-version: `" (:backend-version report) "`\n" "\n" "Trace:\n" (:trace report) @@ -50,13 +52,15 @@ (defn record->report [{:keys [::l/context ::l/id ::l/cause] :as record}] (us/assert! ::l/record record) - {:id id - :tenant (cf/get :tenant) - :host (cf/get :host) - :public-uri (cf/get :public-uri) - :version (:full cf/version) - :profile-id (:profile-id context) - :trace (ex/format-throwable cause :detail? false :header? false)}) + {:id id + :tenant (cf/get :tenant) + :host (cf/get :host) + :public-uri (cf/get :public-uri) + :backend-version (or (:version/backend context) (:full cf/version)) + :frontend-version (:version/frontend context) + :profile-id (:request/profile-id context) + :request-path (:request/path context) + :trace (ex/format-throwable cause :detail? false :header? false)}) (defn handle-event [cfg record] From 4b28685a6d00e784c270f21cc4b3f6d370d3aa70 Mon Sep 17 00:00:00 2001 From: Aitor Date: Wed, 2 Aug 2023 12:53:11 +0200 Subject: [PATCH 17/29] :bug: Fix prototype selects preventing ctrl-z --- .../sidebar/options/menus/interactions.cljs | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs index a672a1f1bb..36e7ecb97c 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/interactions.cljs @@ -319,7 +319,8 @@ [:div.interactions-element.separator [:span.element-set-subtitle.wide (tr "workspace.options.interaction-trigger")] [:select.input-select - {:value (str (:event-type interaction)) + {:data-mousetrap-dont-stop true ;; makes mousetrap to not stop at this element + :value (str (:event-type interaction)) :on-change change-event-type} (for [[value name] (event-type-names)] (when-not (and (= value :after-delay) @@ -342,7 +343,8 @@ [:div.interactions-element.separator [:span.element-set-subtitle.wide (tr "workspace.options.interaction-action")] [:select.input-select - {:value (str (:action-type interaction)) + {:data-mousetrap-dont-stop true ;; makes mousetrap to not stop at this element + :value (str (:action-type interaction)) :on-change change-action-type} (for [[value name] (action-type-names)] [:option {:key (dm/str "action-" value) @@ -353,7 +355,8 @@ [:div.interactions-element [:span.element-set-subtitle.wide (tr "workspace.options.interaction-destination")] [:select.input-select - {:value (str (:destination interaction)) + {:data-mousetrap-dont-stop true ;; makes mousetrap to not stop at this element + :value (str (:destination interaction)) :on-change change-destination} (if (= (:action-type interaction) :close-overlay) [:option {:value ""} (tr "workspace.options.interaction-self")] @@ -390,7 +393,8 @@ [:div.interactions-element [:span.element-set-subtitle.wide (tr "workspace.options.interaction-relative-to")] [:select.input-select - {:value (str (:position-relative-to interaction)) + {:data-mousetrap-dont-stop true ;; makes mousetrap to not stop at this element + :value (str (:position-relative-to interaction)) :on-change change-position-relative-to} (when (not= (:overlay-pos-type interaction) :manual) [:* @@ -405,7 +409,8 @@ [:div.interactions-element [:span.element-set-subtitle.wide (tr "workspace.options.interaction-position")] [:select.input-select - {:value (str (:overlay-pos-type interaction)) + {:data-mousetrap-dont-stop true ;; makes mousetrap to not stop at this element + :value (str (:overlay-pos-type interaction)) :on-change (partial change-overlay-pos-type (:id shape))} (for [[value name] (overlay-pos-type-names)] [:option {:value (str value)} name])]] @@ -467,7 +472,8 @@ [:div.interactions-element.separator [:span.element-set-subtitle.wide (tr "workspace.options.interaction-animation")] [:select.input-select - {:value (str (-> interaction :animation :animation-type)) + {:data-mousetrap-dont-stop true ;; makes mousetrap to not stop at this element + :value (str (-> interaction :animation :animation-type)) :on-change change-animation-type} [:option {:value ""} (tr "workspace.options.interaction-animation-none")] (for [[value name] (animation-type-names interaction)] @@ -529,7 +535,8 @@ [:div.interactions-element [:span.element-set-subtitle.wide (tr "workspace.options.interaction-easing")] [:select.input-select - {:value (str (-> interaction :animation :easing)) + {:data-mousetrap-dont-stop true ;; makes mousetrap to not stop at this element + :value (str (-> interaction :animation :easing)) :on-change change-easing} (for [[value name] (easing-names)] [:option {:value (str value)} name])] From 3ff13f1d8fe7d73e59962ca1375621582176c90a Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Wed, 2 Aug 2023 18:13:59 +0200 Subject: [PATCH 18/29] :bug: Fix duplicate board --- frontend/src/app/main/data/workspace/selection.cljs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/main/data/workspace/selection.cljs b/frontend/src/app/main/data/workspace/selection.cljs index eac3221338..6cb8c12373 100644 --- a/frontend/src/app/main/data/workspace/selection.cljs +++ b/frontend/src/app/main/data/workspace/selection.cljs @@ -430,12 +430,14 @@ :parent-id parent-id :frame-id frame-id) + (dissoc :shapes + :main-instance? + :use-for-thumbnail?) + (cond-> (or group? bool?) (assoc :shapes [])) - (dissoc :main-instance? - :use-for-thumbnail?) (gsh/move delta) (d/update-when :interactions #(ctsi/remap-interactions % ids-map objects))) From 9334f935eb70d7a807e15d7d485156ed26f309ce Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 3 Aug 2023 16:10:41 +0200 Subject: [PATCH 19/29] :sparkles: Add better error reporting on response encoding middleware --- backend/resources/app/templates/error-report.v3.tmpl | 2 +- backend/src/app/http/middleware.clj | 9 ++++++--- backend/src/app/loggers/database.clj | 3 +++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/backend/resources/app/templates/error-report.v3.tmpl b/backend/resources/app/templates/error-report.v3.tmpl index 216c4d3ebb..b36a97e499 100644 --- a/backend/resources/app/templates/error-report.v3.tmpl +++ b/backend/resources/app/templates/error-report.v3.tmpl @@ -71,7 +71,7 @@ penpot - error report v2 {{id}} {% if value %}
-
VALIDATION VALUE:
+
VALUE:
{{value}}
diff --git a/backend/src/app/http/middleware.clj b/backend/src/app/http/middleware.clj index e11a60d04d..2e6161bcd2 100644 --- a/backend/src/app/http/middleware.clj +++ b/backend/src/app/http/middleware.clj @@ -118,7 +118,9 @@ (t/write! tw data))) (catch java.io.IOException _) (catch Throwable cause - (l/error :hint "unexpected error on encoding response" :cause cause)) + (binding [l/*context* {:value data}] + (l/error :hint "unexpected error on encoding response" + :cause cause))) (finally (.close ^OutputStream output-stream)))))) @@ -131,8 +133,9 @@ (catch java.io.IOException _) (catch Throwable cause - (l/error :hint "unexpected error on encoding response" - :cause cause)) + (binding [l/*context* {:value data}] + (l/error :hint "unexpected error on encoding response" + :cause cause))) (finally (.close ^OutputStream output-stream)))))) diff --git a/backend/src/app/loggers/database.clj b/backend/src/app/loggers/database.clj index a295783740..093175adaf 100644 --- a/backend/src/app/loggers/database.clj +++ b/backend/src/app/loggers/database.clj @@ -58,6 +58,9 @@ (when-let [params (:request/params context)] {:params (pp/pprint-str params :width 200)}) + (when-let [value (:value context)] + {:value (pp/pprint-str value :width 200 :length 50 :level 10)}) + (when-let [data (some-> data (dissoc ::s/problems ::s/value ::s/spec ::sm/explain :hint))] {:data (pp/pprint-str data :width 200)}) From 54bb89b2bb941674b437ee80c39f49ba4a4e6872 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 3 Aug 2023 16:23:01 +0200 Subject: [PATCH 20/29] :arrow_up: Upgrade yetti to v9.16 (fixes exception unwrapping) --- backend/deps.edn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/deps.edn b/backend/deps.edn index 0b4e5180a4..5bf32ab958 100644 --- a/backend/deps.edn +++ b/backend/deps.edn @@ -21,8 +21,8 @@ java-http-clj/java-http-clj {:mvn/version "0.4.3"} funcool/yetti - {:git/tag "v9.15" - :git/sha "aa9b967" + {:git/tag "v9.16" + :git/sha "7df3e08" :git/url "https://github.com/funcool/yetti.git" :exclusions [org.slf4j/slf4j-api]} From 0527c55398c72e480cec91bbd916bc6032cf4981 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 3 Aug 2023 16:28:50 +0200 Subject: [PATCH 21/29] :sparkles: Add better exception handling on json content type handling --- backend/src/app/http/middleware.clj | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/backend/src/app/http/middleware.clj b/backend/src/app/http/middleware.clj index 2e6161bcd2..f71f9da952 100644 --- a/backend/src/app/http/middleware.clj +++ b/backend/src/app/http/middleware.clj @@ -22,9 +22,10 @@ (:import com.fasterxml.jackson.core.JsonParseException com.fasterxml.jackson.core.io.JsonEOFException + com.fasterxml.jackson.databind.exc.MismatchedInputException io.undertow.server.RequestTooBigException - java.io.OutputStream - java.io.InputStream)) + java.io.InputStream + java.io.OutputStream)) (set! *warn-on-reflection* true) @@ -78,11 +79,13 @@ (or (instance? JsonEOFException cause) - (instance? JsonParseException cause)) + (instance? JsonParseException cause) + (instance? MismatchedInputException cause)) (raise (ex/error :type :validation :code :malformed-json :hint (ex-message cause) :cause cause)) + :else (raise cause)))] From 79e3aadfcfda702a5cc63fd246e2150d37893850 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Thu, 3 Aug 2023 16:35:32 +0200 Subject: [PATCH 22/29] :bug: Fix undo change for multiple shapes --- .../app/main/ui/workspace/sidebar/options/shapes/multiple.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs index e93eb9314a..0180b09ff6 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/shapes/multiple.cljs @@ -319,7 +319,7 @@ layout-container-ids layout-container-values layout-item-ids layout-item-values] (mf/use-memo - (mf/deps objects-no-measures) + (mf/deps shapes objects-no-measures) (fn [] (into [] From 66e877ed40703d52fdbf53e2fcdc4d8f555daf58 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Fri, 4 Aug 2023 08:41:20 +0200 Subject: [PATCH 23/29] :bug: Fix stroke-width parsing on svg upload And refactor a bit the stroke parsing function --- .../app/main/data/workspace/svg_upload.cljs | 94 ++++++++++--------- frontend/src/app/main/ui/shapes/attrs.cljs | 2 +- frontend/src/app/util/color.cljs | 17 ++-- 3 files changed, 63 insertions(+), 50 deletions(-) diff --git a/frontend/src/app/main/data/workspace/svg_upload.cljs b/frontend/src/app/main/data/workspace/svg_upload.cljs index 53fbbbafb1..b2b9ff6294 100644 --- a/frontend/src/app/main/data/workspace/svg_upload.cljs +++ b/frontend/src/app/main/data/workspace/svg_upload.cljs @@ -8,6 +8,7 @@ (:require [app.common.colors :as clr] [app.common.data :as d] + [app.common.data.macros :as dm] [app.common.exceptions :as ex] [app.common.geom.matrix :as gmt] [app.common.geom.point :as gpt] @@ -123,56 +124,65 @@ (assoc-in [:fills 0 :fill-opacity] (-> (get-in shape [:svg-attrs :style :fill-opacity]) (d/parse-double 1))))))) -(defn setup-stroke [shape] - (let [stroke-linecap (-> (or (get-in shape [:svg-attrs :stroke-linecap]) - (get-in shape [:svg-attrs :style :stroke-linecap])) - ((d/nilf str/trim)) - ((d/nilf keyword))) - color-attr (str/trim (get-in shape [:svg-attrs :stroke])) - color-attr (if (= color-attr "currentColor") clr/black color-attr) - color-style (str/trim (get-in shape [:svg-attrs :style :stroke])) - color-style (if (= color-style "currentColor") clr/black color-style) - shape - (cond-> shape - ;; Color present as attribute - (uc/color? color-attr) - (-> (update :svg-attrs dissoc :stroke) - (assoc-in [:strokes 0 :stroke-color] (uc/parse-color color-attr))) +(defn- setup-stroke + [shape] + (let [attrs (get shape :svg-attrs) + style (get attrs :style) - ;; Color present as style - (uc/color? color-style) - (-> (update-in [:svg-attrs :style] dissoc :stroke) - (assoc-in [:strokes 0 :stroke-color] (uc/parse-color color-style))) + stroke (or (str/trim (:stroke attrs)) + (str/trim (:stroke style))) - (get-in shape [:svg-attrs :stroke-opacity]) - (-> (update :svg-attrs dissoc :stroke-opacity) - (assoc-in [:strokes 0 :stroke-opacity] (-> (get-in shape [:svg-attrs :stroke-opacity]) - (d/parse-double 1)))) + color (cond + (= stroke "currentColor") clr/black + (= stroke "none") nil + :else (uc/parse-color stroke)) - (get-in shape [:svg-attrs :style :stroke-opacity]) - (-> (update-in [:svg-attrs :style] dissoc :stroke-opacity) - (assoc-in [:strokes 0 :stroke-opacity] (-> (get-in shape [:svg-attrs :style :stroke-opacity]) - (d/parse-double 1)))) + opacity (when (some? color) + (d/parse-double + (or (:stroke-opacity attrs) + (:stroke-opacity style)) + 1)) - (get-in shape [:svg-attrs :stroke-width]) - (-> (update :svg-attrs dissoc :stroke-width) - (assoc-in [:strokes 0 :stroke-width] (-> (get-in shape [:svg-attrs :stroke-width]) - (d/parse-double)))) + width (when (some? color) + (d/parse-double + (or (:stroke-width attrs) + (:stroke-width style)) + 1)) - (get-in shape [:svg-attrs :style :stroke-width]) - (-> (update-in [:svg-attrs :style] dissoc :stroke-width) - (assoc-in [:strokes 0 :stroke-width] (-> (get-in shape [:svg-attrs :style :stroke-width]) - (d/parse-double)))) + linecap (or (get attrs :stroke-linecap) + (get style :stroke-linecap)) + linecap (some-> linecap str/trim keyword) - (and stroke-linecap (= (:type shape) :path)) - (-> (update-in [:svg-attrs :style] dissoc :stroke-linecap) - (cond-> (#{:round :square} stroke-linecap) - (assoc :stroke-cap-start stroke-linecap - :stroke-cap-end stroke-linecap))))] + attrs (-> attrs + (dissoc :stroke) + (dissoc :stroke-width) + (dissoc :stroke-opacity) + (update :style (fn [style] + (-> style + (dissoc :stroke) + (dissoc :stroke-linecap) + (dissoc :stroke-width) + (dissoc :stroke-opacity)))))] - (cond-> shape - (d/any-key? (get-in shape [:strokes 0]) :stroke-color :stroke-opacity :stroke-width :stroke-cap-start :stroke-cap-end) + (cond-> (assoc shape :svg-attrs attrs) + (some? color) + (assoc-in [:strokes 0 :stroke-color] color) + + (and (some? color) (some? opacity)) + (assoc-in [:strokes 0 :stroke-opacity] opacity) + + (and (some? color) (some? width)) + (assoc-in [:strokes 0 :stroke-width] width) + + (and (some? linecap) (= (:type shape) :path) + (or (= linecap :round) (= linecap :square))) + (assoc :stroke-cap-start linecap + :stroke-cap-end linecap) + + (d/any-key? (dm/get-in shape [:strokes 0]) + :stroke-color :stroke-opacity :stroke-width + :stroke-cap-start :stroke-cap-end) (assoc-in [:strokes 0 :stroke-style] :svg)))) (defn setup-opacity [shape] diff --git a/frontend/src/app/main/ui/shapes/attrs.cljs b/frontend/src/app/main/ui/shapes/attrs.cljs index d736e2cf44..8ea32ef4ec 100644 --- a/frontend/src/app/main/ui/shapes/attrs.cljs +++ b/frontend/src/app/main/ui/shapes/attrs.cljs @@ -89,7 +89,7 @@ (obj/merge! attrs (clj->js fill-attrs))))) (defn add-stroke [attrs stroke-data render-id index] - (let [stroke-style (:stroke-style stroke-data :none) + (let [stroke-style (:stroke-style stroke-data :solid) stroke-color-gradient-id (str "stroke-color-gradient_" render-id "_" index) stroke-width (:stroke-width stroke-data 1)] (if (not= stroke-style :none) diff --git a/frontend/src/app/util/color.cljs b/frontend/src/app/util/color.cljs index 30f49882e3..5b8ca29fdd 100644 --- a/frontend/src/app/util/color.cljs +++ b/frontend/src/app/util/color.cljs @@ -8,6 +8,7 @@ "Color conversion utils." (:require [app.common.data :as d] + [app.common.data.macros :as dm] [app.util.i18n :as i18n :refer [tr]] [app.util.object :as obj] [app.util.strings :as ust] @@ -176,14 +177,16 @@ (= id :multiple) (= file-id :multiple))) -(defn color? [^string color-str] - (and (not (nil? color-str)) - (seq color-str) - (gcolor/isValidColor color-str))) +(defn color? + [color] + (and (string? color) + (gcolor/isValidColor color))) -(defn parse-color [^string color-str] - (let [result (gcolor/parse color-str)] - (str (.-hex ^js result)))) +(defn parse-color + [color] + (when (color? color) + (let [result (gcolor/parse color)] + (dm/str (.-hex ^js result))))) (def color-names (obj/get-keys ^js gcolor/names)) From 2ba79961167550da6c427ba1e2af28090541c1a4 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Fri, 4 Aug 2023 08:58:44 +0200 Subject: [PATCH 24/29] :bug: Fix unexpected viewport update on leave workspace --- frontend/src/app/main/ui/hooks/resize.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/main/ui/hooks/resize.cljs b/frontend/src/app/main/ui/hooks/resize.cljs index 1782048cae..2811805a06 100644 --- a/frontend/src/app/main/ui/hooks/resize.cljs +++ b/frontend/src/app/main/ui/hooks/resize.cljs @@ -106,7 +106,7 @@ (mf/set-ref-val! prev-val-ref node))))] - (mf/with-effect [] + (mf/with-layout-effect [] ;; On dismount we need to disconnect the current observer (fn [] (when-let [observer (mf/ref-val observer-ref)] From 259b05db510aedf1661946257944763bfff99672 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Fri, 4 Aug 2023 10:45:17 +0200 Subject: [PATCH 25/29] :sparkles: Add more improvements to error reporting --- backend/src/app/loggers/database.clj | 5 ++--- backend/src/app/worker.clj | 20 ++++++-------------- 2 files changed, 8 insertions(+), 17 deletions(-) diff --git a/backend/src/app/loggers/database.clj b/backend/src/app/loggers/database.clj index 093175adaf..16818e57e5 100644 --- a/backend/src/app/loggers/database.clj +++ b/backend/src/app/loggers/database.clj @@ -47,7 +47,7 @@ (assoc :public-uri (cf/get :public-uri)) (assoc :logger/name logger) (assoc :logger/level level) - (dissoc :request/params))] + (dissoc :request/params :value :params :data))] (merge {:context (-> (into (sorted-map) context) (pp/pprint-str :width 200 :length 50 :level 10)) @@ -55,7 +55,7 @@ :hint (or (ex-message cause) @message) :trace (ex/format-throwable cause :data? false :explain? false :header? false :summary? false)} - (when-let [params (:request/params context)] + (when-let [params (or (:request/params context) (:params context))] {:params (pp/pprint-str params :width 200)}) (when-let [value (:value context)] @@ -67,7 +67,6 @@ (when-let [explain (ex/explain data {:level 10 :length 50})] {:explain explain})))) - (defn error-record? [{:keys [::l/level ::l/cause]}] (and (= :error level) diff --git a/backend/src/app/worker.clj b/backend/src/app/worker.clj index e11c68d2a3..05c27f7f8e 100644 --- a/backend/src/app/worker.clj +++ b/backend/src/app/worker.clj @@ -489,16 +489,8 @@ (l/error :hint "worker: unhandled exception" :cause cause)))))) (defn- get-error-context - [error item] - (let [data (ex-data error)] - (merge - {:hint (ex-message error) - :spec-problems (some->> data ::s/problems (take 10) seq vec) - :spec-value (some->> data ::s/value) - :data (some-> data (dissoc ::s/problems ::s/value ::s/spec)) - :params item} - (when-let [explain (ex/explain data)] - {:spec-explain explain})))) + [_ item] + {:params item}) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; CRON @@ -597,10 +589,10 @@ (catch InterruptedException _ (l/debug :hint "cron: task interrupted" :task-id id)) (catch Throwable cause - (l/error :hint "cron: unhandled exception on running task" - ::l/context (get-error-context cause task) - :task-id id - :cause cause)) + (binding [l/*context* (get-error-context cause task)] + (l/error :hint "cron: unhandled exception on running task" + :task-id id + :cause cause))) (finally (when-not (px/interrupted? :current) (schedule-cron-task cfg task)))))) From cf68a9cf1eb608b30b9b2c4ec8274a688fcd3032 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Fri, 4 Aug 2023 15:11:28 +0200 Subject: [PATCH 26/29] :bug: Fix safe number max values --- common/src/app/common/spec.cljc | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/common/src/app/common/spec.cljc b/common/src/app/common/spec.cljc index acb3c698b4..5a8c23a385 100644 --- a/common/src/app/common/spec.cljc +++ b/common/src/app/common/spec.cljc @@ -29,8 +29,10 @@ (def uuid-rx #"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$") -(def max-safe-int (int 1e6)) -(def min-safe-int (int -1e6)) +;; Integer/MAX_VALUE +(def max-safe-int 2147483647) +;; Integer/MIN_VALUE +(def min-safe-int -2147483648) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; DEFAULT SPECS From 7afaa9d31fd58ac6387c415b31dcdd9e97ecde60 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Fri, 4 Aug 2023 18:40:07 +0200 Subject: [PATCH 27/29] :bug: Fix incorrect implementation on error reporting context collection --- backend/src/app/loggers/database.clj | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/backend/src/app/loggers/database.clj b/backend/src/app/loggers/database.clj index 16818e57e5..fac70eac65 100644 --- a/backend/src/app/loggers/database.clj +++ b/backend/src/app/loggers/database.clj @@ -40,16 +40,16 @@ [{:keys [::l/context ::l/message ::l/props ::l/logger ::l/level ::l/cause] :as record}] (us/assert! ::l/record record) - (let [data (ex-data cause) - context (-> context - (assoc :tenant (cf/get :tenant)) - (assoc :host (cf/get :host)) - (assoc :public-uri (cf/get :public-uri)) - (assoc :logger/name logger) - (assoc :logger/level level) - (dissoc :request/params :value :params :data))] + (let [data (ex-data cause) + ctx (-> context + (assoc :tenant (cf/get :tenant)) + (assoc :host (cf/get :host)) + (assoc :public-uri (cf/get :public-uri)) + (assoc :logger/name logger) + (assoc :logger/level level) + (dissoc :request/params :value :params :data))] (merge - {:context (-> (into (sorted-map) context) + {:context (-> (into (sorted-map) ctx) (pp/pprint-str :width 200 :length 50 :level 10)) :props (pp/pprint-str props :width 200 :length 50) :hint (or (ex-message cause) @message) From 766040198a042f6ec4e9da879dae73639fb94b68 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Mon, 7 Aug 2023 09:29:04 +0200 Subject: [PATCH 28/29] :bug: Fix text validation --- common/src/app/common/types/shape/text.cljc | 78 +++++++++++---------- 1 file changed, 40 insertions(+), 38 deletions(-) diff --git a/common/src/app/common/types/shape/text.cljc b/common/src/app/common/types/shape/text.cljc index 89851ba8e4..dff8759561 100644 --- a/common/src/app/common/types/shape/text.cljc +++ b/common/src/app/common/types/shape/text.cljc @@ -21,44 +21,46 @@ [:type [:= "root"]] [:key {:optional true} :string] [:children - [:vector {:min 1 :gen/max 2 :gen/min 1} - [:map - [:type [:= "paragraph-set"]] - [:key {:optional true} :string] - [:children - [:vector {:min 1 :gen/max 2 :gen/min 1} - [:map - [:type [:= "paragraph"]] - [:key {:optional true} :string] - [:fills {:optional true} - [:maybe - [:vector {:gen/max 2} ::shape/fill]]] - [:font-family {:optional true} :string] - [:font-size {:optional true} :string] - [:font-style {:optional true} :string] - [:font-weight {:optional true} :string] - [:direction {:optional true} :string] - [:text-decoration {:optional true} :string] - [:text-transform {:optional true} :string] - [:typography-ref-id {:optional true} [:maybe ::sm/uuid]] - [:typography-ref-file {:optional true} [:maybe ::sm/uuid]] - [:children - [:vector {:min 1 :gen/max 2 :gen/min 1} - [:map - [:text :string] - [:key {:optional true} :string] - [:fills {:optional true} - [:maybe - [:vector {:gen/max 2} ::shape/fill]]] - [:font-family {:optional true} :string] - [:font-size {:optional true} :string] - [:font-style {:optional true} :string] - [:font-weight {:optional true} :string] - [:direction {:optional true} :string] - [:text-decoration {:optional true} :string] - [:text-transform {:optional true} :string] - [:typography-ref-id {:optional true} [:maybe ::sm/uuid]] - [:typography-ref-file {:optional true} [:maybe ::sm/uuid]]]]]]]]]]]]) + {:optional true} + [:maybe + [:vector {:min 1 :gen/max 2 :gen/min 1} + [:map + [:type [:= "paragraph-set"]] + [:key {:optional true} :string] + [:children + [:vector {:min 1 :gen/max 2 :gen/min 1} + [:map + [:type [:= "paragraph"]] + [:key {:optional true} :string] + [:fills {:optional true} + [:maybe + [:vector {:gen/max 2} ::shape/fill]]] + [:font-family {:optional true} :string] + [:font-size {:optional true} :string] + [:font-style {:optional true} :string] + [:font-weight {:optional true} :string] + [:direction {:optional true} :string] + [:text-decoration {:optional true} :string] + [:text-transform {:optional true} :string] + [:typography-ref-id {:optional true} [:maybe ::sm/uuid]] + [:typography-ref-file {:optional true} [:maybe ::sm/uuid]] + [:children + [:vector {:min 1 :gen/max 2 :gen/min 1} + [:map + [:text :string] + [:key {:optional true} :string] + [:fills {:optional true} + [:maybe + [:vector {:gen/max 2} ::shape/fill]]] + [:font-family {:optional true} :string] + [:font-size {:optional true} :string] + [:font-style {:optional true} :string] + [:font-weight {:optional true} :string] + [:direction {:optional true} :string] + [:text-decoration {:optional true} :string] + [:text-transform {:optional true} :string] + [:typography-ref-id {:optional true} [:maybe ::sm/uuid]] + [:typography-ref-file {:optional true} [:maybe ::sm/uuid]]]]]]]]]]]]]) From 6e313dff8449dbf34acfa39c726540c17b67a711 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 7 Aug 2023 11:12:27 +0200 Subject: [PATCH 29/29] :bug: Add workaround for unexpected exception on fix-broken-shapes which happens when we have a component shape tree with an ephimeral shape with id ZERO (unused and with invalid children) --- .../workspace/fix_broken_shape_links.cljs | 23 +++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/frontend/src/app/main/data/workspace/fix_broken_shape_links.cljs b/frontend/src/app/main/data/workspace/fix_broken_shape_links.cljs index a9443b2fab..e547f0c033 100644 --- a/frontend/src/app/main/data/workspace/fix_broken_shape_links.cljs +++ b/frontend/src/app/main/data/workspace/fix_broken_shape_links.cljs @@ -11,13 +11,28 @@ [potok.core :as ptk])) (defn- generate-changes - [attr {:keys [objects id]}] + [attr {:keys [objects id] :as container}] (let [base {:type :fix-obj attr id} contains? (partial contains? objects) xform (comp - (remove #(every? contains? (:shapes %))) - (map #(assoc base :id (:id %))))] - (sequence xform (vals objects)))) + ;; FIXME: Ensure all obj have id field (this is needed + ;; because some bug adds an ephimeral shape with id ZERO, + ;; with a single attr `:shapes` having a vector of ids + ;; pointing to not existing shapes). That happens on + ;; components. THIS IS A WORKAOURD + (map (fn [[id obj]] + (if (some? (:id obj)) + obj + (assoc obj :id id)))) + + ;; Remove all valid shapes + (remove (fn [obj] + (every? contains? (:shapes obj)))) + + (map (fn [obj] + (assoc base :id (:id obj)))))] + + (sequence xform objects))) (defn fix-broken-shapes []