From a2f466810b9a0f2cb560d76b9b67833d8cc884f9 Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Mon, 9 Sep 2024 20:48:05 +0200 Subject: [PATCH] :recycle: Add minor refactor on set-plugin-data change --- common/src/app/common/files/changes.cljc | 60 +++++++++++++------ .../src/app/common/files/changes_builder.cljc | 48 +++++++++++---- common/src/app/common/schema/generators.cljc | 5 +- .../test/common_tests/file_changes_test.cljc | 21 +++++++ common/test/common_tests/uuid_test.cljc | 18 ------ frontend/src/app/main/data/workspace.cljs | 2 +- 6 files changed, 103 insertions(+), 51 deletions(-) delete mode 100644 common/test/common_tests/uuid_test.cljc diff --git a/common/src/app/common/files/changes.cljc b/common/src/app/common/files/changes.cljc index 4f8bee8c3..2ed1ab257 100644 --- a/common/src/app/common/files/changes.cljc +++ b/common/src/app/common/files/changes.cljc @@ -115,6 +115,45 @@ change))))] [:schema {:gen/gen gen} schema])) + +(def schema:set-plugin-data-change + (let [types #{:file :page :shape :color :typography :component} + + schema [:map {:title "SetPagePluginData"} + [:type [:= :set-plugin-data]] + [:object-type [::sm/one-of types]] + ;; It's optional because files don't need the id for type :file + [:object-id {:optional true} ::sm/uuid] + [:page-id {:optional true} ::sm/uuid] + [:namespace {:gen/gen (sg/word-keyword)} :keyword] + [:key {:gen/gen (sg/word-string)} :string] + [:value [:maybe [:string {:gen/gen (sg/word-string)}]]]] + + check1 [:fn {:error/path [:page-id] + :error/message "missing page-id"} + (fn [{:keys [object-type] :as change}] + (if (= :shape object-type) + (uuid? (:page-id change)) + true))] + + gen (->> (sg/generator schema) + (sg/filter :object-id) + (sg/filter :page-id) + (sg/fmap (fn [{:keys [object-type] :as change}] + (cond + (= :file object-type) + (-> change + (dissoc :object-id) + (dissoc :page-id)) + + (= :shape object-type) + change + + :else + (dissoc change :page-id)))))] + + [:and {:gen/gen gen} schema check1])) + (def schema:change [:schema [:multi {:dispatch :type @@ -220,17 +259,7 @@ [:background {:optional true} [:maybe ::ctc/rgb-color]] [:name {:optional true} :string]]] - [:mod-plugin-data - [:map {:title "ModPagePluginData"} - [:type [:= :mod-plugin-data]] - [:object-type [::sm/one-of #{:file :page :shape :color :typography :component}]] - ;; It's optional because files don't need the id for type :file - [:object-id {:optional true} [:maybe ::sm/uuid]] - ;; Only needed in type shape - [:page-id {:optional true} [:maybe ::sm/uuid]] - [:namespace :keyword] - [:key :string] - [:value [:maybe :string]]]] + [:set-plugin-data schema:set-plugin-data-change] [:del-page [:map {:title "DelPageChange"} @@ -736,16 +765,13 @@ (nil? bg) (dissoc :background)))))) -(defmethod process-change :mod-plugin-data +(defmethod process-change :set-plugin-data [data {:keys [object-type object-id page-id namespace key value]}] - - (when (and (= object-type :shape) (nil? page-id)) - (ex/raise :type :internal :hint "update for shapes needs a page-id")) - (letfn [(update-fn [data] (if (some? value) (assoc-in data [:plugin-data namespace key] value) - (update-in data [:plugin-data namespace] (fnil dissoc {}) key)))] + (update-in data [:plugin-data namespace] dissoc key)))] + (case object-type :file (update-fn data) diff --git a/common/src/app/common/files/changes_builder.cljc b/common/src/app/common/files/changes_builder.cljc index 4aa995ee8..ce593e8a4 100644 --- a/common/src/app/common/files/changes_builder.cljc +++ b/common/src/app/common/files/changes_builder.cljc @@ -214,35 +214,60 @@ (update :undo-changes conj undo) (apply-changes-local))))) -(defn mod-plugin-data +(defn set-plugin-data ([changes namespace key value] - (mod-plugin-data changes :file nil nil namespace key value)) + (set-plugin-data changes :file nil nil namespace key value)) ([changes type id namespace key value] - (mod-plugin-data changes type id nil namespace key value)) + (set-plugin-data changes type id nil namespace key value)) ([changes type id page-id namespace key value] (let [data (::file-data (meta changes)) old-val (case type :file - (get-in data [:plugin-data namespace key]) + (dm/get-in data [:plugin-data namespace key]) :page - (get-in data [:pages-index id :options :plugin-data namespace key]) + (dm/get-in data [:pages-index id :options :plugin-data namespace key]) :shape - (get-in data [:pages-index page-id :objects id :plugin-data namespace key]) + (dm/get-in data [:pages-index page-id :objects id :plugin-data namespace key]) :color - (get-in data [:colors id :plugin-data namespace key]) + (dm/get-in data [:colors id :plugin-data namespace key]) :typography - (get-in data [:typographies id :plugin-data namespace key]) + (dm/get-in data [:typographies id :plugin-data namespace key]) :component - (get-in data [:components id :plugin-data namespace key]))] + (dm/get-in data [:components id :plugin-data namespace key])) + + redo-change + (cond-> {:type :set-plugin-data + :object-type type + :namespace namespace + :key key + :value value} + (uuid? id) + (assoc :object-id id) + + (uuid? page-id) + (assoc :page-id page-id)) + + undo-change + (cond-> {:type :set-plugin-data + :object-type type + :namespace namespace + :key key + :value old-val} + (uuid? id) + (assoc :object-id id) + + (uuid? page-id) + (assoc :page-id page-id))] + (-> changes - (update :redo-changes conj {:type :mod-plugin-data :object-type type :object-id id :page-id page-id :namespace namespace :key key :value value}) - (update :undo-changes conj {:type :mod-plugin-data :object-type type :object-id id :page-id page-id :namespace namespace :key key :value old-val}) + (update :redo-changes conj redo-change) + (update :undo-changes conj undo-change) (apply-changes-local))))) (defn del-page @@ -259,7 +284,6 @@ (update :undo-changes conj {:type :mov-page :id page-id :index prev-index}) (apply-changes-local))) - (defn set-guide [changes id guide] (let [page-id (::page-id (meta changes)) diff --git a/common/src/app/common/schema/generators.cljc b/common/src/app/common/schema/generators.cljc index 49845b4af..978e79407 100644 --- a/common/src/app/common/schema/generators.cljc +++ b/common/src/app/common/schema/generators.cljc @@ -149,7 +149,6 @@ (tg/fmap (fn [v] (str v "@example.net"))))) - (defn uri [] (tg/let [scheme (tg/elements ["http" "https"]) @@ -161,8 +160,8 @@ (defn uuid [] - (->> tg/small-integer - (tg/fmap (fn [_] (uuid/next))))) + (->> (small-int :min 1 :max 100000000) + (tg/fmap (fn [i] (uuid/custom 100 i))))) (defn subseq "Given a collection, generates \"subsequences\" which are sequences diff --git a/common/test/common_tests/file_changes_test.cljc b/common/test/common_tests/file_changes_test.cljc index e8056519a..50b4509a5 100644 --- a/common/test/common_tests/file_changes_test.cljc +++ b/common/test/common_tests/file_changes_test.cljc @@ -735,3 +735,24 @@ (nil? (get-in result2 [:pages-index page-id :guides]))))) {:num 1000}))) + +(t/deftest set-plugin-data-json-encode-decode + (let [schema ch/schema:set-plugin-data-change + encode (sm/encoder schema (sm/json-transformer)) + decode (sm/decoder schema (sm/json-transformer))] + (sg/check! + (sg/for [data (sg/generator schema)] + (let [data-1 (encode data) + data-2 (json-roundtrip data-1) + data-3 (decode data-2)] + (= data data-3))) + {:num 1000}))) + +(t/deftest set-plugin-data-gen-and-validate + (let [file-id (uuid/custom 2 2) + page-id (uuid/custom 1 1) + data (make-file-data file-id page-id)] + (sg/check! + (sg/for [change (sg/generator ch/schema:set-plugin-data-change)] + (sm/validate ch/schema:set-plugin-data-change change)) + {:num 1000}))) diff --git a/common/test/common_tests/uuid_test.cljc b/common/test/common_tests/uuid_test.cljc deleted file mode 100644 index 74d25f037..000000000 --- a/common/test/common_tests/uuid_test.cljc +++ /dev/null @@ -1,18 +0,0 @@ -;; 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.uuid-test - (:require - [app.common.schema :as sm] - [app.common.schema.generators :as sg] - [clojure.test :as t])) - -(t/deftest non-repeating-uuid-next-1-schema - (sg/check! - (sg/for [uuid1 (sg/generator ::sm/uuid) - uuid2 (sg/generator ::sm/uuid)] - (not= uuid1 uuid2)) - {:num 200})) diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index e0d8b0ef4..21f978e90 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -598,7 +598,7 @@ (-> (pcb/empty-changes it) (pcb/with-file-data file-data) (assoc :file-id file-id) - (pcb/mod-plugin-data type id page-id namespace key value))] + (pcb/set-plugin-data type id page-id namespace key value))] (rx/of (dch/commit-changes changes))))))) (declare purge-page)