diff --git a/common/src/app/common/files/tokens.cljc b/common/src/app/common/files/tokens.cljc index 1e72897aed..49051c29ff 100644 --- a/common/src/app/common/files/tokens.cljc +++ b/common/src/app/common/files/tokens.cljc @@ -472,12 +472,25 @@ (defn tokens-source? "Returns true if the given id is the current tokens source of the file-data. - When no tokens-source is set, the file's own id is considered the source." + When no tokens-source is set, the file's own id is considered the source if there are any tokens in it." [file-data id] (assert (uuid? id) "expected valid uuid") - (let [source (or (:tokens-source file-data) - (:id file-data))] - (= source id))) + (let [source (:tokens-source file-data)] + (if (= id (:id file-data)) + (and (some? (:tokens-lib file-data)) + (or (nil? source) (= source id))) + (= source id)))) + +(defn tokens-provider? + "Returns true if the file MAY become the tokens source for the file with the given id. + This is true if the file has tokens and has not configured another tokens source, + or if we are asking if may become the tokens source for itself." + [file-data id] + (if (some? (:tokens-lib file-data)) + (or (nil? (:tokens-source file-data)) + (= (:tokens-source file-data) (:id file-data)) + (= (:id file-data) id)) + false)) (defn editable-tokens? "Returns true if the file-data owns its tokens (no external source or source is itself)." @@ -485,12 +498,6 @@ (let [source (:tokens-source file-data)] (or (nil? source) (= source (:id file-data))))) -(defn has-tokens-lib? - "Returns true if the file-data has its own tokens-lib (not an external source)." - [file-data] - (and (some? (:tokens-lib file-data)) - (:nil? (:tokens-source file-data)))) - (defn get-tokens-lib [file-data] (:tokens-lib file-data)) diff --git a/common/test/common_tests/files/tokens_test.cljc b/common/test/common_tests/files/tokens_test.cljc index 913c13b596..a529ae3866 100644 --- a/common/test/common_tests/files/tokens_test.cljc +++ b/common/test/common_tests/files/tokens_test.cljc @@ -284,44 +284,129 @@ (t/is (= source-id (:tokens-source file-data')))))) (t/deftest test-tokens-source? - (t/testing "file-data has no tokens-source, asking for the same id as file-data returns true" + (t/testing "no tokens, no tokens-source, ask for file id -> false" (let [file (thf/sample-file :file1) file-data (:data file)] + (t/is (false? (cfo/tokens-source? file-data (:id file-data)))))) + + (t/testing "tokens, no tokens-source, ask for file id -> true" + (let [file (-> (thf/sample-file :file1) + (tht/add-tokens-lib)) + file-data (:data file)] (t/is (true? (cfo/tokens-source? file-data (:id file-data)))))) - (t/testing "file-data has no tokens-source, asking for any other uuid returns false" + (t/testing "no tokens, no tokens source, ask for other id -> false" (let [file (thf/sample-file :file1) file-data (:data file)] (t/is (false? (cfo/tokens-source? file-data (uuid/next)))))) - (t/testing "file-data has tokens-source equal to its own id, asking for the same id as file-data returns true" + (t/testing "tokens, no tokens source, ask for other id -> false" + (let [file (-> (thf/sample-file :file1) + (tht/add-tokens-lib)) + file-data (:data file)] + (t/is (false? (cfo/tokens-source? file-data (uuid/next)))))) + + ;; --- + + (t/testing "no tokens, tokens source = file id, ask for file id -> false" ;; This case should not occur (let [file (thf/sample-file :file1) file-data (cfo/set-tokens-source (:data file) (:id (:data file)))] + (t/is (false? (cfo/tokens-source? file-data (:id file-data)))))) + + (t/testing "tokens, tokens source = file id, ask for file id -> true" + (let [file (-> (thf/sample-file :file1) + (tht/add-tokens-lib)) + file-data (cfo/set-tokens-source (:data file) (:id (:data file)))] (t/is (true? (cfo/tokens-source? file-data (:id file-data)))))) - (t/testing "file-data has tokens-source equal to its own id, asking for any other uuid returns false" + (t/testing "no tokens, tokens source = file id, ask for other id -> false" ;; This case should not occur (let [file (thf/sample-file :file1) file-data (cfo/set-tokens-source (:data file) (:id (:data file)))] (t/is (false? (cfo/tokens-source? file-data (uuid/next)))))) - (t/testing "file-data has a new uuid as tokens-source, asking for the same id as file-data returns false" + (t/testing "tokens, tokens source = file id, ask for other id -> false" + (let [file (-> (thf/sample-file :file1) + (tht/add-tokens-lib)) + file-data (cfo/set-tokens-source (:data file) (:id (:data file)))] + (t/is (false? (cfo/tokens-source? file-data (uuid/next)))))) + + ;; --- + + (t/testing "no tokens, tokens source = other id, ask for file id -> false" (let [source-id (thi/new-id! :tokens-source) file (thf/sample-file :file1) file-data (cfo/set-tokens-source (:data file) source-id)] (t/is (false? (cfo/tokens-source? file-data (:id file-data)))))) - (t/testing "file-data has a new uuid as tokens-source, asking for the same id as the tokens-source returns true" + (t/testing "tokens, tokens source = other id, ask for file id -> false" + (let [source-id (thi/new-id! :tokens-source) + file (-> (thf/sample-file :file1) + (tht/add-tokens-lib)) + file-data (cfo/set-tokens-source (:data file) source-id)] + (t/is (false? (cfo/tokens-source? file-data (:id file-data)))))) + + (t/testing "no tokens, tokens source = other id, ask for this same id -> true" (let [source-id (thi/new-id! :tokens-source) file (thf/sample-file :file1) file-data (cfo/set-tokens-source (:data file) source-id)] (t/is (true? (cfo/tokens-source? file-data source-id))))) - (t/testing "file-data has a new uuid as tokens-source, asking for any other uuid returns false" + (t/testing "tokens, tokens source = other id, ask for this same id -> true" + (let [source-id (thi/new-id! :tokens-source) + file (-> (thf/sample-file :file1) + (tht/add-tokens-lib)) + file-data (cfo/set-tokens-source (:data file) source-id)] + (t/is (true? (cfo/tokens-source? file-data source-id))))) + + (t/testing "no tokens, tokens source = other id, ask for a different id -> false" (let [source-id (thi/new-id! :tokens-source) file (thf/sample-file :file1) file-data (cfo/set-tokens-source (:data file) source-id)] + (t/is (false? (cfo/tokens-source? file-data (uuid/next)))))) + + (t/testing "tokens, tokens source = other id, ask for a different id -> false" + (let [source-id (thi/new-id! :tokens-source) + file (-> (thf/sample-file :file1) + (tht/add-tokens-lib)) + file-data (cfo/set-tokens-source (:data file) source-id)] (t/is (false? (cfo/tokens-source? file-data (uuid/next))))))) +(t/deftest test-tokens-provider? + (t/testing "returns false if it has no tokens" + (let [file (thf/sample-file :file1) + file-data (:data file)] + (t/is (false? (cfo/tokens-provider? file-data (:id file-data)))) + (t/is (false? (cfo/tokens-provider? file-data (uuid/next)))))) + + (t/testing "returns true if it has tokens and no tokens-source" + (let [file (-> (thf/sample-file :file1) + (tht/add-tokens-lib)) + file-data (:data file)] + (t/is (true? (cfo/tokens-provider? file-data (:id file-data)))) + (t/is (true? (cfo/tokens-provider? file-data (uuid/next)))))) + + (t/testing "returns true if it has tokens and tokens-source is its own id" + (let [file (-> (thf/sample-file :file1) + (tht/add-tokens-lib)) + file-data (cfo/set-tokens-source (:data file) (:id file))] + (t/is (true? (cfo/tokens-provider? file-data (:id file-data)))) + (t/is (true? (cfo/tokens-provider? file-data (uuid/next)))))) + + (t/testing "returns false if it has tokens and tokens-source is other id and we are asking to other file" + (let [file (-> (thf/sample-file :file1) + (tht/add-tokens-lib)) + file-data (cfo/set-tokens-source (:data file) (uuid/next))] + (t/is (false? (cfo/tokens-provider? file-data (uuid/next)))))) + + (t/testing "returns true if it has tokens and tokens-source is other id but we are asking to the same file" + (let [file (-> (thf/sample-file :file1) + (tht/add-tokens-lib)) + file-data (cfo/set-tokens-source (:data file) (uuid/next))] + (t/is (true? (cfo/tokens-provider? file-data (:id file-data)))))) + + + ) + (t/deftest test-editable-tokens? (t/testing "returns true when file-data has no tokens-source" (let [file (thf/sample-file :file1) diff --git a/frontend/src/app/main/ui/workspace/libraries.cljs b/frontend/src/app/main/ui/workspace/libraries.cljs index c21eec5d14..761909ea46 100644 --- a/frontend/src/app/main/ui/workspace/libraries.cljs +++ b/frontend/src/app/main/ui/workspace/libraries.cljs @@ -284,6 +284,15 @@ :tokens/import-from-library {:file-id file-id :library-id library-id}))))) + set-as-tokens-source + (mf/use-fn + (mf/deps file-id) + (fn [event] + (let [_library-id (some-> (dom/get-current-target event) + (dom/get-data "library-id") + (uuid/parse))] + #_(st/emit! (dwl/set-tokens-source file-id library-id))))) + on-delete-accept (mf/use-fn (mf/deps file-id) @@ -376,14 +385,20 @@ [:div (tr "workspace.libraries.tokens-source")]))] [:div {:class (stl/css :library-actions)} - (when ^boolean has-tokens? - [:> icon-button* - {:type "button" - :aria-label (tr "workspace.tokens.import-tokens") - :icon i/import-export - :data-library-id (dm/str id) - :variant "secondary" - :on-click import-tokens}]) + (if (contains? cf/flags :token-lib-sync) + (when (cfo/tokens-provider? (:data library) (:id local-library)) + [:> button* {:variant "secondary" + :type "button" + :on-click (partial set-as-tokens-source id)} + (tr "workspace.libraries.set-as-tokens-source")]) + (when ^boolean has-tokens? + [:> icon-button* + {:type "button" + :aria-label (tr "workspace.tokens.import-tokens") + :icon i/import-export + :data-library-id (dm/str id) + :variant "secondary" + :on-click import-tokens}])) [:> icon-button* {:type "button" :aria-label (tr "workspace.libraries.unlink-library-btn") diff --git a/frontend/test/frontend_tests/tokens/logic/token_actions_test.cljs b/frontend/test/frontend_tests/tokens/logic/token_actions_test.cljs index 9eb0be8dfa..a0c9eb3632 100644 --- a/frontend/test/frontend_tests/tokens/logic/token_actions_test.cljs +++ b/frontend/test/frontend_tests/tokens/logic/token_actions_test.cljs @@ -6,7 +6,6 @@ (ns frontend-tests.tokens.logic.token-actions-test (:require - [app.common.files.tokens :as cfo] [app.common.test-helpers.compositions :as ctho] [app.common.test-helpers.files :as cthf] [app.common.test-helpers.ids-map :as cthi] diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 7f7174706e..2eb3249231 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -7121,6 +7121,10 @@ msgstr "File library" msgid "workspace.libraries.tokens-source" msgstr "Tokens source" +#: src/app/main/ui/workspace/libraries.cljs:336 +msgid "workspace.libraries.set-as-tokens-source" +msgstr "Set as tokens source" + #: src/app/main/ui/workspace/libraries.cljs:100, src/app/main/ui/workspace/libraries.cljs:124 msgid "workspace.libraries.graphics" msgid_plural "workspace.libraries.graphics" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 3c1b22d9e3..118036a76e 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -6948,6 +6948,10 @@ msgstr "Biblioteca del archivo" msgid "workspace.libraries.tokens-source" msgstr "Fuente de tokens" +#: src/app/main/ui/workspace/libraries.cljs:336 +msgid "workspace.libraries.set-as-tokens-source" +msgstr "Activar fuente de tokens" + #: src/app/main/ui/workspace/libraries.cljs:100, src/app/main/ui/workspace/libraries.cljs:124 msgid "workspace.libraries.graphics" msgid_plural "workspace.libraries.graphics"