From d61ede802d42aadf1c55938094827f8e81b7a450 Mon Sep 17 00:00:00 2001 From: "alonso.torres" Date: Sun, 11 Oct 2026 23:06:25 +0200 Subject: [PATCH] :fire: Remove the components v1 leftovers No components v1 file reaches the code any more: opening one fails the feature check, and imports reject it or give it the feature. What only served v1 goes: - validate-file and validate-file-affected no longer skip a file without components/v2; - the root of a deleted component is found by its main instance id only, in the type helper and the component sprite; - generate-sync-library, which synced shapes inside live components, and the live components in containers-seq, so asset usages walk the pages only (deleted components keep their objects and still sync); - the unused :components-v2 file option, from the schema, the file data and the test fixtures; stored files that carry it still validate; - the team migration-in-progress check and its frontend alert, which leaves ephimeral features out of the team comparison; - the components v2 introduction dialog, its styles and icons, and the :v2-info-shown profile prop; - the graphic asset events and builders and the reads of graphics in the selection (the :add-media, :mod-media and :del-media changes stay, so stored changes still apply), and the uncalled render-page and render-components helpers. AI-assisted-by: claude-opus-5-5 Co-Authored-By: Claude Opus 5.5 (1M context) --- backend/src/app/rpc/commands/auth.clj | 1 - backend/src/app/rpc/commands/profile.clj | 1 - .../test/backend_tests/binfile_svg_test.clj | 2 - backend/test/backend_tests/binfile_test.clj | 18 +-- backend/test/backend_tests/rpc_file_test.clj | 22 +--- .../rpc_file_thumbnails_test.clj | 1 - backend/test/backend_tests/rpc_team_test.clj | 3 +- .../test/backend_tests/rpc_viewer_test.clj | 26 +---- common/src/app/common/features.cljc | 56 ++++------ .../src/app/common/files/changes_builder.cljc | 27 ----- common/src/app/common/files/validate.cljc | 104 +++++++++--------- common/src/app/common/logic/libraries.cljc | 52 +-------- .../test_helpers/composable/comp/nodes.cljc | 2 +- common/src/app/common/types/component.cljc | 4 +- common/src/app/common/types/container.cljc | 2 +- common/src/app/common/types/file.cljc | 13 +-- common/test/common_tests/features_test.cljc | 34 ++++++ .../common_tests/files/validate_test.cljc | 14 ++- .../logic/comp_creation_test.cljc | 6 +- .../common_tests/logic/comp_reset_test.cljc | 2 +- .../common_tests/logic/comp_sync_test.cljc | 2 +- .../common_tests/logic/comp_touched_test.cljc | 2 +- common/test/common_tests/runner.cljc | 2 + frontend/resources/images/icons/v2-icon-1.svg | 1 - frontend/resources/images/icons/v2-icon-2.svg | 1 - frontend/resources/images/icons/v2-icon-3.svg | 1 - frontend/resources/images/icons/v2-icon-4.svg | 1 - .../app/main/data/workspace/libraries.cljs | 56 ---------- frontend/src/app/main/errors.cljs | 5 - frontend/src/app/main/render.cljs | 79 +------------ frontend/src/app/main/ui/icons.cljs | 4 - .../src/app/main/ui/workspace/libraries.cljs | 58 ---------- .../src/app/main/ui/workspace/libraries.scss | 73 ------------ .../ui/workspace/sidebar/assets/colors.cljs | 1 - .../workspace/sidebar/assets/components.cljs | 3 +- .../sidebar/assets/file_library.cljs | 2 - .../sidebar/assets/typographies.cljs | 1 - .../test/frontend_tests/helpers/pages.cljs | 1 - frontend/translations/ca.po | 4 - frontend/translations/cs.po | 4 - frontend/translations/de.po | 4 - frontend/translations/en.po | 4 - frontend/translations/es.po | 4 - frontend/translations/fa.po | 4 - frontend/translations/fr.po | 4 - frontend/translations/fr_CA.po | 4 - frontend/translations/he.po | 4 - frontend/translations/hi.po | 4 - frontend/translations/hr.po | 4 - frontend/translations/id.po | 4 - frontend/translations/it.po | 4 - frontend/translations/jpn_JP.po | 4 - frontend/translations/ko.po | 4 - frontend/translations/lv.po | 4 - frontend/translations/nl.po | 4 - frontend/translations/pt_BR.po | 4 - frontend/translations/pt_PT.po | 4 - frontend/translations/ro.po | 4 - frontend/translations/ru.po | 4 - frontend/translations/sv.po | 4 - frontend/translations/tr.po | 4 - frontend/translations/ukr_UA.po | 4 - frontend/translations/zh_CN.po | 4 - frontend/translations/zh_Hant.po | 4 - 64 files changed, 151 insertions(+), 636 deletions(-) create mode 100644 common/test/common_tests/features_test.cljc delete mode 100644 frontend/resources/images/icons/v2-icon-1.svg delete mode 100644 frontend/resources/images/icons/v2-icon-2.svg delete mode 100644 frontend/resources/images/icons/v2-icon-3.svg delete mode 100644 frontend/resources/images/icons/v2-icon-4.svg diff --git a/backend/src/app/rpc/commands/auth.clj b/backend/src/app/rpc/commands/auth.clj index 549d24a3ba..e2833fcfdd 100644 --- a/backend/src/app/rpc/commands/auth.clj +++ b/backend/src/app/rpc/commands/auth.clj @@ -398,7 +398,6 @@ (merge {:viewed-tutorial? false :viewed-walkthrough? false :nudge {:big 10 :small 1} - :v2-info-shown true :release-notes-viewed (:main cf/version)})) password (or (:password params) "!") diff --git a/backend/src/app/rpc/commands/profile.clj b/backend/src/app/rpc/commands/profile.clj index f388d0dfc0..886758ecee 100644 --- a/backend/src/app/rpc/commands/profile.clj +++ b/backend/src/app/rpc/commands/profile.clj @@ -70,7 +70,6 @@ [:onboarding-questions {:optional true} [:map-of :keyword :string]] [:onboarding-questions-answered {:optional true} ::sm/boolean] [:nitrate-onboarding-viewed {:optional true} ::sm/boolean] - [:v2-info-shown {:optional true} ::sm/boolean] [:release-notes-viewed {:optional true} [::sm/text {:max 100}]] [:notifications {:optional true} schema:props-notifications] diff --git a/backend/test/backend_tests/binfile_svg_test.clj b/backend/test/backend_tests/binfile_svg_test.clj index f992f155d2..e6ff7de1ec 100644 --- a/backend/test/backend_tests/binfile_svg_test.clj +++ b/backend/test/backend_tests/binfile_svg_test.clj @@ -221,7 +221,6 @@ :id shape-id :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id shape-id :name "image" @@ -343,7 +342,6 @@ :id shape-id :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id shape-id :name "image" diff --git a/backend/test/backend_tests/binfile_test.clj b/backend/test/backend_tests/binfile_test.clj index 9570b68a38..4510527c68 100644 --- a/backend/test/backend_tests/binfile_test.clj +++ b/backend/test/backend_tests/binfile_test.clj @@ -95,7 +95,6 @@ :id shape-id :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id shape-id :name "image" @@ -142,7 +141,6 @@ :id root-id :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id root-id :name "svg-root" @@ -155,7 +153,6 @@ :id child-id :parent-id root-id :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id child-id :name "svg-text" @@ -186,8 +183,7 @@ file-id (first (:file-ids result)) imported (:result (th/command! {::th/type :get-file ::rpc/profile-id (:id profile) - :id file-id - :components-v2 true})) + :id file-id})) root (get-in imported [:data :pages-index svg-raw-page-id :objects svg-raw-root-id])] @@ -1654,8 +1650,7 @@ ;; Get the imported file's data (let [imported (:result (th/command! {::th/type :get-file ::rpc/profile-id (:id profile) - :id new-file-id - :components-v2 true})) + :id new-file-id})) shapes (get-file-shapes (:data imported))] ;; Check that component-file references point to the new library (doseq [shape shapes] @@ -1690,8 +1685,7 @@ ;; Get the imported file's data (let [imported (:result (th/command! {::th/type :get-file ::rpc/profile-id (:id profile) - :id new-file-id - :components-v2 true})) + :id new-file-id})) file-data (:data imported) pages (vals (:pages-index file-data)) all-shapes (mapcat vals (map :objects pages)) @@ -1863,8 +1857,7 @@ original-lib-id (:id (first (:external-libraries manifest))) imported (:result (th/command! {::th/type :get-file ::rpc/profile-id (:id profile) - :id new-file-id - :components-v2 true})) + :id new-file-id})) file-data (:data imported) pages (vals (:pages-index file-data)) all-shapes (mapcat vals (map :objects pages)) @@ -1919,8 +1912,7 @@ original-lib-id (:id (first (:external-libraries manifest))) imported (:result (th/command! {::th/type :get-file ::rpc/profile-id (:id viewer) - :id new-file-id - :components-v2 true})) + :id new-file-id})) file-data (:data imported) pages (vals (:pages-index file-data)) all-shapes (mapcat vals (map :objects pages)) diff --git a/backend/test/backend_tests/rpc_file_test.clj b/backend/test/backend_tests/rpc_file_test.clj index 305108003c..11a02d94a3 100644 --- a/backend/test/backend_tests/rpc_file_test.clj +++ b/backend/test/backend_tests/rpc_file_test.clj @@ -94,8 +94,7 @@ (t/testing "query single file without users" (let [data {::th/type :get-file ::rpc/profile-id (:id prof) - :id file-id - :components-v2 true} + :id file-id} out (th/command! data)] ;; (th/print-result! out) @@ -120,8 +119,7 @@ (t/testing "query single file after delete" (let [data {::th/type :get-file ::rpc/profile-id (:id prof) - :id file-id - :components-v2 true} + :id file-id} out (th/command! data)] (let [error (:error out) error-data (ex-data error)] @@ -199,7 +197,6 @@ :id shape-id :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id shape-id :name "image" @@ -292,7 +289,6 @@ :id shid :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id shid :name "image" @@ -451,7 +447,6 @@ :id s1-shid :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id s1-shid :name "image" @@ -465,7 +460,6 @@ :id s2-shid :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id s2-shid :name "image" @@ -478,7 +472,6 @@ :id t-shid :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id t-shid :name "text" @@ -1194,7 +1187,6 @@ :profile-id (:id prof) :revn 0 :vern 0 - :components-v2 true :changes changes}) (t/testing "RPC page query (rendering purposes)" @@ -1679,7 +1671,6 @@ :id s-id-1 :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id s-id-1 :name "Board" @@ -1696,7 +1687,6 @@ :id s-id-2 :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id s-id-2 :name "Board" @@ -1840,7 +1830,6 @@ :id s-id-1 :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id s-id-1 :name "Board" @@ -1871,7 +1860,6 @@ :id s-id-2 :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id s-id-2 :name "Board" @@ -2040,7 +2028,6 @@ :id s-id-1 :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id s-id-1 :name "Board" @@ -2072,7 +2059,6 @@ :id s-id-2 :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id s-id-2 :name "Board" @@ -2174,7 +2160,6 @@ :id main-id :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id main-id :name "Board" @@ -2204,7 +2189,6 @@ :id inst-id :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id inst-id :name "Board" @@ -2494,7 +2478,6 @@ :id frame-id :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id frame-id :name "frame" @@ -2506,7 +2489,6 @@ :id rect-id :parent-id frame-id :frame-id frame-id - :components-v2 true :obj (cts/setup-shape {:id rect-id :name "rect" diff --git a/backend/test/backend_tests/rpc_file_thumbnails_test.clj b/backend/test/backend_tests/rpc_file_thumbnails_test.clj index 46206af06f..24f4069e1f 100644 --- a/backend/test/backend_tests/rpc_file_thumbnails_test.clj +++ b/backend/test/backend_tests/rpc_file_thumbnails_test.clj @@ -50,7 +50,6 @@ :id shid :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id shid :name "Artboard" diff --git a/backend/test/backend_tests/rpc_team_test.clj b/backend/test/backend_tests/rpc_team_test.clj index 7781605860..441e33b319 100644 --- a/backend/test/backend_tests/rpc_team_test.clj +++ b/backend/test/backend_tests/rpc_team_test.clj @@ -1526,8 +1526,7 @@ (t/testing "get-file after leaving fails with not-found" (let [out (th/command! {::th/type :get-file ::rpc/profile-id (:id editor) - :id (:id file) - :components-v2 true}) + :id (:id file)}) error (:error out)] (t/is (th/ex-info? error)) (t/is (th/ex-of-type? error :not-found))))))) diff --git a/backend/test/backend_tests/rpc_viewer_test.clj b/backend/test/backend_tests/rpc_viewer_test.clj index ac09c1e67f..796649ee4a 100644 --- a/backend/test/backend_tests/rpc_viewer_test.clj +++ b/backend/test/backend_tests/rpc_viewer_test.clj @@ -74,8 +74,7 @@ (let [data {::th/type :get-view-only-bundle ::rpc/profile-id (:id prof) :file-id (:id file) - :page-id (get-in file [:data :pages 0]) - :components-v2 true} + :page-id (get-in file [:data :pages 0])} out (th/command! data)] @@ -108,8 +107,7 @@ (let [data {::th/type :get-view-only-bundle ::rpc/profile-id (:id prof2) :file-id (:id file) - :page-id (get-in file [:data :pages 0]) - :components-v2 true} + :page-id (get-in file [:data :pages 0])} out (th/command! data)] ;; (th/print-result! out) @@ -124,8 +122,7 @@ ::rpc/profile-id (:id prof2) :share-id @share-id :file-id (:id file) - :page-id (get-in file [:data :pages 0]) - :components-v2 true} + :page-id (get-in file [:data :pages 0])} out (th/command! data)] ;; (th/print-result! out) @@ -139,8 +136,7 @@ (let [data {::th/type :get-view-only-bundle :share-id @share-id :file-id (:id file) - :page-id (get-in file [:data :pages 0]) - :components-v2 true} + :page-id (get-in file [:data :pages 0])} out (th/command! data)] ;; (th/print-result! out) @@ -390,8 +386,7 @@ (t/testing "control: non-member cannot read the library directly" (let [out (th/command! {::th/type :get-file ::rpc/profile-id (:id stranger) - :id (:id lib) - :components-v2 true}) + :id (:id lib)}) error-data (ex-data (:error out))] (t/is (th/ex-info? (:error out))) (t/is (= :not-found (:type error-data))))) @@ -552,7 +547,6 @@ :id n-main :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (frame n-main uuid/zero uuid/zero {:main-instance true :component-root true @@ -575,7 +569,6 @@ :id u-main :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (frame u-main uuid/zero uuid/zero {:main-instance true :component-root true @@ -586,7 +579,6 @@ :id u-child :parent-id u-main :frame-id u-main - :components-v2 true :obj (frame u-child u-main u-main {:main-instance false :component-root true @@ -609,7 +601,6 @@ :id x-main :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (frame x-main uuid/zero uuid/zero {:main-instance true :component-root true @@ -637,7 +628,6 @@ :id inst :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (frame inst uuid/zero uuid/zero {:main-instance false :component-root true @@ -687,7 +677,6 @@ :id main :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id main :name "Board" @@ -733,7 +722,6 @@ :id inst :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id inst :name "Board" @@ -786,7 +774,6 @@ :id b-main :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id b-main :name "Leaf" @@ -826,7 +813,6 @@ :id a-main :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id a-main :name "Wrapper" @@ -842,7 +828,6 @@ :id a-child :parent-id a-main :frame-id a-main - :components-v2 true :obj (cts/setup-shape {:id a-child :name "Leaf" @@ -875,7 +860,6 @@ :id inst :parent-id uuid/zero :frame-id uuid/zero - :components-v2 true :obj (cts/setup-shape {:id inst :name "Wrapper" diff --git a/common/src/app/common/features.cljc b/common/src/app/common/features.cljc index 281ed4c9bb..dbd287d71c 100644 --- a/common/src/app/common/features.cljc +++ b/common/src/app/common/features.cljc @@ -260,40 +260,32 @@ (defn check-teams-compatibility! [{source-features :features} {destination-features :features}] - (when (contains? source-features "ephimeral/migration") - (ex/raise :type :restriction - :code :migration-in-progress - :hint "the source team is in migration process")) + (let [source-features (into #{} xf-remove-ephimeral source-features) + destination-features (into #{} xf-remove-ephimeral destination-features)] - (when (contains? destination-features "ephimeral/migration") - (ex/raise :type :restriction - :code :migration-in-progress - :hint "the destination team is in migration process")) - - (let [not-supported (-> (or source-features #{}) - (set/difference destination-features) - (set/difference no-migration-features) - (set/difference default-features) - (seq))] - (when not-supported - (ex/raise :type :restriction - :code :team-feature-mismatch - :feature (first not-supported) - :hint (str/ffmt "the destination team does not have support '%' features" - (str/join "," not-supported))))) - - (let [not-supported (-> (or destination-features #{}) - (set/difference source-features) - (set/difference no-migration-features) - (set/difference default-features) - (seq))] - (when not-supported - (ex/raise :type :restriction - :code :team-feature-mismatch - :feature (first not-supported) - :hint (str/ffmt "the source team does not have support '%' features" - (str/join "," not-supported)))))) + (let [not-supported (-> source-features + (set/difference destination-features) + (set/difference no-migration-features) + (set/difference default-features) + (seq))] + (when not-supported + (ex/raise :type :restriction + :code :team-feature-mismatch + :feature (first not-supported) + :hint (str/ffmt "the destination team does not have support '%' features" + (str/join "," not-supported))))) + (let [not-supported (-> destination-features + (set/difference source-features) + (set/difference no-migration-features) + (set/difference default-features) + (seq))] + (when not-supported + (ex/raise :type :restriction + :code :team-feature-mismatch + :feature (first not-supported) + :hint (str/ffmt "the source team does not have support '%' features" + (str/join "," not-supported))))))) (defn check-paste-features! "Function used for check feature compability between currently enabled diff --git a/common/src/app/common/files/changes_builder.cljc b/common/src/app/common/files/changes_builder.cljc index 3317d91653..6aa6ad9311 100644 --- a/common/src/app/common/files/changes_builder.cljc +++ b/common/src/app/common/files/changes_builder.cljc @@ -812,33 +812,6 @@ (update :undo-changes conj {:type :add-color :color prev-color}) (apply-changes-local)))) -(defn add-media - [changes object] - (-> changes - (update :redo-changes conj {:type :add-media :object object}) - (update :undo-changes conj {:type :del-media :id (:id object)}) - (apply-changes-local))) - -(defn update-media - [changes object] - (assert-library! changes) - (let [library-data (::library-data (meta changes)) - prev-object (get-in library-data [:media (:id object)])] - (-> changes - (update :redo-changes conj {:type :mod-media :object object}) - (update :undo-changes conj {:type :mod-media :object prev-object}) - (apply-changes-local)))) - -(defn delete-media - [changes id] - (assert-library! changes) - (let [library-data (::library-data (meta changes)) - prev-object (get-in library-data [:media id])] - (-> changes - (update :redo-changes conj {:type :del-media :id id}) - (update :undo-changes conj {:type :add-media :object prev-object}) - (apply-changes-local)))) - (defn add-typography [changes typography] (-> changes diff --git a/common/src/app/common/files/validate.cljc b/common/src/app/common/files/validate.cljc index 280f468d10..f732b4d223 100644 --- a/common/src/app/common/files/validate.cljc +++ b/common/src/app/common/files/validate.cljc @@ -836,38 +836,37 @@ "Validate full referential integrity and semantic coherence on file data. Return a list of errors or `nil`" - [{:keys [data features] :as file} libraries] - (when (contains? features "components/v2") - (binding [*errors* (volatile! [])] + [{:keys [data] :as file} libraries] + (binding [*errors* (volatile! [])] - ;; `reduce-kv` is used throughout this function (and `validate-file-affected`) - ;; instead of `(run! f (vals m))` or `(doseq [[k v] m])` because persistent - ;; maps implement `IKVReduce`, which drives iteration internally without - ;; first materialising an intermediate sequence of key-value pairs. - (reduce-kv - (fn [_ _ page] - (when (some? page) - ;; Both performance caches are scoped to a single page: ref-shape - ;; lookups and parent→children sets are page-local and must never - ;; carry over to the next page. A fresh volatile is created for - ;; each page so stale entries cannot corrupt subsequent pages. - (binding [*ref-shape-cache* (volatile! {}) - *children-sets* (build-children-sets (:objects page))] - (check-shape uuid/zero file page libraries) - (run! #(check-shape % file page libraries) - (get-orphan-shapes page))))) - nil - (:pages-index data)) + ;; `reduce-kv` is used throughout this function (and `validate-file-affected`) + ;; instead of `(run! f (vals m))` or `(doseq [[k v] m])` because persistent + ;; maps implement `IKVReduce`, which drives iteration internally without + ;; first materialising an intermediate sequence of key-value pairs. + (reduce-kv + (fn [_ _ page] + (when (some? page) + ;; Both performance caches are scoped to a single page: ref-shape + ;; lookups and parent→children sets are page-local and must never + ;; carry over to the next page. A fresh volatile is created for + ;; each page so stale entries cannot corrupt subsequent pages. + (binding [*ref-shape-cache* (volatile! {}) + *children-sets* (build-children-sets (:objects page))] + (check-shape uuid/zero file page libraries) + (run! #(check-shape % file page libraries) + (get-orphan-shapes page))))) + nil + (:pages-index data)) - (reduce-kv - (fn [_ _ component] - (check-component component file)) - nil - (:components data)) + (reduce-kv + (fn [_ _ component] + (check-component component file)) + nil + (:components data)) - (check-tokens file) + (check-tokens file) - (-> *errors* deref not-empty)))) + (-> *errors* deref not-empty))) (defn validate-shape "Validate a shape and all its children. Returns a list of errors." @@ -946,34 +945,33 @@ to call on every incremental file update. Returns a list of errors or `nil`." - [{:keys [data features] :as file} libraries changes] - (when (contains? features "components/v2") - (let [{:keys [page-ids component-ids]} (extract-affected-ids changes)] - (binding [*errors* (volatile! [])] + [{:keys [data] :as file} libraries changes] + (let [{:keys [page-ids component-ids]} (extract-affected-ids changes)] + (binding [*errors* (volatile! [])] - (reduce-kv - (fn [_ page-id page] - (when (and (some? page) (contains? page-ids page-id)) - ;; Both performance caches are scoped to a single page: ref-shape - ;; lookups and parent→children sets are page-local and must never - ;; carry over to the next page. A fresh volatile is created for - ;; each page so stale entries cannot corrupt subsequent pages. - (binding [*ref-shape-cache* (volatile! {}) - *children-sets* (build-children-sets (:objects page))] - (check-shape uuid/zero file page libraries) - (run! #(check-shape % file page libraries) - (get-orphan-shapes page))))) - nil - (:pages-index data)) + (reduce-kv + (fn [_ page-id page] + (when (and (some? page) (contains? page-ids page-id)) + ;; Both performance caches are scoped to a single page: ref-shape + ;; lookups and parent→children sets are page-local and must never + ;; carry over to the next page. A fresh volatile is created for + ;; each page so stale entries cannot corrupt subsequent pages. + (binding [*ref-shape-cache* (volatile! {}) + *children-sets* (build-children-sets (:objects page))] + (check-shape uuid/zero file page libraries) + (run! #(check-shape % file page libraries) + (get-orphan-shapes page))))) + nil + (:pages-index data)) - (reduce-kv - (fn [_ id component] - (when (contains? component-ids id) - (check-component component file))) - nil - (:components data)) + (reduce-kv + (fn [_ id component] + (when (contains? component-ids id) + (check-component component file))) + nil + (:components data)) - (-> *errors* deref not-empty))))) + (-> *errors* deref not-empty)))) (defn validate-file-affected! "Like `validate-file-affected` but raises on the first non-empty diff --git a/common/src/app/common/logic/libraries.cljc b/common/src/app/common/logic/libraries.cljc index 688179dc40..9595c3bdd1 100644 --- a/common/src/app/common/logic/libraries.cljc +++ b/common/src/app/common/logic/libraries.cljc @@ -526,48 +526,6 @@ libraries current-file-id))))))))) -(defn generate-sync-library - "Generate changes to synchronize all shapes in all components of the - local library of the given file, that use assets of the given type in - the given library. - - If an asset id is given, only shapes linked to this particular asset will - be synchronized. - - If early-return? is true, stops as soon as the first change is generated." - ([changes file-id asset-type asset-id library-id libraries current-file-id] - (generate-sync-library changes file-id asset-type asset-id library-id libraries current-file-id false)) - ([changes file-id asset-type asset-id library-id libraries current-file-id early-return?] - (assert (contains? #{:colors :components :typographies} asset-type)) - (assert (or (nil? asset-id) (uuid? asset-id))) - (assert (uuid? file-id)) - (assert (uuid? library-id)) - - (container-log :info asset-id - :msg "Sync local components with library" - :asset-type asset-type - :asset-id asset-id - :file (pretty-file file-id libraries current-file-id) - :library (pretty-file library-id libraries current-file-id)) - - (let [file (get-in libraries [file-id :data])] - (loop [local-components (ctkl/components-seq file) - changes changes] - (let [local-component (first local-components)] - (if (or (nil? local-component) - (and early-return? (seq (:redo-changes changes)))) - changes - (recur (next local-components) - (pcb/concat-changes ;;TODO Remove concat changes - changes - (generate-sync-container (pcb/empty-changes nil) - asset-type - asset-id - library-id - (cfh/make-container local-component :component) - libraries - current-file-id))))))))) - (defn- generate-sync-container "Generate changes to synchronize all shapes in a particular container (a page or a component) that use assets of the given type in the given library." @@ -587,9 +545,8 @@ (recur (next shapes) (let [objects' (pcb/get-objects changes) shape' (get objects' (:id shape))] - ;; The shape could have been deleted in previous changes, if this nested component - ;; comes from components-v1 era or if there has been some error with the swap slot. - ;; In that case, we just skip it. + ;; An earlier change of this loop may have deleted the shape (a broken + ;; swap slot can do it); then it is skipped. (if shape' (generate-sync-shape asset-type changes @@ -2772,11 +2729,6 @@ sync-typographies? (or (nil? asset-type) (= asset-type :typographies)) done? (fn [c] (and early-return? (seq (:redo-changes c))))] (-> (pcb/set-undo-group changes undo-group) - ;; library-changes - (maybe-sync sync-components? done? #(generate-sync-library % file-id :components asset-id library-id libraries current-file-id early-return?)) - (maybe-sync sync-colors? done? #(generate-sync-library % file-id :colors asset-id library-id libraries current-file-id early-return?)) - (maybe-sync sync-typographies? done? #(generate-sync-library % file-id :typographies asset-id library-id libraries current-file-id early-return?)) - ;; file-changes (maybe-sync sync-components? done? #(generate-sync-file % file-id :components asset-id library-id libraries current-file-id early-return?)) (maybe-sync sync-colors? done? #(generate-sync-file % file-id :colors asset-id library-id libraries current-file-id early-return?)) (maybe-sync sync-typographies? done? #(generate-sync-file % file-id :typographies asset-id library-id libraries current-file-id early-return?)))))) diff --git a/common/src/app/common/test_helpers/composable/comp/nodes.cljc b/common/src/app/common/test_helpers/composable/comp/nodes.cljc index ec0a2e3906..1e4ff88851 100644 --- a/common/src/app/common/test_helpers/composable/comp/nodes.cljc +++ b/common/src/app/common/test_helpers/composable/comp/nodes.cljc @@ -1881,7 +1881,7 @@ page (:objects page) #{shape-id} - {:components-v2 true}) + {}) file' (thf/apply-changes the-file changes)] (-> situation (tm/with-file file') diff --git a/common/src/app/common/types/component.cljc b/common/src/app/common/types/component.cljc index deb5379e72..4dfc3b58de 100644 --- a/common/src/app/common/types/component.cljc +++ b/common/src/app/common/types/component.cljc @@ -318,9 +318,7 @@ (defn get-deleted-component-root [component] - (if (some? (:main-instance-id component)) - (get-in component [:objects (:main-instance-id component)]) - (get-in component [:objects (:id component)]))) + (get-in component [:objects (:main-instance-id component)])) (defn uses-library-components? "Check if the shape uses any component in the given library." diff --git a/common/src/app/common/types/container.cljc b/common/src/app/common/types/container.cljc index cc7ea9bd07..0274bab41e 100644 --- a/common/src/app/common/types/container.cljc +++ b/common/src/app/common/types/container.cljc @@ -233,7 +233,7 @@ (contains? visited (:id shape)) nil - (nil? (:parent-id shape)) ; This occurs in the root of components v1 + (nil? (:parent-id shape)) ; A shape without parent ends the walk shape (ctk/main-instance? shape) diff --git a/common/src/app/common/types/file.cljc b/common/src/app/common/types/file.cljc index c4ab29e3da..54c71ab5cb 100644 --- a/common/src/app/common/types/file.cljc +++ b/common/src/app/common/types/file.cljc @@ -75,7 +75,6 @@ (def schema:options [:map {:title "FileOptions"} - [:components-v2 {:optional true} ::sm/boolean] [:base-font-size {:optional true} :string]]) (def schema:data @@ -157,8 +156,7 @@ (ctpl/add-page page) :always - (update :options merge {:components-v2 true - :base-font-size BASE-FONT-SIZE}))))) + (update :options merge {:base-font-size BASE-FONT-SIZE}))))) ;; FIXME: we can't handle the "default" migrations for avoid providing ;; them all the time the file is created because we can't import file @@ -221,10 +219,10 @@ (update file :data f))) (defn containers-seq - "Generate a sequence of all pages and all components, wrapped as containers" + "Generate a sequence of all pages, wrapped as containers. Live + components hold no objects: their main instances are page shapes." [file-data] - (concat (map #(ctn/make-container % :page) (ctpl/pages-seq file-data)) - (map #(ctn/make-container % :component) (ctkl/components-seq file-data)))) + (map #(ctn/make-container % :page) (ctpl/pages-seq file-data))) (defn object-containers-seq "Generate a sequence of all pages and all deleted components (all those components that have :objects), wrapped as containers" @@ -707,8 +705,7 @@ assets))) (defn used-in? - "Checks if a specific asset is used in a given file (by any shape in its pages or in - the components of the local library)." + "Checks if a specific asset is used in a given file (by any shape in its pages)." [file-data library-id asset asset-type] (letfn [(used-in-shape? [shape] (uses-asset? asset-type shape library-id asset)) diff --git a/common/test/common_tests/features_test.cljc b/common/test/common_tests/features_test.cljc new file mode 100644 index 0000000000..fafe88b09b --- /dev/null +++ b/common/test/common_tests/features_test.cljc @@ -0,0 +1,34 @@ +;; 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 SUBSIDIARY SL + +(ns common-tests.features-test + (:require + [app.common.features :as cfeat] + [clojure.test :as t])) + +(defn- incompatibility + "The code of the error raised when moving files between two teams + with the given features, or nil when they are compatible." + [source-features destination-features] + (try + (cfeat/check-teams-compatibility! {:features source-features} + {:features destination-features}) + nil + (catch #?(:clj Exception :cljs :default) cause + (:code (ex-data cause))))) + +(t/deftest teams-with-the-same-features-are-compatible + (t/is (nil? (incompatibility cfeat/default-features cfeat/default-features)))) + +(t/deftest a-feature-only-one-team-has-makes-them-incompatible + (let [features (conj cfeat/default-features "test/unknown")] + (t/is (= :team-feature-mismatch (incompatibility features cfeat/default-features))) + (t/is (= :team-feature-mismatch (incompatibility cfeat/default-features features))))) + +(t/deftest ephimeral-features-left-on-a-team-are-ignored + (let [features (conj cfeat/default-features "ephimeral/migration")] + (t/is (nil? (incompatibility features cfeat/default-features))) + (t/is (nil? (incompatibility cfeat/default-features features))))) diff --git a/common/test/common_tests/files/validate_test.cljc b/common/test/common_tests/files/validate_test.cljc index 48fd3e3f07..1d9dcdfd93 100644 --- a/common/test/common_tests/files/validate_test.cljc +++ b/common/test/common_tests/files/validate_test.cljc @@ -71,16 +71,20 @@ :main-instance-page (uuid/next)}))))) ;; ---------------------------------------------------------------- -;; 1. Feature gate +;; 1. Features ;; ---------------------------------------------------------------- -(t/deftest validate-file-affected-no-feature - (t/testing "returns nil when file does not have the components/v2 feature" +(t/deftest validate-file-whatever-its-features + (t/testing "a file without features is validated like any other" (let [file (-> (thf/sample-file :file1 :page-label :page1) - (assoc :features #{})) + (assoc :features #{}) + (inject-broken-child :page1)) page-id (thi/id :page1) changes [{:type :add-obj :page-id page-id :id (uuid/next)}]] - (t/is (nil? (cfv/validate-file-affected file {} changes)))))) + (t/is (some #(= :child-not-found (:code %)) + (cfv/validate-file-affected file {} changes))) + (t/is (some #(= :child-not-found (:code %)) + (cfv/validate-file file {})))))) ;; ---------------------------------------------------------------- ;; 2. Empty changes – nothing to validate diff --git a/common/test/common_tests/logic/comp_creation_test.cljc b/common/test/common_tests/logic/comp_creation_test.cljc index 76571b4d45..0447226b77 100644 --- a/common/test/common_tests/logic/comp_creation_test.cljc +++ b/common/test/common_tests/logic/comp_creation_test.cljc @@ -380,7 +380,7 @@ page (:objects page) #{(:id root)} - {:components-v2 true}) + {}) file' (thf/apply-changes file changes) @@ -421,7 +421,7 @@ page (:objects page) #{(:id root)} - {:components-v2 true}) + {}) file-deleted (thf/apply-changes file changes) page-deleted (thf/current-page file-deleted) @@ -465,7 +465,7 @@ page2 (:objects page2) #{(:id root)} - {:components-v2 true}) + {}) file (-> (thf/apply-changes file changes) (ctf/update-file-data #(ctpl/delete-page % (:id page2)))) changes (cll/generate-restore-component (pcb/empty-changes) diff --git a/common/test/common_tests/logic/comp_reset_test.cljc b/common/test/common_tests/logic/comp_reset_test.cljc index d9491271a3..6df4ca8f47 100644 --- a/common/test/common_tests/logic/comp_reset_test.cljc +++ b/common/test/common_tests/logic/comp_reset_test.cljc @@ -187,7 +187,7 @@ page (:objects page) #{(:id copy-child)} - {:components-v2 true}) + {}) file-mdf (thf/apply-changes file changes) page-mdf (thf/current-page file-mdf) diff --git a/common/test/common_tests/logic/comp_sync_test.cljc b/common/test/common_tests/logic/comp_sync_test.cljc index a929c7a616..84397671de 100644 --- a/common/test/common_tests/logic/comp_sync_test.cljc +++ b/common/test/common_tests/logic/comp_sync_test.cljc @@ -253,7 +253,7 @@ page (:objects page) #{(:id main-child)} - {:components-v2 true}) + {}) updated-file (thf/apply-changes file changes1) diff --git a/common/test/common_tests/logic/comp_touched_test.cljc b/common/test/common_tests/logic/comp_touched_test.cljc index b31874d128..ff8ec9181a 100644 --- a/common/test/common_tests/logic/comp_touched_test.cljc +++ b/common/test/common_tests/logic/comp_touched_test.cljc @@ -154,7 +154,7 @@ page (:objects page) #{(:id copy-child)} - {:components-v2 true}) + {}) file' (thf/apply-changes file changes) diff --git a/common/test/common_tests/runner.cljc b/common/test/common_tests/runner.cljc index 73916b7d6c..84b62b4fbf 100644 --- a/common/test/common_tests/runner.cljc +++ b/common/test/common_tests/runner.cljc @@ -16,6 +16,7 @@ [common-tests.buffer-test] [common-tests.colors-test] [common-tests.data-test] + [common-tests.features-test] [common-tests.files-builder-test] [common-tests.files-changes-test] [common-tests.files-migrations-0025-test] @@ -129,6 +130,7 @@ 'common-tests.buffer-test 'common-tests.colors-test 'common-tests.data-test + 'common-tests.features-test 'common-tests.files-builder-test 'common-tests.files-changes-test 'common-tests.files-migrations-0025-test diff --git a/frontend/resources/images/icons/v2-icon-1.svg b/frontend/resources/images/icons/v2-icon-1.svg deleted file mode 100644 index b39647eb1c..0000000000 --- a/frontend/resources/images/icons/v2-icon-1.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/frontend/resources/images/icons/v2-icon-2.svg b/frontend/resources/images/icons/v2-icon-2.svg deleted file mode 100644 index d384ee2ed3..0000000000 --- a/frontend/resources/images/icons/v2-icon-2.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/frontend/resources/images/icons/v2-icon-3.svg b/frontend/resources/images/icons/v2-icon-3.svg deleted file mode 100644 index bfc88da6d5..0000000000 --- a/frontend/resources/images/icons/v2-icon-3.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/frontend/resources/images/icons/v2-icon-4.svg b/frontend/resources/images/icons/v2-icon-4.svg deleted file mode 100644 index dc2443432b..0000000000 --- a/frontend/resources/images/icons/v2-icon-4.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index e86a0c6243..7b03d0b8d5 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -242,62 +242,6 @@ (pcb/add-color new-color))] (rx/of (dch/commit-changes changes)))))) -;; FIXME: this should be deleted -(defn add-media - [media] - (let [media (ctf/check-file-media media)] - (ptk/reify ::add-media - ev/Event - (-data [_] media) - - ptk/WatchEvent - (watch [it _ _] - (let [obj (select-keys media [:id :name :width :height :mtype]) - changes (-> (pcb/empty-changes it) - (pcb/add-media obj))] - (rx/of (dch/commit-changes changes))))))) - -(defn rename-media - [id new-name] - - (dm/assert! - "expected valid uuid for `id`" - (uuid? id)) - - (dm/assert! - "expected valid string for `new-name`" - (string? new-name)) - - (ptk/reify ::rename-media - ptk/WatchEvent - (watch [it state _] - (let [new-name (str/trim new-name)] - (if (str/empty? new-name) - (rx/empty) - (let [[path name] (cpn/split-group-name new-name) - data (dsh/lookup-file-data state) - object (get-in data [:media id]) - new-object (assoc object :path path :name name) - changes (-> (pcb/empty-changes it) - (pcb/with-library-data data) - (pcb/update-media new-object))] - (rx/of (dch/commit-changes changes)))))))) - -(defn delete-media - [{:keys [id]}] - (assert (uuid? id) "expected valid uuid for `id`") - (ptk/reify ::delete-media - ev/Event - (-data [_] {:id id}) - - ptk/WatchEvent - (watch [it state _] - (let [data (dsh/lookup-file-data state) - changes (-> (pcb/empty-changes it) - (pcb/with-library-data data) - (pcb/delete-media id))] - (rx/of (dch/commit-changes changes)))))) - (defn add-typography ([typography] (add-typography typography true)) ([typography edit?] diff --git a/frontend/src/app/main/errors.cljs b/frontend/src/app/main/errors.cljs index 928722f889..c018b787de 100644 --- a/frontend/src/app/main/errors.cljs +++ b/frontend/src/app/main/errors.cljs @@ -810,11 +810,6 @@ (defmethod ptk/handle-error :restriction [{:keys [code] :as error}] (cond - (= :migration-in-progress code) - (let [message (tr "errors.migration-in-progress" (:feature error)) - on-accept (constantly nil)] - (st/emit! (modal/show {:type :alert :message message :on-accept on-accept}))) - (= :team-feature-mismatch code) (let [message (tr "errors.team-feature-mismatch" (:feature error)) on-accept (constantly nil)] diff --git a/frontend/src/app/main/render.cljs b/frontend/src/app/main/render.cljs index 4a45630454..9851c40592 100644 --- a/frontend/src/app/main/render.cljs +++ b/frontend/src/app/main/render.cljs @@ -49,12 +49,10 @@ [app.main.ui.shapes.text.fontfaces :as ff] [app.render-wasm.api :as wasm.api] [app.util.dom :as dom] - [app.util.http :as http] [app.util.strings :as ust] [app.util.thumbnails :as th] [app.util.timers :as ts] [beicon.v2.core :as rx] - [clojure.set :as set] [cuerdas.core :as str] [promesa.core :as p] [rumext.v2 :as mf])) @@ -575,8 +573,7 @@ [{:keys [component] :as props}] (let [name (:name component) path (:path component) - root-id (or (:main-instance-id component) - (:id component)) + root-id (:main-instance-id component) orig-root (get (:objects component) root-id) objects (adapt-objects-for-shape (:objects component) root-id) @@ -646,80 +643,6 @@ ;; RENDER FOR DOWNLOAD (wrongly called exportation) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -(defn- get-image-data [shape] - (cond - (= :image (:type shape)) - [(:metadata shape)] - - (some? (:fill-image shape)) - [(:fill-image shape)] - - :else - [])) - -(defn- populate-images-cache - [objects] - (let [images (->> objects - (vals) - (mapcat get-image-data))] - (->> (rx/from images) - (rx/map #(cfg/resolve-file-media %)) - (rx/merge-map http/fetch-data-uri)))) - -(defn populate-fonts-cache [objects] - (let [texts (->> objects - (vals) - (filterv #(= (:type %) :text)) - (mapv :content))] - - (->> (rx/from texts) - (rx/map fonts/get-content-fonts) - (rx/reduce set/union #{}) - (rx/merge-map identity) - (rx/merge-map fonts/fetch-font-css) - (rx/merge-map fonts/extract-fontface-urls) - (rx/merge-map http/fetch-data-uri)))) - -(defn render-page - [data] - (rx/concat - (->> (rx/merge - (populate-images-cache (:objects data)) - (populate-fonts-cache (:objects data))) - (rx/ignore)) - - (->> (rx/of data) - (rx/map - (fn [data] - (let [elem (mf/element page-svg #js {:data data :embed true :include-metadata true})] - (rds/renderToStaticMarkup elem))))))) - -(defn render-components - [data deleted?] - (let [;; Join all components objects into a single map - components (if (not deleted?) - (ctkl/components-seq data) - (ctkl/deleted-components-seq data)) - objects (->> components - (map (partial ctf/load-component-objects data)) - (map :objects) - (reduce conj))] - (rx/concat - (->> (rx/merge - (populate-images-cache objects) - (populate-fonts-cache objects)) - (rx/ignore)) - - (->> (rx/of data) - (rx/map - (fn [data] - (let [elem (mf/element components-svg - #js {:data data - :embed true - :include-metadata true - :deleted? deleted?})] - (rds/renderToStaticMarkup elem)))))))) - (defn render-frame ([objects shape object-id] (render-frame objects shape object-id nil)) diff --git a/frontend/src/app/main/ui/icons.cljs b/frontend/src/app/main/ui/icons.cljs index 9e62720d02..e6ad4cced9 100644 --- a/frontend/src/app/main/ui/icons.cljs +++ b/frontend/src/app/main/ui/icons.cljs @@ -273,10 +273,6 @@ (def ^:icon tree (icon-xref :tree)) (def ^:icon unlock (icon-xref :unlock)) (def ^:icon user (icon-xref :user)) -(def ^:icon v2-icon-1 (icon-xref :v2-icon-1)) -(def ^:icon v2-icon-2 (icon-xref :v2-icon-2)) -(def ^:icon v2-icon-3 (icon-xref :v2-icon-3)) -(def ^:icon v2-icon-4 (icon-xref :v2-icon-4)) (def ^:icon variant (icon-xref :variant)) (def ^:icon vertical-align-items-center (icon-xref :vertical-align-items-center)) (def ^:icon vertical-align-items-end (icon-xref :vertical-align-items-end)) diff --git a/frontend/src/app/main/ui/workspace/libraries.cljs b/frontend/src/app/main/ui/workspace/libraries.cljs index ca7d530203..9d115d5b30 100644 --- a/frontend/src/app/main/ui/workspace/libraries.cljs +++ b/frontend/src/app/main/ui/workspace/libraries.cljs @@ -21,7 +21,6 @@ [app.main.data.dashboard :as dd] [app.main.data.modal :as modal] [app.main.data.notifications :as ntf] - [app.main.data.profile :as du] [app.main.data.team :as dtm] [app.main.data.workspace.colors :as mdc] [app.main.data.workspace.libraries :as dwl] @@ -41,7 +40,6 @@ [app.main.ui.ds.layout.tab-switcher :refer [tab-switcher*]] [app.main.ui.ds.product.empty-state :refer [empty-state*]] [app.main.ui.hooks :as h] - [app.main.ui.icons :as deprecated-icon] [app.main.ui.workspace.tokens.import-from-library] [app.util.color :as uc] [app.util.dom :as dom] @@ -1206,59 +1204,3 @@ :is-legacy (not token-lib-sync?) :libraries linked-libraries}])]]])) -(mf/defc v2-info-dialog - {::mf/register modal/components - ::mf/register-as :v2-info} - [] - (let [handle-gotit-click - (mf/use-fn - (fn [] - (modal/hide!) - (st/emit! (du/update-profile-props {:v2-info-shown true}))))] - - [:div {:class (stl/css :modal-overlay)} - [:div {:class (stl/css :modal-dialog :modal-v2-info)} - [:div {:class (stl/css :modal-v2-title)} - "IMPORTANT INFORMATION ABOUT NEW COMPONENTS"] - [:div {:class (stl/css :modal-content)} - [:div {:class (stl/css :info-content)} - [:div {:class (stl/css :info-block)} - [:div {:class (stl/css :info-icon)} deprecated-icon/v2-icon-1] - [:div {:class (stl/css :info-block-title)} - "One physical source of truth"] - [:div {:class (stl/css :info-block-content)} - "Main components are now found at the design space. They act as a single source " - "of truth and can be worked on with their copies. This ensures consistency and " - "allows better control and synchronization."]] - - [:div {:class (stl/css :info-block)} - [:div {:class (stl/css :info-icon)} deprecated-icon/v2-icon-2] - [:div {:class (stl/css :info-block-title)} - "Swap components"] - [:div {:class (stl/css :info-block-content)} - "Now, you can replace one component copy with another within your libraries. " - "The swap components functionality streamlines making changes, testing " - "variations, or updating elements without extensive manual adjustments."]] - - [:div {:class (stl/css :info-block)} - [:div {:class (stl/css :info-icon)} deprecated-icon/v2-icon-3] - [:div {:class (stl/css :info-block-title)} - "Graphic assets no longer exist"] - [:div {:class (stl/css :info-block-content)} - "Graphic assets now disappear, so that all graphic assets become components. " - "This way, swapping between them is possible, and we avoid confusion about " - "what should go in each typology."]] - - [:div {:class (stl/css :info-block)} - [:div {:class (stl/css :info-icon)} deprecated-icon/v2-icon-4] - [:div {:class (stl/css :info-block-title)} - "Main components page"] - [:div {:class (stl/css :info-block-content)} - "You might find that a new page called 'Main components' has appeared in " - "your file. On that page, you'll find all the main components that were " - "created in your files previously to this new version."]]] - - [:div {:class (stl/css :info-bottom)} - [:> button* {:class (stl/css :primary-button) - :variant "primary" - :on-click handle-gotit-click} "I GOT IT"]]]]])) diff --git a/frontend/src/app/main/ui/workspace/libraries.scss b/frontend/src/app/main/ui/workspace/libraries.scss index 6dc6dfcec1..5035260e96 100644 --- a/frontend/src/app/main/ui/workspace/libraries.scss +++ b/frontend/src/app/main/ui/workspace/libraries.scss @@ -354,79 +354,6 @@ padding-inline: var(--sp-xxs) px2rem(6); } -// Modal Component v2 update -.modal-v2-info { - width: px2rem(664); - height: fit-content; - max-height: fit-content; -} - -.modal-v2-title { - @include t.use-typography("headline-medium"); - - color: var(--modal-title-foreground-color); -} - -.info-content { - display: grid; - grid-template-rows: repeat(4, 1fr); - margin-top: var(--sp-xxxl); - gap: var(--sp-xxl); -} - -.info-block { - display: grid; - column-gap: var(--sp-xl); - grid-template: - "icon title" auto - "icon content" auto / auto 1fr; -} - -.info-icon { - grid-area: icon; - width: px2rem(52); - height: px2rem(52); - margin-top: var(--sp-s); - border-radius: $br-circle; - background: var(--color-background-quaternary); - display: flex; - justify-content: center; - align-items: center; - - svg { - width: $sz-32; - height: $sz-32; - fill: var(--icon-foreground-active); - } -} - -.info-block-title { - @include t.use-typography("body-large"); - - grid-area: title; - color: var(--modal-title-foreground-color); -} - -.info-block-content { - @include t.use-typography("body-medium"); - - grid-area: content; - color: var(--library-content-foreground-color); -} - -.info-bottom { - display: flex; - justify-content: flex-end; - margin-block-start: var(--sp-xxl); - margin-inline-end: var(--sp-s); -} - -.primary-button { - @include t.use-typography("headline-small"); - - padding: 0 var(--sp-l); -} - .sample-libraries-info { @include t.use-typography("body-small"); diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/colors.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/colors.cljs index e1e70bb2e4..56eddbfbfb 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/colors.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/colors.cljs @@ -395,7 +395,6 @@ multi-colors? (> (count selected) 1) multi-assets? (or (seq (:components selected)) - (seq (:graphics selected)) (seq (:typographies selected))) groups (mf/with-memo [colors is-reverse-sort] diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs index ab1bfb1137..dc1b566385 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs @@ -339,8 +339,7 @@ selected-full (into #{} (filter #(contains? selected (:id %))) components) multi-components? (> (count selected) 1) - multi-assets? (or (seq (:graphics selected)) - (seq (:colors selected)) + multi-assets? (or (seq (:colors selected)) (seq (:typographies selected))) selected-and-current (mf/with-memo [selected components current-component-id] diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/file_library.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/file_library.cljs index 8596dfd11a..c63d7cf273 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/file_library.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/file_library.cljs @@ -244,8 +244,6 @@ (st/emit! (dwu/start-undo-transaction undo-id)) (run! st/emit! (map delete-component (:components selected))) - (run! st/emit! (map #(dwl/delete-media {:id %}) - (:graphics selected))) (run! st/emit! (map #(dwl/delete-color {:id %}) (:colors selected))) (run! st/emit! (map #(dwl/delete-typography %) diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets/typographies.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets/typographies.cljs index f9ec09486f..0de5691291 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/typographies.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/typographies.cljs @@ -328,7 +328,6 @@ multi-typographies? (> (count selected) 1) multi-assets? (or (seq (:components selected)) - (seq (:graphics selected)) (seq (:colors selected))) open-groups-ref (mf/with-memo [open-status-ref] diff --git a/frontend/test/frontend_tests/helpers/pages.cljs b/frontend/test/frontend_tests/helpers/pages.cljs index b1a82e46da..90e1bfd5a2 100644 --- a/frontend/test/frontend_tests/helpers/pages.cljs +++ b/frontend/test/frontend_tests/helpers/pages.cljs @@ -35,7 +35,6 @@ {current-file-id {:id current-file-id :data {:id current-file-id - :options {:components-v2 true} :components {} :pages [] :pages-index {}}}} diff --git a/frontend/translations/ca.po b/frontend/translations/ca.po index 2c3702dc0c..05f9dbe092 100644 --- a/frontend/translations/ca.po +++ b/frontend/translations/ca.po @@ -1686,10 +1686,6 @@ msgstr "" "El perfil que estàs convidant té els missatges de correu silenciats (per " "informes de correu brossa o de retorns alts)." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "Migració en curs" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "Només la persona creadora de la versió la pot bloquejar" diff --git a/frontend/translations/cs.po b/frontend/translations/cs.po index 6807d634eb..126a6c1bc3 100644 --- a/frontend/translations/cs.po +++ b/frontend/translations/cs.po @@ -998,10 +998,6 @@ msgstr "" "Profil, který zvete, má ztlumené e-maily (zprávy o spamu nebo vysoké " "nedoručitelnosti)." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "Probíhá migrace" - #: src/app/main/ui/auth/recovery.cljs:25, src/app/main/ui/settings/password.cljs:73 msgid "errors.password-invalid-confirmation" msgstr "Potvrzovací heslo se musí shodovat" diff --git a/frontend/translations/de.po b/frontend/translations/de.po index b535d2d859..d7504d45ad 100644 --- a/frontend/translations/de.po +++ b/frontend/translations/de.po @@ -1403,10 +1403,6 @@ msgstr "" "In dem von Ihnen eingeladenen Profil sind E-Mails stummgeschaltet " "(Spam-Berichte oder hohe Unzustellbarkeitsberichte)." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "Migration wird durchgeführt" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "Nur der Ersteller der Version kann sie sperren" diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 61d7dbc5ec..d85300766a 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -1679,10 +1679,6 @@ msgstr "Seems that this is not a valid image." msgid "errors.member-is-muted" msgstr "The profile you inviting has emails muted (spam reports or high bounces)." -#: src/app/main/errors.cljs:814 -msgid "errors.migration-in-progress" -msgstr "Migration in progress" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "Only the version creator can lock it" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index e8c0c37225..70caa4d1b3 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -1701,10 +1701,6 @@ msgstr "" "El perfil que esta invitando tiene los emails silenciados (por reportes de " "spam o alto índice de rebote)." -#: src/app/main/errors.cljs:814 -msgid "errors.migration-in-progress" -msgstr "Migración en proceso" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "Solo el creador de la versión puede bloquearla" diff --git a/frontend/translations/fa.po b/frontend/translations/fa.po index 2acda65b41..df9f20fe97 100644 --- a/frontend/translations/fa.po +++ b/frontend/translations/fa.po @@ -1663,10 +1663,6 @@ msgstr "" "پروفایلی که دعوت می‌کنید ارسال ایمیل برایش غیرفعال شده است (گزارش‌های " "هرزنامه یا برگشت‌های زیاد)." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "مهاجرت در حال انجام است" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "فقط ایجادکنندهٔ نسخه می‌تواند آن را قفل کند" diff --git a/frontend/translations/fr.po b/frontend/translations/fr.po index 507dfc85bb..d78a5e23f6 100644 --- a/frontend/translations/fr.po +++ b/frontend/translations/fr.po @@ -1709,10 +1709,6 @@ msgstr "" "L'adresse e-mail du profil que vous invitez est ignorée (signalée comme " "spam ou taux de rebond élevé)." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "Migration en cours" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "Seul le créateur d'une version peut la verrouiller" diff --git a/frontend/translations/fr_CA.po b/frontend/translations/fr_CA.po index 65470f996a..bed7203b4e 100644 --- a/frontend/translations/fr_CA.po +++ b/frontend/translations/fr_CA.po @@ -1575,10 +1575,6 @@ msgstr "" "Le profil invité a tu ses courriels (selon les rapports de pourriels ou un " "haut taux de rebond)." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "Migration en cours" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "Seul le créateur de la version peut la vérouiller" diff --git a/frontend/translations/he.po b/frontend/translations/he.po index 468980a6f6..57a8e3aa03 100644 --- a/frontend/translations/he.po +++ b/frontend/translations/he.po @@ -1528,10 +1528,6 @@ msgstr "נראה כי זאת תמונה שגויה." msgid "errors.member-is-muted" msgstr "הודעות הדוא״ל לפרופיל שהזמנת מושתקות (דיווחים על דואר זבל או הרבה החזרות)." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "מתבצעת הסבה" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "רק יוצר או יוצרת הגרסה יכולים לנעול אותה" diff --git a/frontend/translations/hi.po b/frontend/translations/hi.po index b55d4239cd..3241551090 100644 --- a/frontend/translations/hi.po +++ b/frontend/translations/hi.po @@ -1247,10 +1247,6 @@ msgstr "" "जिस प्रोफाइल को आप निमंत्रित कर रहे हैं उसके ईमेल म्यूट किए गए हैं (स्पैम " "रिपोर्ट्स या उच्च बाउंस के कारण)।" -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "माइग्रेशन प्रगति पर है" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "केवल संस्करण निर्माता ही इसे लॉक कर सकता है" diff --git a/frontend/translations/hr.po b/frontend/translations/hr.po index b3c94b2d6a..19e4ab8fe6 100644 --- a/frontend/translations/hr.po +++ b/frontend/translations/hr.po @@ -995,10 +995,6 @@ msgstr "" "Profil koji pozivaš ima isključen e-email (izvješća o neželjenoj pošti ili " "veliki broj odbijanja)." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "Migracija u tijeku" - #: src/app/main/ui/auth/recovery.cljs:25, src/app/main/ui/settings/password.cljs:73 msgid "errors.password-invalid-confirmation" msgstr "Lozinka za potvrdu mora odgovarati" diff --git a/frontend/translations/id.po b/frontend/translations/id.po index 03058d1683..6720c5183e 100644 --- a/frontend/translations/id.po +++ b/frontend/translations/id.po @@ -1053,10 +1053,6 @@ msgstr "" "Profil yang Anda undang membisukan surel (laporan spam atau lompatan " "tinggi)." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "Migrasi sedang berlangsung" - #: src/app/main/ui/auth/recovery.cljs:25, src/app/main/ui/settings/password.cljs:73 msgid "errors.password-invalid-confirmation" msgstr "Kata sandi konfirmasi harus cocok" diff --git a/frontend/translations/it.po b/frontend/translations/it.po index 992dc61a58..9668c3522c 100644 --- a/frontend/translations/it.po +++ b/frontend/translations/it.po @@ -1549,10 +1549,6 @@ msgstr "" "Il profilo che stai invitando ha le email disattivate (rapporti di spam o " "alti tassi di rimbalzo)." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "Migrazione in corso" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "Solo il creatore della versione può bloccarla" diff --git a/frontend/translations/jpn_JP.po b/frontend/translations/jpn_JP.po index 1d633bb75d..fd01be3ee9 100644 --- a/frontend/translations/jpn_JP.po +++ b/frontend/translations/jpn_JP.po @@ -1631,10 +1631,6 @@ msgstr "有効な画像ではないようです。" msgid "errors.member-is-muted" msgstr "招待しようとしているユーザーは、メールがミュートされています(スパム報告または配信エラーの多発)。" -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "移行中です" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "このバージョンをロックできるのは作成者のみです" diff --git a/frontend/translations/ko.po b/frontend/translations/ko.po index fdb131f37d..0a2cff6d8f 100644 --- a/frontend/translations/ko.po +++ b/frontend/translations/ko.po @@ -1265,10 +1265,6 @@ msgstr "유효한 이미지가 아닌 것 같습니다." msgid "errors.member-is-muted" msgstr "초대하려는 프로필의 이메일 수신이 거부되었습니다(스팸 신고 또는 높은 반송률)." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "마이그레이션 진행 중" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "버전 생성자만 잠글 수 있습니다" diff --git a/frontend/translations/lv.po b/frontend/translations/lv.po index 6f2f7b95a9..bc66d367bb 100644 --- a/frontend/translations/lv.po +++ b/frontend/translations/lv.po @@ -1183,10 +1183,6 @@ msgstr "" "Uzaicinātajam profilam ir apklusināta e-pasta saņemšana (ziņojumi par " "surogātpastu vai daudz atlēcienu)." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "Notiek pārcelšana" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "Tikai versijas izveidotājs var to aizslēgt" diff --git a/frontend/translations/nl.po b/frontend/translations/nl.po index 1de2d611ec..9c3ac4d71f 100644 --- a/frontend/translations/nl.po +++ b/frontend/translations/nl.po @@ -1685,10 +1685,6 @@ msgstr "" "Het profiel dat je uitnodigt, heeft e-mails gedempt (spammeldingen of hoge " "bounces)." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "Migratie aan de gang" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "Alleen de maker van de versie kan het vergrendelen" diff --git a/frontend/translations/pt_BR.po b/frontend/translations/pt_BR.po index 3c27a3205f..0158a6c71d 100644 --- a/frontend/translations/pt_BR.po +++ b/frontend/translations/pt_BR.po @@ -1155,10 +1155,6 @@ msgstr "" "O perfil que você está convidando tem e-mails silenciados (relatos de spam " "ou altas devoluções)." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "Migração em progresso" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "Somente o criador da versão pode bloqueá-la" diff --git a/frontend/translations/pt_PT.po b/frontend/translations/pt_PT.po index 3140b7a1a6..1a11db7b7f 100644 --- a/frontend/translations/pt_PT.po +++ b/frontend/translations/pt_PT.po @@ -1003,10 +1003,6 @@ msgstr "" "O perfil que estás a convidar tem e-mails silenciados (relatórios de spam " "ou devoluções altas)." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "Migração em progresso" - #: src/app/main/ui/auth/recovery.cljs:25, src/app/main/ui/settings/password.cljs:73 msgid "errors.password-invalid-confirmation" msgstr "A palavra-passe de confirmação tem de corresponder" diff --git a/frontend/translations/ro.po b/frontend/translations/ro.po index d4b4fc6751..71b7d30bcb 100644 --- a/frontend/translations/ro.po +++ b/frontend/translations/ro.po @@ -1170,10 +1170,6 @@ msgstr "" "Profilul pe care încerci să îl inviți este dezactivat (din cauza " "rapoartelor spam sau inactivitate)." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "Migrație în progres" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "Doar creatorul versiunii poate bloca" diff --git a/frontend/translations/ru.po b/frontend/translations/ru.po index 72cd5b5d4b..80aa8d64e3 100644 --- a/frontend/translations/ru.po +++ b/frontend/translations/ru.po @@ -1317,10 +1317,6 @@ msgstr "Неверное медиа." msgid "errors.member-is-muted" msgstr "Невозможно пригласить адресата с недоступным адресом электронной почты." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "Миграция в процессе" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "Только создатель версии может ее заблокировать" diff --git a/frontend/translations/sv.po b/frontend/translations/sv.po index b74e6d85a0..5da82133ce 100644 --- a/frontend/translations/sv.po +++ b/frontend/translations/sv.po @@ -1670,10 +1670,6 @@ msgstr "" "Den profil du bjuder in har e-postmeddelanden som är avstängda " "(skräppostrapporter eller höga studsar)." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "Migrering pågår" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "Endast skaparen av versionen kan låsa den" diff --git a/frontend/translations/tr.po b/frontend/translations/tr.po index 82cd5fe9a6..63b1872e81 100644 --- a/frontend/translations/tr.po +++ b/frontend/translations/tr.po @@ -1672,10 +1672,6 @@ msgstr "" "Davet ettiğiniz profilin e-posta adresine ait çok fazla geri dönme raporu " "var veya spam olarak bildirilmiş." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "Geçiş devam ediyor" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "Yalnızca sürüm oluşturucu onu kilitleyebilir" diff --git a/frontend/translations/ukr_UA.po b/frontend/translations/ukr_UA.po index e716947918..2d68128057 100644 --- a/frontend/translations/ukr_UA.po +++ b/frontend/translations/ukr_UA.po @@ -1457,10 +1457,6 @@ msgstr "" "Електронна пошта профілю, який Ви намагаєтесь запросити, має приглушення " "листів (скарги на спам або постійне пересилання)." -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "Міграція триває" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "Тільки власник версії може заблокувати її" diff --git a/frontend/translations/zh_CN.po b/frontend/translations/zh_CN.po index 94376eaabc..c5cabdf348 100644 --- a/frontend/translations/zh_CN.po +++ b/frontend/translations/zh_CN.po @@ -1380,10 +1380,6 @@ msgstr "该图片好像不可用。" msgid "errors.member-is-muted" msgstr "受邀用户已停用邮件通知(曾举报垃圾邮件或多次发生退信)。" -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "迁移正在进行中" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "只有版本创建者可以锁定" diff --git a/frontend/translations/zh_Hant.po b/frontend/translations/zh_Hant.po index 94bb9de6fa..36f4421274 100644 --- a/frontend/translations/zh_Hant.po +++ b/frontend/translations/zh_Hant.po @@ -1579,10 +1579,6 @@ msgstr "這似乎不是有效的圖片。" msgid "errors.member-is-muted" msgstr "您邀請的使用者已因垃圾郵件檢舉或退信率過高而暫停接收電子郵件。" -#: src/app/main/errors.cljs:805 -msgid "errors.migration-in-progress" -msgstr "正在進行資料遷移" - #: src/app/main/errors.cljs:707 msgid "errors.only-creator-can-lock" msgstr "只有此版本的建立者可以鎖定此版本"