diff --git a/frontend/resources/locales.json b/frontend/resources/locales.json index 72d89fc6e8..b1c0fdc4cd 100644 --- a/frontend/resources/locales.json +++ b/frontend/resources/locales.json @@ -2113,6 +2113,38 @@ "es" : "Añadir “%s” como Biblioteca Compartida" } }, + "modals.update-remote-component.message" : { + "translations" : { + "en" : "Update a component in a shared library", + "fr" : "", + "ru" : "", + "es" : "Actualizar un componente en librería" + } + }, + "modals.update-remote-component.hint" : { + "translations" : { + "en" : "You are about to update a component in a shared library. This may affect other files that use it.", + "fr" : "", + "ru" : "", + "es" : "Vas a actualizar un componente en una librería compartida. Esto puede afectar a otros archivos que la usen." + } + }, + "modals.update-remote-component.accept" : { + "translations" : { + "en" : "Update component", + "fr" : "", + "ru" : "", + "es" : "Actualizar componente" + } + }, + "modals.update-remote-component.cancel" : { + "translations" : { + "en" : "Cancel", + "fr" : "", + "ru" : "", + "es" : "Cancelar" + } + }, "notifications.profile-deletion-not-allowed" : { "used-in" : [ "src/app/main/ui/settings/delete_account.cljs:28" ], "translations" : { diff --git a/frontend/src/app/main/data/workspace/common.cljs b/frontend/src/app/main/data/workspace/common.cljs index ead0725f87..50b70d826c 100644 --- a/frontend/src/app/main/data/workspace/common.cljs +++ b/frontend/src/app/main/data/workspace/common.cljs @@ -66,7 +66,8 @@ ([changes undo-changes] (commit-changes changes undo-changes {})) ([changes undo-changes {:keys [save-undo? - commit-local?] + commit-local? + file-id] :or {save-undo? true commit-local? false} :as opts}] @@ -79,17 +80,25 @@ (let [error (volatile! nil)] (ptk/reify ::commit-changes cljs.core/IDeref - (-deref [_] changes) + (-deref [_] {:file-id file-id :changes changes}) ptk/UpdateEvent (update [_ state] - (try - (let [state (update-in state [:workspace-file :data] cp/process-changes changes)] - (cond-> state - commit-local? (update :workspace-data cp/process-changes changes))) - (catch :default e - (vreset! error e) - state))) + (let [current-file-id (get state :current-file-id) + file-id (or file-id current-file-id) + path1 (if (= file-id current-file-id) + [:workspace-file :data] + [:workspace-libraries file-id :data]) + path2 (if (= file-id current-file-id) + [:workspace-data] + [:workspace-libraries file-id :data])] + (try + (let [state (update-in state path1 cp/process-changes changes)] + (cond-> state + commit-local? (update-in path2 cp/process-changes changes))) + (catch :default e + (vreset! error e) + state)))) ptk/WatchEvent (watch [_ state stream] diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index e4db491296..318c7ecba5 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -36,21 +36,21 @@ (log/set-level! :warn) (defn- log-changes - [changes local-library] + [changes file] (let [extract-change (fn [change] (let [shape (when (:id change) (cond (:page-id change) - (get-in local-library [:pages-index - (:page-id change) - :objects - (:id change)]) + (get-in file [:pages-index + (:page-id change) + :objects + (:id change)]) (:component-id change) - (get-in local-library [:components - (:component-id change) - :objects - (:id change)]) + (get-in file [:components + (:component-id change) + :objects + (:id change)]) :default nil)) prefix (if (:component-id change) "[C] " "[P] ") @@ -118,7 +118,7 @@ uchg {:type :mod-color :color prev}] (rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true}) - (sync-file file-id)))))) + (sync-file (:current-file-id state) file-id)))))) (defn delete-color [{:keys [id] :as params}] @@ -208,7 +208,7 @@ uchg {:type :mod-typography :typography prev}] (rx/of (dwc/commit-changes [rchg] [uchg] {:commit-local? true}) - (sync-file file-id)))))) + (sync-file (:current-file-id state) file-id)))))) (defn delete-typography [id] @@ -337,7 +337,7 @@ (watch [_ state stream] (let [component (cp/get-component id (:current-file-id state) - (dwlh/get-local-library state) + (dwlh/get-local-file state) nil) all-components (vals (get-in state [:workspace-data :components])) unames (set (map :name all-components)) @@ -385,7 +385,7 @@ (ptk/reify ::instantiate-component ptk/WatchEvent (watch [_ state stream] - (let [local-library (dwlh/get-local-library state) + (let [local-library (dwlh/get-local-file state) libraries (get state :workspace-libraries) component (cp/get-component component-id file-id local-library libraries) component-shape (cp/get-shape component component-id) @@ -529,14 +529,15 @@ (st/emit! (rt/nav-new-window :workspace pparams qparams)))))) (defn ext-library-changed - [file-id modified-at changes] + [file-id modified-at revn changes] (us/assert ::us/uuid file-id) (us/assert ::cp/changes changes) (ptk/reify ::ext-library-changed ptk/UpdateEvent (update [_ state] (-> state - (assoc-in [:workspace-libraries file-id :modified-at] modified-at) + (update-in [:workspace-libraries file-id] + #(assoc % :modified-at modified-at :revn revn)) (d/update-in-when [:workspace-libraries file-id :data] cp/process-changes changes))))) @@ -550,7 +551,7 @@ ptk/WatchEvent (watch [_ state stream] (log/info :msg "RESET-COMPONENT of shape" :id (str id)) - (let [local-library (dwlh/get-local-library state) + (let [local-library (dwlh/get-local-file state) libraries (dwlh/get-libraries state) container (cp/get-container (get state :current-page-id) :page @@ -577,46 +578,84 @@ ptk/WatchEvent (watch [_ state stream] (log/info :msg "UPDATE-COMPONENT of shape" :id (str id)) - (let [local-library (dwlh/get-local-library state) + (let [page-id (get state :current-page-id) + local-library (dwlh/get-local-file state) libraries (dwlh/get-libraries state) + [rchanges uchanges] - (dwlh/generate-sync-shape-inverse (get state :current-page-id) + (dwlh/generate-sync-shape-inverse page-id id local-library - libraries)] + libraries) - (log/debug :msg "UPDATE-COMPONENT finished" :js/rchanges (log-changes - rchanges - local-library)) + container (cp/get-container page-id :page local-library) + shape (cp/get-shape container id) + file-id (:component-file shape) + file (dwlh/get-file state file-id) - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true})))))) + local-rchanges (->> rchanges + (filter :local-change?) + (map #(dissoc % :local-change?)) + vec) + local-uchanges (->> uchanges + (filter :local-change?) + (map #(dissoc % :local-change?)) + vec) + rchanges (->> rchanges + (remove :local-change?) + (map #(dissoc % :local-change?)) + vec) + uchanges (->> uchanges + (remove :local-change?) + (map #(dissoc % :local-change?)) + vec)] + + (log/debug :msg "UPDATE-COMPONENT finished" + :js/local-rchanges (log-changes + local-rchanges + local-library) + :js/rchanges (log-changes + rchanges + file)) + + (rx/of (when (seq local-rchanges) + (dwc/commit-changes local-rchanges local-uchanges + {:commit-local? true + :file-id (:id local-library)})) + (when (seq rchanges) + (dwc/commit-changes rchanges uchanges + {:commit-local? true + :file-id file-id}))))))) (declare sync-file-2nd-stage) (defn sync-file - "Syhchronize the library file with the given id, with the current file. - Walk through all shapes in all pages that use some color, typography or - component of the library file, and copy the new values to the shapes. - Do it also for shapes inside components of the local file library." - [file-id] + "Syhchronize the given file from ghe given library. Walk through all shapes + in all pages in the file that use some color, typography or component of the + library, and copy the new values to the shapes. Do it also for shapes inside + components of the local file library." + [file-id library-id] (us/assert ::us/uuid file-id) + (us/assert ::us/uuid library-id) (ptk/reify ::sync-file ptk/UpdateEvent (update [_ state] - (if (not= file-id (:current-file-id state)) - (assoc-in state [:workspace-libraries file-id :synced-at] (dt/now)) + (if (not= library-id (:current-file-id state)) + (assoc-in state [:workspace-libraries library-id :synced-at] (dt/now)) state)) ptk/WatchEvent (watch [_ state stream] - (log/info :msg "SYNC-FILE" :file (if (= file-id (:current-file-id state)) "local" (str file-id))) - (let [local-library (dwlh/get-local-library state) - library-changes [(dwlh/generate-sync-library :components file-id state) - (dwlh/generate-sync-library :colors file-id state) - (dwlh/generate-sync-library :typographies file-id state)] - file-changes [(dwlh/generate-sync-file :components file-id state) - (dwlh/generate-sync-file :colors file-id state) - (dwlh/generate-sync-file :typographies file-id state)] + (log/info :msg "SYNC-FILE" + :file (dwlh/pretty-file file-id state) + :library (dwlh/pretty-file library-id state)) + (let [file (dwlh/get-file state file-id) + library-changes [(dwlh/generate-sync-library file-id :components library-id state) + (dwlh/generate-sync-library file-id :colors library-id state) + (dwlh/generate-sync-library file-id :typographies library-id state)] + file-changes [(dwlh/generate-sync-file file-id :components library-id state) + (dwlh/generate-sync-file file-id :colors library-id state) + (dwlh/generate-sync-file file-id :typographies library-id state)] rchanges (d/concat [] (->> library-changes (remove nil?) (map first) (flatten)) (->> file-changes (remove nil?) (map first) (flatten))) @@ -625,17 +664,22 @@ (->> file-changes (remove nil?) (map second) (flatten)))] (log/debug :msg "SYNC-FILE finished" :js/rchanges (log-changes rchanges - local-library)) + file)) (rx/concat (rx/of (dm/hide-tag :sync-dialog)) (when rchanges - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))) - (when (not= file-id (:current-file-id state)) - (rp/mutation :update-sync - {:file-id (get-in state [:workspace-file :id]) - :library-id file-id})) + (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true + :file-id file-id}))) + (when (not= file-id library-id) + ;; When we have just updated the library file, give some time for the + ;; update to finish, before marking this file as synced. + ;; TODO: look for a more precise way of syncing this. + (rx/concat (rx/timer 3000) + (rp/mutation :update-sync + {:file-id file-id + :library-id library-id}))) (when (some? library-changes) - (rx/of (sync-file-2nd-stage file-id)))))))) + (rx/of (sync-file-2nd-stage file-id library-id)))))))) (defn sync-file-2nd-stage "If some components have been modified, we need to launch another synchronization @@ -646,22 +690,26 @@ ;; recursively. But for this not to cause an infinite loop, we need to ;; implement updated-at at component level, to detect what components have ;; not changed, and then not to apply sync and terminate the loop. - [file-id] + [file-id library-id] (us/assert ::us/uuid file-id) + (us/assert ::us/uuid library-id) (ptk/reify ::sync-file-2nd-stage ptk/WatchEvent (watch [_ state stream] - (log/info :msg "SYNC-FILE (2nd stage)" :file (if (= file-id (:current-file-id state)) "local" (str file-id))) - (let [local-library (dwlh/get-local-library state) - [rchanges1 uchanges1] (dwlh/generate-sync-file :components file-id state) - [rchanges2 uchanges2] (dwlh/generate-sync-library :components file-id state) + (log/info :msg "SYNC-FILE (2nd stage)" + :file (dwlh/pretty-file file-id state) + :library (dwlh/pretty-file library-id state)) + (let [file (dwlh/get-file state file-id) + [rchanges1 uchanges1] (dwlh/generate-sync-file file-id :components library-id state) + [rchanges2 uchanges2] (dwlh/generate-sync-library file-id :components library-id state) rchanges (d/concat rchanges1 rchanges2) uchanges (d/concat uchanges1 uchanges2)] (when rchanges (log/debug :msg "SYNC-FILE (2nd stage) finished" :js/rchanges (log-changes rchanges - local-library)) - (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true}))))))) + file)) + (rx/of (dwc/commit-changes rchanges uchanges {:commit-local? true + :file-id file-id}))))))) (def ignore-sync (ptk/reify ::ignore-sync @@ -684,7 +732,8 @@ (let [libraries-need-sync (filter #(> (:modified-at %) (:synced-at %)) (vals (get state :workspace-libraries))) do-update #(do (apply st/emit! (map (fn [library] - (sync-file (:id library))) + (sync-file (:current-file-id state) + (:id library))) libraries-need-sync)) (st/emit! dm/hide)) do-dismiss #(do (st/emit! ignore-sync) diff --git a/frontend/src/app/main/data/workspace/libraries_helpers.cljs b/frontend/src/app/main/data/workspace/libraries_helpers.cljs index 9538498add..e27329c311 100644 --- a/frontend/src/app/main/data/workspace/libraries_helpers.cljs +++ b/frontend/src/app/main/data/workspace/libraries_helpers.cljs @@ -59,14 +59,26 @@ [(d/concat rchanges1 rchanges2) (d/concat uchanges1 uchanges2)]) -(defn get-local-library +(defn get-local-file [state] (get state :workspace-data)) +(defn get-file + [state file-id] + (if (= file-id (:current-file-id state)) + (get state :workspace-data) + (get-in state [:workspace-libraries file-id :data]))) + (defn get-libraries [state] (get state :workspace-libraries)) +(defn pretty-file + [file-id state] + (if (= file-id (:current-file-id state)) + "" + (str "<" (get-in state [:workspace-libraries file-id :name]) ">"))) + ;; ---- Create a new component ---- @@ -124,25 +136,26 @@ ;; ---- General library synchronization functions ---- (defn generate-sync-file - "Generate changes to synchronize all shapes in all pages of the current file, + "Generate changes to synchronize all shapes in all pages of the given file, that use assets of the given type in the given library." - [asset-type library-id state] + [file-id asset-type library-id state] (s/assert #{:colors :components :typographies} asset-type) + (s/assert ::us/uuid file-id) (s/assert ::us/uuid library-id) - (log/info :msg "Sync local file with library" + (log/info :msg "Sync file with library" :asset-type asset-type - :library (str (or library-id "local"))) + :file (pretty-file file-id state) + :library (pretty-file library-id state)) - (let [library-items - (if (= library-id (:current-file-id state)) - (get-in state [:workspace-data asset-type]) - (get-in state [:workspace-libraries library-id :data asset-type]))] + (let [file (get-file state file-id) + library (get-file state library-id) + library-items (get library asset-type)] (if (empty? library-items) empty-changes - (loop [pages (vals (get-in state [:workspace-data :pages-index])) + (loop [pages (vals (get file :pages-index)) rchanges [] uchanges []] (if-let [page (first pages)] @@ -157,22 +170,24 @@ [rchanges uchanges]))))) (defn generate-sync-library - "Generate changes to synchronize all shapes in all components of the current - file library, that use assets of the given type in the given library." - [asset-type library-id state] + "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." + [file-id asset-type library-id state] (log/info :msg "Sync local components with library" :asset-type asset-type - :library (str library-id)) + :file (pretty-file file-id state) + :library (pretty-file library-id state)) + + (let [file (get-file state file-id) + library (get-file state library-id) + library-items (get library asset-type)] - (let [library-items - (if (= library-id (:current-file-id state)) - (get-in state [:workspace-data asset-type]) - (get-in state [:workspace-libraries library-id :data asset-type]))] (if (empty? library-items) empty-changes - (loop [local-components (seq (vals (get-in state [:workspace-data :components]))) + (loop [local-components (vals (get file :components)) rchanges [] uchanges []] (if-let [local-component (first local-components)] @@ -261,7 +276,7 @@ [_ library-id state container shape] (generate-sync-shape-direct container (:id shape) - (get-local-library state) + (get-local-file state) (get-libraries state) false)) @@ -689,7 +704,18 @@ only-master both moved - true)] + true) + + ;; The inverse sync may be made on a component that is inside a + ;; remote library. We need to separate changes that are from + ;; local and remote files. + check-local (fn [change] + (cond-> change + (= (:id change) (:id shape-inst)) + (assoc :local-change? true))) + + rchanges (vec (map check-local rchanges)) + uchanges (vec (map check-local uchanges))] [(d/concat rchanges child-rchanges) (d/concat uchanges child-uchanges)])) diff --git a/frontend/src/app/main/data/workspace/notifications.cljs b/frontend/src/app/main/data/workspace/notifications.cljs index 7a1c2622a5..068c8b40a0 100644 --- a/frontend/src/app/main/data/workspace/notifications.cljs +++ b/frontend/src/app/main/data/workspace/notifications.cljs @@ -218,12 +218,12 @@ ::changes])) (defn handle-library-change - [{:keys [file-id modified-at changes] :as msg}] + [{:keys [file-id modified-at changes revn] :as msg}] (us/assert ::library-change-event msg) (ptk/reify ::handle-library-change ptk/WatchEvent (watch [_ state stream] (when (contains? (:workspace-libraries state) file-id) - (rx/of (dwl/ext-library-changed file-id modified-at changes) + (rx/of (dwl/ext-library-changed file-id modified-at revn changes) (dwl/notify-sync-file file-id)))))) diff --git a/frontend/src/app/main/data/workspace/persistence.cljs b/frontend/src/app/main/data/workspace/persistence.cljs index 9ce538f5b8..ad53f2eaaa 100644 --- a/frontend/src/app/main/data/workspace/persistence.cljs +++ b/frontend/src/app/main/data/workspace/persistence.cljs @@ -55,6 +55,13 @@ (rx/debounce 2000) (rx/merge stoper forcer)) + local-file? #(let [event-file-id (:file-id %)] + (or (nil? event-file-id) + (= event-file-id file-id))) + library-file? #(let [event-file-id (:file-id %)] + (and (some? event-file-id) + (not= event-file-id file-id))) + on-dirty (fn [] ;; Enable reload stoper @@ -70,27 +77,36 @@ ;; Disable reload stoper (obj/set! js/window "onbeforeunload" nil) (st/emit! (update-persistence-status {:status :saved})))] - (->> (rx/merge - (->> stream - (rx/filter (ptk/type? ::dwc/commit-changes)) - (rx/map deref) - (rx/tap on-dirty) - (rx/buffer-until notifier) - (rx/map vec) - (rx/filter (complement empty?)) - (rx/map #(persist-changes file-id %)) - (rx/tap on-saving) - (rx/take-until (rx/delay 100 stoper))) - (->> stream - (rx/filter (ptk/type? ::changes-persisted)) - (rx/tap on-saved) - (rx/ignore) - (rx/take-until stoper))) + (->> stream + (rx/filter (ptk/type? ::dwc/commit-changes)) + (rx/map deref) + (rx/filter local-file?) + (rx/tap on-dirty) + (rx/buffer-until notifier) + (rx/filter (complement empty?)) + (rx/map (fn [buf] {:file-id file-id + :changes (into [] (mapcat :changes) buf)})) + (rx/map persist-changes) + (rx/tap on-saving) + (rx/take-until (rx/delay 100 stoper))) + (->> stream + (rx/filter (ptk/type? ::dwc/commit-changes)) + (rx/map deref) + (rx/filter library-file?) + (rx/filter (complement #(empty? (:changes %)))) + (rx/map persist-changes) + (rx/take-until (rx/delay 100 stoper))) + (->> stream + (rx/filter (ptk/type? ::changes-persisted)) + (rx/tap on-saved) + (rx/ignore) + (rx/take-until stoper))) (rx/subs #(st/emit! %))))))) (defn persist-changes - [file-id changes] + [{:keys [file-id changes]}] + (us/verify ::us/uuid file-id) (ptk/reify ::persist-changes ptk/UpdateEvent (update [_ state] @@ -102,10 +118,11 @@ ptk/WatchEvent (watch [_ state stream] (let [sid (:session-id state) - file (:workspace-file state) + file (if (= file-id (:current-file-id state)) + (get state :workspace-file) + (get-in state [:workspace-libraries file-id])) queue (get-in state [:workspace-persistence :queue] []) - xf-cat (comp (mapcat :changes) - (mapcat identity)) + xf-cat (comp (mapcat :changes)) changes (into [] xf-cat queue) params {:id (:id file) :revn (:revn file) @@ -143,10 +160,9 @@ (rx/delay 200) (rx/mapcat #(rx/throw error))))))] - (when (= file-id (:id file)) - (->> (rp/mutation :update-file params) - (rx/mapcat handle-response) - (rx/catch on-error))))))) + (->> (rp/mutation :update-file params) + (rx/mapcat handle-response) + (rx/catch on-error)))))) (defn update-persistence-status @@ -171,14 +187,16 @@ (ptk/reify ::changes-persisted ptk/UpdateEvent (update [_ state] - (let [sid (:session-id state) - file (:workspace-file state)] - (if (= file-id (:id file)) - (let [state (update-in state [:workspace-file :revn] #(max % revn))] - (-> state - (update :workspace-data cp/process-changes changes) - (update-in [:workspace-file :data] cp/process-changes changes))) - state))))) + (if (= file-id (:current-file-id state)) + (-> state + (update-in [:workspace-file :revn] #(max % revn)) + (update :workspace-data cp/process-changes changes) + (update-in [:workspace-file :data] cp/process-changes changes)) + (-> state + (update-in state [:workspace-libraries file-id :revn] + #(max % revn)) + (update-in [:workspace-libraries file-id :data] + cp/process-changes changes)))))) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/frontend/src/app/main/ui/workspace/context_menu.cljs b/frontend/src/app/main/ui/workspace/context_menu.cljs index d1985ee7b4..9bc4d122c5 100644 --- a/frontend/src/app/main/ui/workspace/context_menu.cljs +++ b/frontend/src/app/main/ui/workspace/context_menu.cljs @@ -10,6 +10,7 @@ (ns app.main.ui.workspace.context-menu "A workspace specific context menu (mouse right click)." (:require + [app.main.data.modal :as modal] [app.main.data.workspace :as dw] [app.main.data.workspace.common :as dwc] [app.main.data.workspace.libraries :as dwl] @@ -76,8 +77,24 @@ do-update-component #(do (st/emit! (dwc/start-undo-transaction)) (st/emit! (dwl/update-component id)) - (st/emit! (dwl/sync-file current-file-id)) + (st/emit! (dwl/sync-file current-file-id + (:component-file shape))) (st/emit! (dwc/commit-undo-transaction))) + confirm-update-remote-component #(do + (st/emit! (dwl/update-component id)) + (st/emit! (dwl/sync-file current-file-id + (:component-file shape))) + (st/emit! (dwl/sync-file (:component-file shape) + (:component-file shape)))) + do-update-remote-component (st/emitf (modal/show + {:type :confirm + :message "" + :title (t locale "modals.update-remote-component.message") + :hint (t locale "modals.update-remote-component.hint") + :cancel-label (t locale "modals.update-remote-component.cancel") + :accept-label (t locale "modals.update-remote-component.accept") + :accept-style :primary + :on-accept confirm-update-remote-component})) do-show-component #(st/emit! (dw/go-to-layout :assets)) do-navigate-component-file #(st/emit! (dwl/nav-to-component-file (:component-file shape)))] @@ -175,7 +192,9 @@ [:& menu-entry {:title (t locale "workspace.shape.menu.reset-overrides") :on-click do-reset-component}] [:& menu-entry {:title (t locale "workspace.shape.menu.go-master") - :on-click do-navigate-component-file}]])) + :on-click do-navigate-component-file}] + [:& menu-entry {:title (t locale "workspace.shape.menu.update-master") + :on-click do-update-remote-component}]])) [:& menu-separator] [:& menu-entry {:title (t locale "workspace.shape.menu.delete") diff --git a/frontend/src/app/main/ui/workspace/libraries.cljs b/frontend/src/app/main/ui/workspace/libraries.cljs index 8138379361..1c8e5fb5d5 100644 --- a/frontend/src/app/main/ui/workspace/libraries.cljs +++ b/frontend/src/app/main/ui/workspace/libraries.cljs @@ -126,7 +126,7 @@ [{:keys [file libraries] :as props}] (let [libraries-need-sync (filter #(> (:modified-at %) (:synced-at %)) (vals libraries)) - update-library #(st/emit! (dwl/sync-file %))] + update-library #(st/emit! (dwl/sync-file (:id file) %))] [:div.section (if (empty? libraries-need-sync) [:div.section-list-empty diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs index 7608519671..7f21d97094 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs @@ -62,7 +62,7 @@ (mf/deps state) (fn [] (st/emit! (dwl/delete-component {:id (:component-id @state)})) - (st/emit! (dwl/sync-file file-id)))) + (st/emit! (dwl/sync-file file-id file-id)))) on-rename (mf/use-callback diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/component.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/component.cljs index a6f0a29dba..4b957fb8e0 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/component.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/component.cljs @@ -11,6 +11,7 @@ (:require [rumext.alpha :as mf] [app.common.pages :as cp] + [app.main.data.modal :as modal] [app.main.refs :as refs] [app.main.store :as st] [app.main.ui.context :as ctx] @@ -54,8 +55,23 @@ do-update-component #(do (st/emit! (dwc/start-undo-transaction)) (st/emit! (dwl/update-component id)) - (st/emit! (dwl/sync-file current-file-id)) + (st/emit! (dwl/sync-file current-file-id current-file-id)) (st/emit! (dwc/commit-undo-transaction))) + confirm-update-remote-component #(do + (st/emit! (dwl/update-component id)) + (st/emit! (dwl/sync-file current-file-id + (:component-file values))) + (st/emit! (dwl/sync-file (:component-file values) + (:component-file values)))) + do-update-remote-component (st/emitf (modal/show + {:type :confirm + :message "" + :title (t locale "modals.update-remote-component.message") + :hint (t locale "modals.update-remote-component.hint") + :cancel-label (t locale "modals.update-remote-component.cancel") + :accept-label (t locale "modals.update-remote-component.accept") + :accept-style :primary + :on-accept confirm-update-remote-component})) do-show-component #(st/emit! (dw/go-to-layout :assets)) do-navigate-component-file #(st/emit! (dwl/nav-to-component-file (:component-file values)))] @@ -83,5 +99,6 @@ [[(t locale "workspace.shape.menu.detach-instance") do-detach-component] [(t locale "workspace.shape.menu.reset-overrides") do-reset-component] - [(t locale "workspace.shape.menu.go-master") do-navigate-component-file]])}]]]]]))) + [(t locale "workspace.shape.menu.go-master") do-navigate-component-file] + [(t locale "workspace.shape.menu.update-master") do-update-remote-component]])}]]]]])))