Merge pull request #3926 from penpot/niwinz-staging-bugfixes-2

🐛 More features related bugfixes
This commit is contained in:
Alejandro 2023-12-15 16:16:39 +01:00 committed by GitHub
commit 051c0dce78
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 146 additions and 166 deletions

View file

@ -9,7 +9,6 @@
[app.common.data :as d] [app.common.data :as d]
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.features :as cfeat]
[app.common.files.changes :as cp] [app.common.files.changes :as cp]
[app.common.files.changes-builder :as fcb] [app.common.files.changes-builder :as fcb]
[app.common.files.helpers :as cfh] [app.common.files.helpers :as cfh]
@ -769,12 +768,13 @@
fdata (migrate-graphics fdata)] fdata (migrate-graphics fdata)]
(update fdata :options assoc :components-v2 true))))) (update fdata :options assoc :components-v2 true)))))
(defn- prepare-fdata (defn- get-file
[fdata id] [system id]
(-> fdata (binding [pmap/*load-fn* (partial fdata/load-pointer system id)]
(assoc :id id) (-> (files/get-file system id :migrate? false)
(fdata/process-pointers deref) (update :data assoc :id id)
(fmg/migrate-data))) (update :data fdata/process-pointers deref)
(fmg/migrate-file))))
(defn- validate-file! (defn- validate-file!
[file libs throw-on-validate?] [file libs throw-on-validate?]
@ -788,18 +788,10 @@
(defn- process-file (defn- process-file
[{:keys [::db/conn] :as system} id & {:keys [validate? throw-on-validate?]}] [{:keys [::db/conn] :as system} id & {:keys [validate? throw-on-validate?]}]
(let [file (binding [cfeat/*new* (atom #{}) (let [file (get-file system id)
pmap/*load-fn* (partial fdata/load-pointer system id)]
(-> (files/get-file system id :migrate? false)
(update :data prepare-fdata id)
(update :features into (deref cfeat/*new*))
(update :features cfeat/migrate-legacy-features)))
libs (->> (files/get-file-libraries conn id) libs (->> (files/get-file-libraries conn id)
(into [file] (map (fn [{:keys [id]}] (into [file] (comp (map :id) (map (partial get-file system))))
(binding [pmap/*load-fn* (partial fdata/load-pointer system id)]
(-> (files/get-file system id :migrate? false)
(update :data prepare-fdata id))))))
(d/index-by :id)) (d/index-by :id))
file (-> file file (-> file

View file

@ -11,7 +11,7 @@
[app.common.exceptions :as ex] [app.common.exceptions :as ex]
[app.common.features :as cfeat] [app.common.features :as cfeat]
[app.common.files.defaults :as cfd] [app.common.files.defaults :as cfd]
[app.common.files.migrations :as pmg] [app.common.files.migrations :as fmg]
[app.common.files.validate :as fval] [app.common.files.validate :as fval]
[app.common.fressian :as fres] [app.common.fressian :as fres]
[app.common.logging :as l] [app.common.logging :as l]
@ -701,23 +701,28 @@
(update :object-id #(str/replace-first % #"^(.*?)/" (str file-id "/"))))) (update :object-id #(str/replace-first % #"^(.*?)/" (str file-id "/")))))
thumbnails)) thumbnails))
(defn- process-fdata (defn- process-file
[fdata id] [{:keys [id] :as file}]
(-> fdata (-> file
(dissoc :recent-colors) (update :data (fn [fdata]
(assoc :id id) (-> fdata
(cond-> (> (:version fdata) cfd/version) (assoc :id id)
(assoc :version cfd/version)) (dissoc :recent-colors)
;; FIXME: We're temporarily activating all (cond-> (> (:version fdata) cfd/version)
;; migrations because a problem in the (assoc :version cfd/version))
;; environments messed up with the version ;; FIXME: We're temporarily activating all
;; numbers When this problem is fixed delete ;; migrations because a problem in the
;; the following line ;; environments messed up with the version
(assoc :version 22) ;; numbers When this problem is fixed delete
(pmg/migrate-data) ;; the following line
(update :pages-index relink-shapes) (cond-> (> (:version fdata) 22)
(update :components relink-shapes) (assoc :version 22)))))
(update :media relink-media))) (fmg/migrate-file)
(update :data (fn [fdata]
(-> fdata
(update :pages-index relink-shapes)
(update :components relink-shapes)
(update :media relink-media))))))
(defmethod read-section :v1/files (defmethod read-section :v1/files
@ -730,19 +735,7 @@
file-id (:id file) file-id (:id file)
file-id' (lookup-index file-id) file-id' (lookup-index file-id)
thumbnails (:thumbnails file) thumbnails (:thumbnails file)]
file (update file :features cfeat/migrate-legacy-features)
features (-> enabled-features
(set/difference cfeat/frontend-only-features)
(set/union (cfeat/check-supported-features! (:features file))))]
;; All features that are enabled and requires explicit migration
;; are added to the state for a posterior migration step
(doseq [feature (-> enabled-features
(set/difference cfeat/no-migration-features)
(set/difference (:features file)))]
(vswap! *state* update :pending-to-migrate (fnil conj []) [feature file-id']))
(when (not= file-id expected-file-id) (when (not= file-id expected-file-id)
(ex/raise :type :validation (ex/raise :type :validation
@ -773,16 +766,28 @@
(l/dbg :hint "update media references" ::l/sync? true) (l/dbg :hint "update media references" ::l/sync? true)
(vswap! *state* update :media into (map #(update % :id lookup-index)) media)) (vswap! *state* update :media into (map #(update % :id lookup-index)) media))
(let [file (binding [cfeat/*new* (atom #{})] (let [file (-> file
(-> file (assoc :id file-id')
(assoc :id file-id') (process-file))
(assoc :features features)
(assoc :project-id project-id) ;; All features that are enabled and requires explicit migration are
(assoc :created-at timestamp) ;; added to the state for a posterior migration step.
(assoc :modified-at timestamp) _ (doseq [feature (-> enabled-features
(dissoc :thumbnails) (set/difference cfeat/no-migration-features)
(update :data process-fdata file-id') (set/difference (:features file)))]
(update :features into (deref cfeat/*new*)))) (vswap! *state* update :pending-to-migrate (fnil conj []) [feature file-id']))
file (-> file
(assoc :project-id project-id)
(assoc :created-at timestamp)
(assoc :modified-at timestamp)
(dissoc :thumbnails)
(update :features
(fn [features]
(let [features (cfeat/check-supported-features! features)]
(-> enabled-features
(set/difference cfeat/frontend-only-features)
(set/union features))))))
_ (when (contains? cf/flags :file-schema-validation) _ (when (contains? cf/flags :file-schema-validation)
(fval/validate-file-schema! file)) (fval/validate-file-schema! file))
@ -803,7 +808,6 @@
file)) file))
file) file)
file (-> file file (-> file
(update :features #(db/create-array conn "text" %)) (update :features #(db/create-array conn "text" %))
(update :data blob/encode))] (update :data blob/encode))]

View file

@ -224,11 +224,8 @@
(defn- migrate-file (defn- migrate-file
[{:keys [::db/conn] :as cfg} {:keys [id] :as file}] [{:keys [::db/conn] :as cfg} {:keys [id] :as file}]
(binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg id) (binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg id)
pmap/*tracked* (pmap/create-tracked) pmap/*tracked* (pmap/create-tracked)]
cfeat/*new* (atom #{})] (let [file (fmg/migrate-file file)]
(let [file (-> (fmg/migrate-file file)
(update :features into (deref cfeat/*new*))
(update :features cfeat/migrate-legacy-features))]
;; NOTE: when file is migrated, we break the rule of no perform ;; NOTE: when file is migrated, we break the rule of no perform
;; mutations on get operations and update the file with all ;; mutations on get operations and update the file with all
@ -250,11 +247,13 @@
file))) file)))
(defn get-file (defn get-file
[{:keys [::db/conn] :as cfg} id & {:keys [project-id migrate? [{:keys [::db/conn] :as cfg} id & {:keys [project-id
migrate?
include-deleted? include-deleted?
lock-for-update?] lock-for-update?]
:or {include-deleted? false :or {include-deleted? false
lock-for-update? false}}] lock-for-update? false
migrate? true}}]
(dm/assert! (dm/assert!
"expected cfg with valid connection" "expected cfg with valid connection"
(db/connection-map? cfg)) (db/connection-map? cfg))

View file

@ -10,6 +10,7 @@
[app.common.data.macros :as dm] [app.common.data.macros :as dm]
[app.common.features :as cfeat] [app.common.features :as cfeat]
[app.common.files.helpers :as cfh] [app.common.files.helpers :as cfh]
[app.common.files.migrations :as fmg]
[app.common.geom.shapes :as gsh] [app.common.geom.shapes :as gsh]
[app.common.schema :as sm] [app.common.schema :as sm]
[app.common.thumbnails :as thc] [app.common.thumbnails :as thc]
@ -105,24 +106,12 @@
(letfn [;; function responsible on finding the frame marked to be (letfn [;; function responsible on finding the frame marked to be
;; used as thumbnail; the returned frame always have ;; used as thumbnail; the returned frame always have
;; the :page-id set to the page that it belongs. ;; the :page-id set to the page that it belongs.
(get-thumbnail-frame [{:keys [data]}]
(get-thumbnail-frame [file] (d/seek #(or (:use-for-thumbnail %)
;; NOTE: this is a hack for avoid perform blocking (:use-for-thumbnail? %)) ; NOTE: backward comp (remove on v1.21)
;; operation inside the for loop, clojure lazy-seq uses (for [page (-> data :pages-index vals)
;; synchronized blocks that does not plays well with frame (-> page :objects ctt/get-frames)]
;; virtual threads where all rpc methods calls are (assoc frame :page-id (:id page)))))
;; dispatched, so we need to perform the load operation
;; first. This operation forces all pointer maps load into
;; the memory.
;;
;; FIXME: this is no longer true with clojure>=1.12
(let [{:keys [data]} (update file :data feat.fdata/process-pointers pmap/load!)]
;; Then proceed to find the frame set for thumbnail
(d/seek #(or (:use-for-thumbnail %)
(:use-for-thumbnail? %)) ; NOTE: backward comp (remove on v1.21)
(for [page (-> data :pages-index vals)
frame (-> page :objects ctt/get-frames)]
(assoc frame :page-id (:id page))))))
;; function responsible to filter objects data structure of ;; function responsible to filter objects data structure of
;; all unneeded shapes if a concrete frame is provided. If no ;; all unneeded shapes if a concrete frame is provided. If no
@ -166,30 +155,29 @@
objects)))] objects)))]
(binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg id)] (let [frame (get-thumbnail-frame file)
(let [frame (get-thumbnail-frame file) frame-id (:id frame)
frame-id (:id frame) page-id (or (:page-id frame)
page-id (or (:page-id frame) (-> data :pages first))
(-> data :pages first))
page (dm/get-in data [:pages-index page-id]) page (dm/get-in data [:pages-index page-id])
page (cond-> page (pmap/pointer-map? page) deref) page (cond-> page (pmap/pointer-map? page) deref)
frame-ids (if (some? frame) (list frame-id) (map :id (ctt/get-frames (:objects page)))) frame-ids (if (some? frame) (list frame-id) (map :id (ctt/get-frames (:objects page))))
obj-ids (map #(thc/fmt-object-id (:id file) page-id % "frame") frame-ids) obj-ids (map #(thc/fmt-object-id (:id file) page-id % "frame") frame-ids)
thumbs (get-object-thumbnails conn id obj-ids)] thumbs (get-object-thumbnails conn id obj-ids)]
(cond-> page (cond-> page
;; If we have frame, we need to specify it on the page level ;; If we have frame, we need to specify it on the page level
;; and remove the all other unrelated objects. ;; and remove the all other unrelated objects.
(some? frame-id) (some? frame-id)
(-> (assoc :thumbnail-frame-id frame-id) (-> (assoc :thumbnail-frame-id frame-id)
(update :objects filter-objects frame-id)) (update :objects filter-objects frame-id))
;; Assoc the available thumbnails and prune not visible shapes ;; Assoc the available thumbnails and prune not visible shapes
;; for avoid transfer unnecessary data. ;; for avoid transfer unnecessary data.
:always :always
(update :objects assoc-thumbnails page-id thumbs)))))) (update :objects assoc-thumbnails page-id thumbs)))))
(def ^:private (def ^:private
schema:get-file-data-for-thumbnail schema:get-file-data-for-thumbnail
@ -221,7 +209,10 @@
:profile-id profile-id :profile-id profile-id
:file-id file-id) :file-id file-id)
file (files/get-file cfg file-id)] file (binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg file-id)]
(-> (files/get-file cfg file-id :migrate? false)
(update :data feat.fdata/process-pointers deref)
(fmg/migrate-file)))]
(-> (cfeat/get-team-enabled-features cf/flags team) (-> (cfeat/get-team-enabled-features cf/flags team)
(cfeat/check-client-features! (:features params)) (cfeat/check-client-features! (:features params))

View file

@ -106,41 +106,34 @@
media media
media)) media))
(update-fdata [fdata new-id] (process-file [{:keys [id] :as file}]
(-> fdata (-> file
(assoc :id new-id) (update :data assoc :id id)
(feat.fdata/process-pointers deref) (update :data feat.fdata/process-pointers deref)
(pmg/migrate-data) (pmg/migrate-file)
(update :pages-index relink-shapes) (update :data (fn [data]
(update :components relink-shapes) (-> data
(update :media relink-media) (update :pages-index relink-shapes)
(d/without-nils)))] (update :components relink-shapes)
(update :media relink-media)
(d/without-nils))))))]
(binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg id) (let [new-id (get index id)
pmap/*tracked* (pmap/create-tracked) file (binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg id)]
cfeat/*new* (atom #{})] (-> (assoc file :id new-id)
(process-file)))
(let [new-id (get index id) file (if (contains? (:features file) "fdata/objects-map")
file (binding [pmap/*load-fn* (partial feat.fdata/load-pointer cfg id) (feat.fdata/enable-objects-map file)
cfeat/*new* (atom #{})] file)
(-> file
(assoc :id new-id)
(update :data update-fdata new-id)
(update :features into (deref cfeat/*new*))
(update :features cfeat/migrate-legacy-features)))
file (if (contains? (:features file) "fdata/objects-map") file (if (contains? (:features file) "fdata/pointer-map")
(feat.fdata/enable-objects-map file) (binding [pmap/*tracked* (pmap/create-tracked)]
file) (let [file (feat.fdata/enable-pointer-map file)]
(feat.fdata/persist-pointers! cfg (:id file))
file (if (contains? (:features file) "fdata/pointer-map") file))
(binding [pmap/*tracked* (pmap/create-tracked)] file)]
(let [file (feat.fdata/enable-pointer-map file)] file)))
(feat.fdata/persist-pointers! cfg (:id file))
file))
file)]
file))))
(def sql:get-used-libraries (def sql:get-used-libraries
"select flr.* "select flr.*

View file

@ -42,18 +42,21 @@
(reduce migrate-fn data (range (:version data 0) to-version)))))) (reduce migrate-fn data (range (:version data 0) to-version))))))
(defn migrate-file (defn migrate-file
[{:keys [id data] :as file}] [{:keys [id data features] :as file}]
(let [data (assoc data :id id)] (binding [cfeat/*new* (atom #{})]
(-> file (let [file (-> file
(assoc ::orig-version (:version data)) (update :data assoc :id id)
(assoc :data (migrate-data data))))) (update :data migrate-data)
(update :features (fnil into #{}) (deref cfeat/*new*))
(update :features cfeat/migrate-legacy-features))]
(if (or (not= (:version data) (:version (:data file)))
(not= features (:features file)))
(vary-meta file assoc ::migrated true)
file))))
(defn migrated? (defn migrated?
[{:keys [data] :as file}] [file]
(or (::migrated file) (true? (-> file meta ::migrated)))
(let [version (:version data)]
(> version
(::orig-version file version)))))
;; Default handler, noop ;; Default handler, noop
(defmethod migrate :default [data] data) (defmethod migrate :default [data] data)

View file

@ -32,11 +32,11 @@
(defn get-team-enabled-features (defn get-team-enabled-features
[state] [state]
(let [runtime-features (set/intersection (:features/runtime state #{}) (-> global-enabled-features
cfeat/no-migration-features)] (set/union (:features/runtime state #{}))
(-> global-enabled-features (set/intersection cfeat/no-migration-features)
(set/union runtime-features) (set/union cfeat/default-enabled-features)
(set/union (:features/team state #{}))))) (set/union (:features/team state #{}))))
(def features-ref (def features-ref
(l/derived get-team-enabled-features st/state =)) (l/derived get-team-enabled-features st/state =))
@ -99,7 +99,7 @@
ptk/UpdateEvent ptk/UpdateEvent
(update [_ state] (update [_ state]
(let [runtime-features (get state :features/runtime #{}) (let [runtime-features (get state :features/runtime #{})
team-features (into cfeat/default-enabled-features team-features (into #{}
cfeat/xf-supported-features cfeat/xf-supported-features
team-features)] team-features)]
(-> state (-> state

View file

@ -65,7 +65,6 @@
(d/seek :is-default) (d/seek :is-default)
(:id))) (:id)))
on-resize on-resize
(mf/use-fn (mf/use-fn
(fn [_] (fn [_]
@ -256,7 +255,7 @@
:section section :section section
:search-term search-term :search-term search-term
:team team}])])]] :team team}])])]]
[:& (mf/provider ctx/current-team-id) {:value team-id} [:& (mf/provider ctx/current-team-id) {:value team-id}
[:& (mf/provider ctx/current-project-id) {:value project-id} [:& (mf/provider ctx/current-project-id) {:value project-id}
;; NOTE: dashboard events and other related functions assumes ;; NOTE: dashboard events and other related functions assumes

View file

@ -351,17 +351,15 @@
on-template-cloned-success on-template-cloned-success
(fn [] (fn []
(swap! state (swap! state assoc :status :importing :importing-templates 0)
(fn [state]
(-> state
(assoc :status :importing :importing-templates 0))))
(st/emit! (dd/fetch-recent-files))) (st/emit! (dd/fetch-recent-files)))
on-template-cloned-error on-template-cloned-error
(fn [cause] (fn [cause]
(errors/print-cause! "Template Clone Error" cause) (swap! state assoc :status :error :importing-templates 0)
(st/emit! (modal/hide) (errors/print-error! cause)
(msg/error (tr "dashboard.libraries-and-templates.import-error")))) (rx/of (modal/hide)
(msg/error (tr "dashboard.libraries-and-templates.import-error"))))
continue-files continue-files
(fn [] (fn []

View file

@ -15,6 +15,7 @@
[app.main.data.messages :as msg] [app.main.data.messages :as msg]
[app.main.data.modal :as modal] [app.main.data.modal :as modal]
[app.main.data.users :as du] [app.main.data.users :as du]
[app.main.errors :as errors]
[app.main.refs :as refs] [app.main.refs :as refs]
[app.main.store :as st] [app.main.store :as st]
[app.main.ui.context :as ctx] [app.main.ui.context :as ctx]
@ -138,10 +139,10 @@
on-template-cloned-error on-template-cloned-error
(mf/use-fn (mf/use-fn
(fn [] (fn [cause]
(swap! state #(assoc % :status :waiting)) (swap! state assoc :status :error)
(st/emit! (errors/print-error! cause)
(msg/error (tr "dashboard.libraries-and-templates.import-error"))))) (st/emit! (msg/error (tr "dashboard.libraries-and-templates.import-error")))))
download-tutorial download-tutorial
(mf/use-fn (mf/use-fn