diff --git a/CHANGES.md b/CHANGES.md index b889bb0c3..bbb9796e0 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -33,6 +33,7 @@ - Fix "Attribute overrides in copies are not exported in zip file" [Taiga #8072](https://tree.taiga.io/project/penpot/issue/8072) - Fix group not automatically selected in the Layers panel after creation [Taiga #8078](https://tree.taiga.io/project/penpot/issue/8078) - Fix export boards loses opacity [Taiga #7592](https://tree.taiga.io/project/penpot/issue/7592) +- Fix show in view mode and interactions workflow [Taiga #4711](https://github.com/penpot/penpot/pull/4711) ## 2.0.3 diff --git a/common/src/app/common/files/defaults.cljc b/common/src/app/common/files/defaults.cljc index 5c15fc10d..91acf6539 100644 --- a/common/src/app/common/files/defaults.cljc +++ b/common/src/app/common/files/defaults.cljc @@ -6,4 +6,4 @@ (ns app.common.files.defaults) -(def version 48) +(def version 49) diff --git a/common/src/app/common/files/migrations.cljc b/common/src/app/common/files/migrations.cljc index 3b7803156..434630977 100644 --- a/common/src/app/common/files/migrations.cljc +++ b/common/src/app/common/files/migrations.cljc @@ -937,6 +937,26 @@ (-> data (update :pages-index update-vals update-page)))) +(defn migrate-up-49 + "Remove hide-in-viewer for shapes that are origin or destination of an interaction" + [data] + (letfn [(update-object [destinations object] + (cond-> object + (or (:interactions object) + (contains? destinations (:id object))) + (dissoc object :hide-in-viewer))) + + (update-page [page] + (let [destinations (->> page + :objects + (vals) + (mapcat :interactions) + (map :destination) + (set))] + (update page :objects update-vals (partial update-object destinations))))] + + (update data :pages-index update-vals update-page))) + (def migrations "A vector of all applicable migrations" [{:id 2 :migrate-up migrate-up-2} @@ -976,4 +996,5 @@ {:id 45 :migrate-up migrate-up-45} {:id 46 :migrate-up migrate-up-46} {:id 47 :migrate-up migrate-up-47} - {:id 48 :migrate-up migrate-up-48}]) + {:id 48 :migrate-up migrate-up-48} + {:id 49 :migrate-up migrate-up-49}]) diff --git a/common/src/app/common/logic/shapes.cljc b/common/src/app/common/logic/shapes.cljc index 29d58dad6..a48155f2e 100644 --- a/common/src/app/common/logic/shapes.cljc +++ b/common/src/app/common/logic/shapes.cljc @@ -517,3 +517,16 @@ {:with-objects? true}) (pcb/reorder-grid-children [frame-id]))) (pcb/remove-objects empty-parents)))) + + +(defn change-show-in-viewer [shape hide?] + (cond-> (assoc shape :hide-in-viewer hide?) + ;; When a frame is no longer shown in view mode, it cannot have interactions + hide? + (dissoc :interactions))) + +(defn add-new-interaction [shape interaction] + (-> shape + (update :interactions ctsi/add-interaction interaction) + ;; When a interaction is created, the frame must be shown in view mode + (dissoc :hide-in-viewer))) diff --git a/common/src/app/common/test_helpers/shapes.cljc b/common/src/app/common/test_helpers/shapes.cljc index 28e8c5d2c..3f9e1f544 100644 --- a/common/src/app/common/test_helpers/shapes.cljc +++ b/common/src/app/common/test_helpers/shapes.cljc @@ -16,6 +16,7 @@ [app.common.types.pages-list :as ctpl] [app.common.types.shape :as cts] [app.common.types.shape-tree :as ctst] + [app.common.types.shape.interactions :as ctsi] [app.common.types.typographies-list :as cttl] [app.common.types.typography :as ctt])) @@ -99,3 +100,19 @@ [file label & {:keys [] :as params}] (let [typography (sample-typography label params)] (ctf/update-file-data file #(cttl/add-typography % typography)))) + +(defn add-interaction + [file origin-label dest-label] + (let [page (thf/current-page file) + origin (get-shape file origin-label) + dest (get-shape file dest-label) + interaction (-> ctsi/default-interaction + (ctsi/set-destination (:id dest)) + (assoc :position-relative-to (:id origin))) + interactions (ctsi/add-interaction (:interactions origin) interaction)] + (ctf/update-file-data + file + (fn [file-data] + (ctpl/update-page file-data + (:id page) + #(ctst/set-shape % (assoc origin :interactions interactions))))))) diff --git a/common/test/common_tests/logic/hide_in_viewer_test.cljc b/common/test/common_tests/logic/hide_in_viewer_test.cljc new file mode 100644 index 000000000..051a4732e --- /dev/null +++ b/common/test/common_tests/logic/hide_in_viewer_test.cljc @@ -0,0 +1,75 @@ +;; 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 common-tests.logic.hide-in-viewer-test + (:require + [app.common.files.changes-builder :as pcb] + [app.common.logic.shapes :as cls] + [app.common.test-helpers.compositions :as tho] + [app.common.test-helpers.files :as thf] + [app.common.test-helpers.ids-map :as thi] + [app.common.test-helpers.shapes :as ths] + [app.common.types.shape.interactions :as ctsi] + [clojure.test :as t])) + +(t/use-fixtures :each thi/test-fixture) + + +(t/deftest test-remove-show-in-view-mode-delete-interactions + (let [;; ==== Setup + + file (-> (thf/sample-file :file1) + (tho/add-frame :frame-dest) + (tho/add-frame :frame-origin) + (ths/add-interaction :frame-origin :frame-dest)) + + frame-origin (ths/get-shape file :frame-origin) + + page (thf/current-page file) + + + ;; ==== Action + changes (-> (pcb/empty-changes nil (:id page)) + (pcb/with-objects (:objects page)) + (pcb/update-shapes [(:id frame-origin)] #(cls/change-show-in-viewer % true))) + file' (thf/apply-changes file changes) + + ;; ==== Get + frame-origin' (ths/get-shape file' :frame-origin)] + + ;; ==== Check + (t/is (some? (:interactions frame-origin))) + (t/is (nil? (:interactions frame-origin'))))) + + + +(t/deftest test-add-new-interaction-updates-show-in-view-mode + (let [;; ==== Setup + + file (-> (thf/sample-file :file1) + (tho/add-frame :frame-dest :hide-in-viewer true) + (tho/add-frame :frame-origin :hide-in-viewer true)) + frame-dest (ths/get-shape file :frame-dest) + frame-origin (ths/get-shape file :frame-origin) + + page (thf/current-page file) + + ;; ==== Action + new-interaction (-> ctsi/default-interaction + (ctsi/set-destination (:id frame-dest)) + (assoc :position-relative-to (:id frame-dest))) + + changes (-> (pcb/empty-changes nil (:id page)) + (pcb/with-objects (:objects page)) + (pcb/update-shapes [(:id frame-origin)] #(cls/add-new-interaction % new-interaction))) + file' (thf/apply-changes file changes) + + ;; ==== Get + frame-origin' (ths/get-shape file' :frame-origin)] + + ;; ==== Check + (t/is (true? (:hide-in-viewer frame-origin))) + (t/is (nil? (:hide-in-viewer frame-origin'))))) diff --git a/frontend/src/app/main/data/workspace/interactions.cljs b/frontend/src/app/main/data/workspace/interactions.cljs index 9727d9033..a1f72393b 100644 --- a/frontend/src/app/main/data/workspace/interactions.cljs +++ b/frontend/src/app/main/data/workspace/interactions.cljs @@ -11,6 +11,7 @@ [app.common.files.changes-builder :as pcb] [app.common.files.helpers :as cfh] [app.common.geom.point :as gpt] + [app.common.logic.shapes :as cls] [app.common.types.page :as ctp] [app.common.types.shape-tree :as ctst] [app.common.types.shape.interactions :as ctsi] @@ -131,8 +132,7 @@ (let [new-interaction (-> ctsi/default-interaction (ctsi/set-destination destination) (assoc :position-relative-to (:id shape)))] - (update shape :interactions - ctsi/add-interaction new-interaction))))) + (cls/add-new-interaction shape new-interaction))))) (when (and (not (connected-frame? objects (:id frame))) (nil? flow)) (rx/of (add-flow (:id frame)))))))))) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs index 48b22e087..8b40932b4 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/measures.cljs @@ -9,6 +9,7 @@ (:require [app.common.data :as d] [app.common.geom.shapes :as gsh] + [app.common.logic.shapes :as cls] [app.common.types.shape.layout :as ctl] [app.common.types.shape.radius :as ctsr] [app.main.constants :refer [size-presets]] @@ -325,16 +326,15 @@ (fn [event] (let [value (-> event dom/get-target dom/checked?) undo-id (js/Symbol)] - (do - (st/emit! (dwu/start-undo-transaction undo-id) - (dwsh/update-shapes ids (fn [shape] (assoc shape :hide-in-viewer (not value))))) + (st/emit! (dwu/start-undo-transaction undo-id) + (dwsh/update-shapes ids (fn [shape] (cls/change-show-in-viewer shape (not value))))) - (when-not value + (when-not value ;; when a frame is no longer shown in view mode, cannot have ;; interactions that navigate to it. - (apply st/emit! (map #(dwi/remove-all-interactions-nav-to %) ids))) + (apply st/emit! (map #(dwi/remove-all-interactions-nav-to %) ids))) - (st/emit! (dwu/commit-undo-transaction undo-id))))))] + (st/emit! (dwu/commit-undo-transaction undo-id)))))] (mf/use-layout-effect (mf/deps radius-mode @radius-multi?)