From a65282c01b7ede81e9f6dce200a0adfcaf96f7e7 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Fri, 26 Apr 2024 06:30:00 +0200 Subject: [PATCH 1/6] :bug: Fix update-temp-file audit_log stored data --- backend/src/app/rpc/commands/files_temp.clj | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/backend/src/app/rpc/commands/files_temp.clj b/backend/src/app/rpc/commands/files_temp.clj index bc183cfd9..4eef26214 100644 --- a/backend/src/app/rpc/commands/files_temp.clj +++ b/backend/src/app/rpc/commands/files_temp.clj @@ -16,6 +16,7 @@ [app.db.sql :as sql] [app.features.components-v2 :as feat.compv2] [app.features.fdata :as fdata] + [app.loggers.audit :as audit] [app.rpc :as-alias rpc] [app.rpc.commands.files :as files] [app.rpc.commands.files-create :as files.create] @@ -23,6 +24,7 @@ [app.rpc.commands.projects :as projects] [app.rpc.commands.teams :as teams] [app.rpc.doc :as-alias doc] + [app.rpc.helpers :as rph] [app.util.blob :as blob] [app.util.pointer-map :as pmap] [app.util.services :as sv] @@ -100,7 +102,9 @@ :revn revn :data nil :changes (blob/encode changes)}) - nil))) + (rph/with-meta (rph/wrap nil) + {::audit/replace-props {:file-id id + :revn revn}})))) ;; --- MUTATION COMMAND: persist-temp-file From 6901acb37e79974f132146b60b85cdb031e9025f Mon Sep 17 00:00:00 2001 From: Pablo Alba Date: Thu, 25 Apr 2024 19:50:22 +0200 Subject: [PATCH 2/6] :bug: Fix ungrouping detach components --- frontend/src/app/main/data/workspace/groups.cljs | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/frontend/src/app/main/data/workspace/groups.cljs b/frontend/src/app/main/data/workspace/groups.cljs index c3a403269..bbda31ecc 100644 --- a/frontend/src/app/main/data/workspace/groups.cljs +++ b/frontend/src/app/main/data/workspace/groups.cljs @@ -143,18 +143,12 @@ (map-indexed vector) (filter #(#{(:id group)} (second %))) (ffirst) - inc) - - ;; Shapes that are in a component (including root) must be detached, - ;; because cannot be easyly synchronized back to the main component. - shapes-to-detach (filter ctk/in-component-copy? - (cfh/get-children-with-self objects (:id group)))] + inc)] (-> (pcb/empty-changes it page-id) (pcb/with-objects objects) (pcb/change-parent parent-id children index-in-parent) - (pcb/remove-objects [(:id group)]) - (pcb/update-shapes (map :id shapes-to-detach) ctk/detach-shape)))) + (pcb/remove-objects [(:id group)])))) (defn remove-frame-changes [it page-id frame objects] From 22939aa689847b2a55d919608feb592fa1dbb120 Mon Sep 17 00:00:00 2001 From: Pablo Alba Date: Fri, 26 Apr 2024 11:55:56 +0200 Subject: [PATCH 3/6] :bug: Fix inspect permission on shared prototype for owners --- frontend/src/app/main/ui/viewer/header.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/app/main/ui/viewer/header.cljs b/frontend/src/app/main/ui/viewer/header.cljs index 77460f0b6..abf81479f 100644 --- a/frontend/src/app/main/ui/viewer/header.cljs +++ b/frontend/src/app/main/ui/viewer/header.cljs @@ -332,7 +332,7 @@ :title (tr "viewer.header.comments-section" (sc/get-tooltip :open-comments))} i/comments]) - (when (or (= (:type permissions) :membership) + (when (or (:in-team permissions) (and (= (:type permissions) :share-link) (= (:who-inspect permissions) "all"))) [:button {:on-click go-to-inspect From bebdc78ce6d34b38058f2badfd6f0523115185e3 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Thu, 25 Apr 2024 15:35:53 +0200 Subject: [PATCH 4/6] :bug: Fix problem with exporter texts --- frontend/src/app/main/ui/shapes/export.cljs | 6 +++++- frontend/src/app/main/ui/shapes/shape.cljs | 7 +++++++ frontend/src/app/worker/import/parser.cljs | 20 ++++++++++++++++---- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/frontend/src/app/main/ui/shapes/export.cljs b/frontend/src/app/main/ui/shapes/export.cljs index d10378e19..8ac2387e8 100644 --- a/frontend/src/app/main/ui/shapes/export.cljs +++ b/frontend/src/app/main/ui/shapes/export.cljs @@ -122,7 +122,11 @@ (add! :stroke-cap-end))) (cond-> text? - (-> (add! :grow-type) + (-> (add! :x) + (add! :y) + (add! :width) + (add! :height) + (add! :grow-type) (add! :content (comp json/encode uuid->string)) (add! :position-data (comp json/encode uuid->string)))) diff --git a/frontend/src/app/main/ui/shapes/shape.cljs b/frontend/src/app/main/ui/shapes/shape.cljs index cbda63671..e0ab37c45 100644 --- a/frontend/src/app/main/ui/shapes/shape.cljs +++ b/frontend/src/app/main/ui/shapes/shape.cljs @@ -94,6 +94,13 @@ (obj/unset! "disable-shadows?") (obj/set! "ref" ref) (obj/set! "id" (dm/fmt "shape-%" shape-id)) + + ;; TODO: This is added for backward compatibility. + (cond-> (and (cfh/text-shape? shape) (empty? (:position-data shape))) + (-> (obj/set! "x" (:x shape)) + (obj/set! "y" (:y shape)) + (obj/set! "width" (:width shape)) + (obj/set! "height" (:height shape)))) (obj/set! "style" styles)) wrapper-props diff --git a/frontend/src/app/worker/import/parser.cljs b/frontend/src/app/worker/import/parser.cljs index a0da1e60d..fab4075ca 100644 --- a/frontend/src/app/worker/import/parser.cljs +++ b/frontend/src/app/worker/import/parser.cljs @@ -272,9 +272,21 @@ (def has-position? #{:frame :rect :image :text}) (defn parse-position - [props svg-data] - (let [values (->> (select-keys svg-data [:x :y :width :height]) - (d/mapm (fn [_ val] (d/parse-double val))))] + [props node svg-data] + (let [x (get-meta node :x d/parse-double) + y (get-meta node :y d/parse-double) + width (get-meta node :width d/parse-double) + height (get-meta node :height d/parse-double) + + values (->> (select-keys svg-data [:x :y :width :height]) + (d/mapm (fn [_ val] (d/parse-double val)))) + + values + (cond-> values + (some? x) (assoc :x x) + (some? y) (assoc :y y) + (some? width) (assoc :width width) + (some? height) (assoc :height height))] (d/merge props values))) (defn parse-circle @@ -392,7 +404,7 @@ center (gpt/point center-x center-y)] (cond-> props (has-position? type) - (parse-position svg-data) + (parse-position node svg-data) (= type :svg-raw) (add-svg-position node) From 3a71068a4868d4a76132fb7501dab1a7b93c0e56 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Fri, 26 Apr 2024 12:16:05 +0200 Subject: [PATCH 5/6] :bug: Add warning when font cannot be found --- frontend/src/app/main/fonts.cljs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/src/app/main/fonts.cljs b/frontend/src/app/main/fonts.cljs index a17201124..31949e7fe 100644 --- a/frontend/src/app/main/fonts.cljs +++ b/frontend/src/app/main/fonts.cljs @@ -133,7 +133,10 @@ (defn- fetch-gfont-css [url] (->> (http/send! {:method :get :uri url :mode :cors :response-type :text}) - (rx/map :body))) + (rx/map :body) + (rx/catch (fn [err] + (.warn js/console "Cannot find the font" (obj/get err "message")) + (rx/empty))))) (defmethod load-font :google [{:keys [id ::on-loaded] :as font}] From 0fc7d8529e58d76df111098faffe8c82e27a0d35 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Tue, 30 Apr 2024 10:38:58 +0200 Subject: [PATCH 6/6] :sparkles: Delete Bottle tutorial and walkthrough from onboarding dashboard --- .../src/app/main/ui/dashboard/projects.cljs | 117 +----------------- .../src/app/main/ui/dashboard/projects.scss | 86 ------------- 2 files changed, 1 insertion(+), 202 deletions(-) diff --git a/frontend/src/app/main/ui/dashboard/projects.cljs b/frontend/src/app/main/ui/dashboard/projects.cljs index cdd9304e9..11ab89f5d 100644 --- a/frontend/src/app/main/ui/dashboard/projects.cljs +++ b/frontend/src/app/main/ui/dashboard/projects.cljs @@ -7,15 +7,11 @@ (ns app.main.ui.dashboard.projects (:require-macros [app.main.style :as stl]) (:require - [app.common.data :as d] [app.common.geom.point :as gpt] - [app.config :as cf] [app.main.data.dashboard :as dd] [app.main.data.events :as ev] - [app.main.data.messages :as msg] [app.main.data.modal :as modal] [app.main.data.users :as du] - [app.main.errors :as errors] [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.dashboard.grid :refer [line-grid]] @@ -100,80 +96,6 @@ (def builtin-templates (l/derived :builtin-templates st/state)) -(mf/defc tutorial-project - [{:keys [close-tutorial default-project-id] :as props}] - (let [state (mf/use-state {:status :waiting - :file nil}) - - templates (mf/deref builtin-templates) - template (d/seek #(= (:id %) "tutorial-for-beginners") templates) - - on-template-cloned-success - (mf/use-fn - (mf/deps default-project-id) - (fn [response] - (swap! state #(assoc % :status :success :file (:first response))) - (st/emit! (dd/go-to-workspace {:id (first response) :project-id default-project-id :name "tutorial"}) - (du/update-profile-props {:viewed-tutorial? true})))) - - on-template-cloned-error - (mf/use-fn - (fn [cause] - (swap! state assoc :status :error) - (errors/print-error! cause) - (st/emit! (msg/error (tr "dashboard.libraries-and-templates.import-error"))))) - - download-tutorial - (mf/use-fn - (mf/deps template default-project-id) - (fn [] - (let [mdata {:on-success on-template-cloned-success - :on-error on-template-cloned-error} - params {:project-id default-project-id - :template-id (:id template)}] - (swap! state #(assoc % :status :importing)) - (st/emit! (with-meta (dd/clone-template (with-meta params mdata)) - {::ev/origin "get-started-hero-block"})))))] - [:article {:class (stl/css :tutorial)} - [:div {:class (stl/css :thumbnail)}] - [:div {:class (stl/css :text)} - [:h2 {:class (stl/css :title)} (tr "dasboard.tutorial-hero.title")] - [:p {:class (stl/css :info)} (tr "dasboard.tutorial-hero.info")] - [:button {:class (stl/css :btn-primary :action) - :on-click download-tutorial} - (case (:status @state) - :waiting (tr "dasboard.tutorial-hero.start") - :importing [:span.loader i/loader-pencil] - :success "")]] - - [:button {:class (stl/css :close) - :on-click close-tutorial - :aria-label (tr "labels.close")} - close-icon]])) - -(mf/defc interface-walkthrough - {::mf/wrap [mf/memo]} - [{:keys [close-walkthrough] :as props}] - (let [handle-walkthrough-link - (fn [] - (st/emit! (ptk/event ::ev/event {::ev/name "show-walkthrough" - ::ev/origin "get-started-hero-block" - :section "dashboard"})))] - [:article {:class (stl/css :walkthrough)} - [:div {:class (stl/css :thumbnail)}] - [:div {:class (stl/css :text)} - [:h2 {:class (stl/css :title)} (tr "dasboard.walkthrough-hero.title")] - [:p {:class (stl/css :info)} (tr "dasboard.walkthrough-hero.info")] - [:a {:class (stl/css :btn-primary :action) - :href " https://design.penpot.app/walkthrough" - :target "_blank" - :on-click handle-walkthrough-link} - (tr "dasboard.walkthrough-hero.start")]] - [:button {:class (stl/css :close) - :on-click close-walkthrough - :aria-label (tr "labels.close")} - close-icon]])) - (mf/defc project-item [{:keys [project first? team files] :as props}] (let [locale (mf/deref i18n/locale) @@ -365,7 +287,7 @@ (l/derived :dashboard-recent-files st/state)) (mf/defc projects-section - [{:keys [team projects profile default-project-id] :as props}] + [{:keys [team projects profile] :as props}] (let [projects (->> (vals projects) (sort-by :modified-at) (reverse)) @@ -378,8 +300,6 @@ (:team-hero? props true) (not (:is-default team))) - tutorial-viewed? (:viewed-tutorial? props true) - walkthrough-viewed? (:viewed-walkthrough? props true) is-my-penpot (= (:default-team-id profile) (:id team)) team-id (:id team) @@ -391,28 +311,6 @@ (ptk/data-event ::ev/event {::ev/name "dont-show-team-up-hero" ::ev/origin "dashboard"})))) - close-tutorial - (mf/use-fn - (fn [] - (st/emit! (du/update-profile-props {:viewed-tutorial? true}) - (ptk/data-event ::ev/event {::ev/name "dont-show-tutorial" - ::ev/origin "get-started-hero" - :type "tutorial" - :section "dashboard"})))) - - close-walkthrough - (mf/use-fn - (fn [] - (st/emit! (du/update-profile-props {:viewed-walkthrough? true}) - (ptk/data-event ::ev/event {::ev/name "dont-show-walkthrough" - ::ev/origin "get-started-hero" - :type "walkthrough" - :section "dashboard"})))) - - show-hero? (and is-my-penpot - (or (not tutorial-viewed?) - (not walkthrough-viewed?))) - show-team-hero? (and (not is-my-penpot) team-hero?)] (mf/with-effect [team] @@ -433,22 +331,9 @@ (when team-hero? [:& team-hero {:team team :close-fn close-banner}]) - (when (and (contains? cf/flags :dashboard-templates-section) - show-hero?) - [:div {:class (stl/css :hero-projects)} - (when (and (not tutorial-viewed?) (:is-default team)) - [:& tutorial-project - {:close-tutorial close-tutorial - :default-project-id default-project-id}]) - - (when (and (not walkthrough-viewed?) (:is-default team)) - [:& interface-walkthrough - {:close-walkthrough close-walkthrough}])]) - [:div {:class (stl/css-case :dashboard-container true :no-bg true :dashboard-projects true - :with-hero show-hero? :with-team-hero show-team-hero?)} (for [{:keys [id] :as project} projects] (let [files (when recent-map diff --git a/frontend/src/app/main/ui/dashboard/projects.scss b/frontend/src/app/main/ui/dashboard/projects.scss index e3b57fba5..680b9ef32 100644 --- a/frontend/src/app/main/ui/dashboard/projects.scss +++ b/frontend/src/app/main/ui/dashboard/projects.scss @@ -20,7 +20,6 @@ height: calc(100vh - $s-64); } -.with-hero, .with-team-hero { height: calc(100vh - $s-280); } @@ -242,88 +241,3 @@ width: 0; } } - -.hero-projects { - display: grid; - grid-template-columns: 1fr 1fr; - grid-gap: $s-32; - margin: 0 $s-16 $s-16 $s-20; - - @media (max-width: 1366px) { - grid-template-columns: 1fr; - } - - .tutorial, - .walkthrough { - display: grid; - grid-template-columns: auto 1fr; - position: relative; - border-radius: $br-8; - min-height: $s-216; - background-color: $db-tertiary; - padding: $s-8; - - .thumbnail { - width: $s-200; - height: $s-200; - border-radius: $br-6; - padding: $s-32; - display: block; - background-color: var(--color-canvas); - } - - img { - border-radius: $br-4; - margin-bottom: 0; - width: $s-232; - } - - .text { - padding: $s-32; - display: flex; - flex-direction: column; - } - - .title { - color: $df-primary; - font-size: $fs-24; - font-weight: $fw400; - margin-bottom: $s-8; - } - .info { - flex: 1; - color: $df-secondary; - margin-bottom: $s-20; - font-size: $fs-16; - } - .invite { - height: $s-32; - } - .action { - width: $s-180; - height: $s-40; - } - } - .walkthrough { - .thumbnail { - background-image: url("/images/walkthrough-cover.png"); - background-position: center; - background-repeat: no-repeat; - background-size: cover; - } - } - .tutorial { - .thumbnail { - background-image: url("/images/hands-on-tutorial.png"); - background-position: center; - background-repeat: no-repeat; - background-size: cover; - } - .loader { - display: flex; - svg#loader-pencil { - width: $s-32; - } - } - } -}