From fb0e22c16b54c2b7d31f225c3876827c1debb3eb Mon Sep 17 00:00:00 2001 From: Alonso Torres Date: Wed, 12 Feb 2025 15:35:28 +0100 Subject: [PATCH 01/10] :bug: Fix problem with team permissions redirection (#5839) --- frontend/src/app/main/data/team.cljs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/frontend/src/app/main/data/team.cljs b/frontend/src/app/main/data/team.cljs index 7ffb46463..5ff7cf097 100644 --- a/frontend/src/app/main/data/team.cljs +++ b/frontend/src/app/main/data/team.cljs @@ -8,6 +8,7 @@ (:require [app.common.data :as d] [app.common.data.macros :as dm] + [app.common.exceptions :as ex] [app.common.logging :as log] [app.common.schema :as sm] [app.common.types.team :as ctt] @@ -118,8 +119,10 @@ (let [team-id (:current-team-id state) teams (get state :teams) team (get teams team-id)] - (rx/of (set-current-team team) - (fetch-members)))))) + (if (not team) + (rx/throw (ex/error :type :authentication)) + (rx/of (set-current-team team) + (fetch-members))))))) (defn initialize-team [team-id] From fb6cd3d9d498b2951895915468e88c3b23523498 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bel=C3=A9n=20Albeza?= Date: Wed, 12 Feb 2025 15:36:01 +0100 Subject: [PATCH 02/10] :bug: Fix "Publish empty library" modal appearing for non-empty libraries (#5838) * :bug: Fix 'Publish empty library' modal appearing for non-empty libraries * :sparkles: Add integration test for bug 10113 --- .../data/workspace/get-file-10113.json | 115 ++++++++++++++++++ .../workspace/get-file-fragment-10113.json | 101 +++++++++++++++ .../get-team-shared-files-empty.json | 1 + .../data/workspace/set-file-shared-10113.json | 5 + .../ui/specs/workspace-shared-library.spec.js | 38 ++++++ .../src/app/main/ui/workspace/libraries.cljs | 10 +- 6 files changed, 261 insertions(+), 9 deletions(-) create mode 100644 frontend/playwright/data/workspace/get-file-10113.json create mode 100644 frontend/playwright/data/workspace/get-file-fragment-10113.json create mode 100644 frontend/playwright/data/workspace/get-team-shared-files-empty.json create mode 100644 frontend/playwright/data/workspace/set-file-shared-10113.json diff --git a/frontend/playwright/data/workspace/get-file-10113.json b/frontend/playwright/data/workspace/get-file-10113.json new file mode 100644 index 000000000..c85e21966 --- /dev/null +++ b/frontend/playwright/data/workspace/get-file-10113.json @@ -0,0 +1,115 @@ +{ + "~:features": { + "~#set": [ + "layout/grid", + "fdata/pointer-map", + "fdata/objects-map", + "components/v2", + "fdata/shape-data-type" + ] + }, + "~:permissions": { + "~:type": "~:membership", + "~:is-owner": true, + "~:is-admin": true, + "~:can-edit": true, + "~:can-read": true, + "~:is-logged": true + }, + "~:has-media-trimmed": false, + "~:comment-thread-seqn": 0, + "~:name": "10113 - Emtpy lib", + "~:revn": 1, + "~:modified-at": "~m1739365936352", + "~:vern": 0, + "~:id": "~u5b7ebd2b-2907-80db-8005-b9d67c20cf2e", + "~:is-shared": false, + "~:migrations": { + "~#ordered-set": [ + "legacy-2", + "legacy-3", + "legacy-5", + "legacy-6", + "legacy-7", + "legacy-8", + "legacy-9", + "legacy-10", + "legacy-11", + "legacy-12", + "legacy-13", + "legacy-14", + "legacy-16", + "legacy-17", + "legacy-18", + "legacy-19", + "legacy-25", + "legacy-26", + "legacy-27", + "legacy-28", + "legacy-29", + "legacy-31", + "legacy-32", + "legacy-33", + "legacy-34", + "legacy-36", + "legacy-37", + "legacy-38", + "legacy-39", + "legacy-40", + "legacy-41", + "legacy-42", + "legacy-43", + "legacy-44", + "legacy-45", + "legacy-46", + "legacy-47", + "legacy-48", + "legacy-49", + "legacy-50", + "legacy-51", + "legacy-52", + "legacy-53", + "legacy-54", + "legacy-55", + "legacy-56", + "legacy-57", + "legacy-59", + "legacy-62", + "legacy-65", + "legacy-66", + "legacy-67" + ] + }, + "~:version": 67, + "~:project-id": "~u1ad2931c-eb80-8098-8005-b86c1d9d26c2", + "~:created-at": "~m1739365911709", + "~:data": { + "~:pages": [ + "~u5b7ebd2b-2907-80db-8005-b9d67c20cf2f" + ], + "~:pages-index": { + "~u5b7ebd2b-2907-80db-8005-b9d67c20cf2f": { + "~#penpot/pointer": [ + "~u5b7ebd2b-2907-80db-8005-b9d67c21cbd3", + { + "~:created-at": "~m1739365911687" + } + ] + } + }, + "~:id": "~u5b7ebd2b-2907-80db-8005-b9d67c20cf2e", + "~:options": { + "~:components-v2": true + }, + "~:colors": { + "~u84a1567d-3f0f-804e-8005-b9d6907e3c8a": { + "~:path": "", + "~:color": "#0087ff", + "~:name": "#0087ff", + "~:modified-at": "~m1739365936355", + "~:opacity": 1, + "~:id": "~u84a1567d-3f0f-804e-8005-b9d6907e3c8a" + } + } + } +} diff --git a/frontend/playwright/data/workspace/get-file-fragment-10113.json b/frontend/playwright/data/workspace/get-file-fragment-10113.json new file mode 100644 index 000000000..c37908a60 --- /dev/null +++ b/frontend/playwright/data/workspace/get-file-fragment-10113.json @@ -0,0 +1,101 @@ +{ + "~:id": "~u5b7ebd2b-2907-80db-8005-b9d67c21cbd3", + "~:file-id": "~u5b7ebd2b-2907-80db-8005-b9d67c20cf2e", + "~:created-at": "~m1739365911680", + "~:data": { + "~:options": {}, + "~:objects": { + "~u00000000-0000-0000-0000-000000000000": { + "~#shape": { + "~:y": 0, + "~:hide-fill-on-export": false, + "~:transform": { + "~#matrix": { + "~:a": 1.0, + "~:b": 0.0, + "~:c": 0.0, + "~:d": 1.0, + "~:e": 0.0, + "~:f": 0.0 + } + }, + "~:rotation": 0, + "~:name": "Root Frame", + "~:width": 0.01, + "~:type": "~:frame", + "~:points": [ + { + "~#point": { + "~:x": 0.0, + "~:y": 0.0 + } + }, + { + "~#point": { + "~:x": 0.01, + "~:y": 0.0 + } + }, + { + "~#point": { + "~:x": 0.01, + "~:y": 0.01 + } + }, + { + "~#point": { + "~:x": 0.0, + "~:y": 0.01 + } + } + ], + "~:r2": 0, + "~:proportion-lock": false, + "~:transform-inverse": { + "~#matrix": { + "~:a": 1.0, + "~:b": 0.0, + "~:c": 0.0, + "~:d": 1.0, + "~:e": 0.0, + "~:f": 0.0 + } + }, + "~:r3": 0, + "~:r1": 0, + "~:id": "~u00000000-0000-0000-0000-000000000000", + "~:parent-id": "~u00000000-0000-0000-0000-000000000000", + "~:frame-id": "~u00000000-0000-0000-0000-000000000000", + "~:strokes": [], + "~:x": 0, + "~:proportion": 1.0, + "~:r4": 0, + "~:selrect": { + "~#rect": { + "~:x": 0, + "~:y": 0, + "~:width": 0.01, + "~:height": 0.01, + "~:x1": 0, + "~:y1": 0, + "~:x2": 0.01, + "~:y2": 0.01 + } + }, + "~:fills": [ + { + "~:fill-color": "#FFFFFF", + "~:fill-opacity": 1 + } + ], + "~:flip-x": null, + "~:height": 0.01, + "~:flip-y": null, + "~:shapes": [] + } + } + }, + "~:id": "~u5b7ebd2b-2907-80db-8005-b9d67c20cf2f", + "~:name": "Page 1" + } +} \ No newline at end of file diff --git a/frontend/playwright/data/workspace/get-team-shared-files-empty.json b/frontend/playwright/data/workspace/get-team-shared-files-empty.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/frontend/playwright/data/workspace/get-team-shared-files-empty.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/frontend/playwright/data/workspace/set-file-shared-10113.json b/frontend/playwright/data/workspace/set-file-shared-10113.json new file mode 100644 index 000000000..9ff97cb34 --- /dev/null +++ b/frontend/playwright/data/workspace/set-file-shared-10113.json @@ -0,0 +1,5 @@ +{ + "~:id": "~u5b7ebd2b-2907-80db-8005-b9d67c20cf2e", + "~:name": "10113 - Emtpy lib", + "~:is-shared": true +} diff --git a/frontend/playwright/ui/specs/workspace-shared-library.spec.js b/frontend/playwright/ui/specs/workspace-shared-library.spec.js index 89c53cb7c..eaef180ae 100644 --- a/frontend/playwright/ui/specs/workspace-shared-library.spec.js +++ b/frontend/playwright/ui/specs/workspace-shared-library.spec.js @@ -72,3 +72,41 @@ test("Bug 9056 - 'More info' doesn't open the update tab", async ({ page }) => { /library updates/i, ); }); + +test("Bug 10113 - Empty library modal for non-empty library", async ({ + page, +}) => { + const workspace = new WorkspacePage(page); + + await workspace.setupEmptyFile(page); + await workspace.mockRPC(/get\-file\?/, "workspace/get-file-10113.json"); + await workspace.mockRPC( + "get-file-fragment?file-id=*&fragment-id=*", + "workspace/get-file-fragment-10113.json", + ); + await workspace.mockRPC(/get\-file\?/, "workspace/get-file-10113.json"); + await workspace.mockRPC( + "get-team-shared-files?team-id=*", + "workspace/get-team-shared-files-empty.json", + ); + await workspace.mockRPC( + "set-file-shared", + "workspace/set-file-shared-10113.json", + ); + + await workspace.goToWorkspace({ + fileId: "5b7ebd2b-2907-80db-8005-b9d67c20cf2e", + pageId: "5b7ebd2b-2907-80db-8005-b9d67c20cf2f", + }); + + await workspace.clickAssets(); + await workspace.openLibrariesModal(); + + await workspace.librariesModal + .getByRole("button", { name: "Publish" }) + .click(); + + await expect( + workspace.page.getByText("Publish empty library"), + ).not.toBeVisible(); +}); diff --git a/frontend/src/app/main/ui/workspace/libraries.cljs b/frontend/src/app/main/ui/workspace/libraries.cljs index ce1daca56..ed4e8e4b9 100644 --- a/frontend/src/app/main/ui/workspace/libraries.cljs +++ b/frontend/src/app/main/ui/workspace/libraries.cljs @@ -176,15 +176,7 @@ (defn- empty-library? "Check if currentt library summary has elements or not" [summary] - (let [colors (or (-> summary :colors :count) 0) - components (or (-> summary :components :count) 0) - media (or (-> summary :media :count) 0) - typographies (or (-> summary :typographies :count) 0)] - - (and (zero? colors) - (zero? components) - (zero? media) - (zero? typographies)))) + (boolean (:is-empty summary))) (mf/defc libraries-tab* {::mf/props :obj From 638a8a8d3f8be70556be0090734b833a13035126 Mon Sep 17 00:00:00 2001 From: Luis de Dios Date: Wed, 12 Feb 2025 12:55:47 +0100 Subject: [PATCH 03/10] :bug: Fix keyboard interactions with mentions --- frontend/src/app/main/ui/comments.cljs | 43 +++++++++++++++++++++----- frontend/src/app/main/ui/comments.scss | 1 - frontend/translations/en.po | 4 +++ frontend/translations/es.po | 4 +++ 4 files changed, 44 insertions(+), 8 deletions(-) diff --git a/frontend/src/app/main/ui/comments.cljs b/frontend/src/app/main/ui/comments.cljs index c41e4273f..6e0d1da30 100644 --- a/frontend/src/app/main/ui/comments.cljs +++ b/frontend/src/app/main/ui/comments.cljs @@ -237,9 +237,14 @@ (str/last-index-of (subs node-text 0 offset) "@") mention-text - (subs node-text current-at-symbol)] + (subs node-text current-at-symbol) - (if (re-matches #"@\w*" mention-text) + at-symbol-inside-word? + (and (> current-at-symbol 0) + (str/word? (str/slice node-text (- current-at-symbol 1) current-at-symbol)))] + + (if (and (not at-symbol-inside-word?) + (re-matches #"@\w*" mention-text)) (do (reset! cur-mention mention-text) (rx/push! mentions-s {:type :display-mentions}) @@ -305,6 +310,17 @@ (when (fn? on-change) (on-change (parse-nodes node)))))))) + handle-insert-at-symbol + (mf/use-fn + (fn [] + (let [node (mf/ref-val local-ref) [span-node] (current-text-node node)] + (when span-node + (let [node-text (dom/get-text span-node) + at-symbol (if (blank-content? node-text) "@" " @")] + + (dom/set-html! span-node (str/concat node-text at-symbol)) + (wapi/set-cursor-after! span-node)))))) + handle-key-down (mf/use-fn (mf/deps on-esc on-ctrl-enter handle-select handle-input) @@ -386,6 +402,8 @@ (case type :insert-mention (handle-insert-mention data) + :insert-at-symbol + (handle-insert-at-symbol) nil)))))) @@ -521,15 +539,25 @@ {::mf/props :obj ::mf/private true} [] - (let [mentions-s (mf/use-ctx mentions-context) + (let [mentions-s (mf/use-ctx mentions-context) display-mentions* (mf/use-state false) - handle-mouse-down + handle-pointer-down (mf/use-fn + (mf/deps @display-mentions*) (fn [event] (dom/prevent-default event) (dom/stop-propagation event) - (rx/push! mentions-s {:type :display-mentions})))] + (if @display-mentions* + (rx/push! mentions-s {:type :hide-mentions}) + (rx/push! mentions-s {:type :insert-at-symbol})))) + + handle-key-down + (mf/use-fn + (mf/deps @display-mentions*) + (fn [event] + (when (or (kbd/enter? event) (kbd/space? event)) + (handle-pointer-down event))))] (mf/use-effect (fn [] @@ -545,8 +573,9 @@ [:> icon-button* {:variant "ghost" - :aria-label (tr "labels.options") - :on-pointer-down handle-mouse-down + :aria-label (tr "labels.mention") + :on-pointer-down handle-pointer-down + :on-key-down handle-key-down :icon-class (stl/css-case :open-mentions-button true :is-toggled @display-mentions*) :icon "at"}])) diff --git a/frontend/src/app/main/ui/comments.scss b/frontend/src/app/main/ui/comments.scss index 70fd5b793..8dda4e806 100644 --- a/frontend/src/app/main/ui/comments.scss +++ b/frontend/src/app/main/ui/comments.scss @@ -255,7 +255,6 @@ } .open-mentions-button { - cursor: pointer; stroke: none; fill: var(--color-foreground-secondary); diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 3d5f7002d..e34b501bf 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -2012,6 +2012,10 @@ msgstr "Member" msgid "labels.members" msgstr "Members" +#: src/app/main/ui/comments.cljs:558 +msgid "labels.mention" +msgstr "Mention" + #: src/app/main/ui/settings/password.cljs:84 msgid "labels.new-password" msgstr "New password" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 642e22aff..89f668712 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -2015,6 +2015,10 @@ msgstr "Integrante" msgid "labels.members" msgstr "Integrantes" +#: src/app/main/ui/comments.cljs:558 +msgid "labels.mention" +msgstr "Mencionar" + #: src/app/main/ui/settings/password.cljs:84 msgid "labels.new-password" msgstr "Nueva contraseña" From 688b9f219459f87d1b47b9c9711fb56e04eaf39b Mon Sep 17 00:00:00 2001 From: Alonso Torres Date: Wed, 12 Feb 2025 17:16:14 +0100 Subject: [PATCH 04/10] :bug: Fix focus to main component (#5842) --- frontend/src/app/main/data/workspace/libraries.cljs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/frontend/src/app/main/data/workspace/libraries.cljs b/frontend/src/app/main/data/workspace/libraries.cljs index 95d1df358..2cf8ad292 100644 --- a/frontend/src/app/main/data/workspace/libraries.cljs +++ b/frontend/src/app/main/data/workspace/libraries.cljs @@ -741,12 +741,12 @@ redirect-to-page (fn [page-id shape-id] (rx/merge - (rx/of (dcm/go-to-workspace :page-id page-id)) (->> stream - (rx/filter (ptk/type? ::initialize-page)) + (rx/filter (ptk/type? ::dw/initialize-page)) (rx/take 1) (rx/observe-on :async) - (rx/mapcat (fn [_] (select-and-zoom shape-id))))))] + (rx/mapcat (fn [_] (select-and-zoom shape-id)))) + (rx/of (dcm/go-to-workspace :page-id page-id))))] (when-let [component (dm/get-in data [:components id])] (let [page-id (:main-instance-page component) From 2d1d1fee1c0773cc7068a3e6471858c92e812afe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?andr=C3=A9s=20gonz=C3=A1lez?= Date: Thu, 13 Feb 2025 10:42:56 +0100 Subject: [PATCH 05/10] :books: Info about gradients (#5843) --- docs/img/styling/color-picker-gradient.webp | Bin 0 -> 8862 bytes docs/user-guide/styling/index.njk | 13 ++++++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) create mode 100644 docs/img/styling/color-picker-gradient.webp diff --git a/docs/img/styling/color-picker-gradient.webp b/docs/img/styling/color-picker-gradient.webp new file mode 100644 index 0000000000000000000000000000000000000000..eec479e7023901e06f6e8caff00a22e133d33691 GIT binary patch literal 8862 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
  • Eyedropper - Allows you to pick any color of the objects at the viewport.
  • Color profiles - Select between RGB, the Harmony Wheel or HSV.
  • -
  • Color type - Solid, linear gradient, radial gradient or image.
  • +
  • Color type - Solid, gradient, or image.
  • Sliders - Easily manage settings like brightness, saturation or opacity.
  • Values - Set precise color values of red(R), green(G), blue(B) and transparency(A).
  • Libraries - Switch between recent colors and libraries.
  • Color palette - A quick launcher of the palette with the selected library.
  • +

    Gradients

    +

    You can apply gradient fills to layers. To do that select the Gradient type at the color picker.

    +
    + Gradient +
    +

    You can choose between two types of gradients:

    +
      +
    • Linear Gradient: A smooth transition between two or more colors along a straight line, with the option to adjust the angle.
    • +
    • Radial Gradient: A circular color transition that starts with one color at the center and gradually shifts to another at the edges, which could be a different color or a fade to transparency.
    • +
    +

    Color palette

    The color palette allows you to have a selected color library in plain sight.

    From f8820695cc56cb99b05e8ecc017aa1a40fb1034f Mon Sep 17 00:00:00 2001 From: Alejandro Date: Thu, 13 Feb 2025 11:55:59 +0100 Subject: [PATCH 06/10] :bug: Fix incorrect numbering files when new team (#5835) --- backend/src/app/rpc/commands/files.clj | 10 +++++++--- frontend/src/app/main/data/dashboard.cljs | 11 ++++++----- frontend/src/app/main/data/helpers.cljs | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/backend/src/app/rpc/commands/files.clj b/backend/src/app/rpc/commands/files.clj index 784e52484..3d2098712 100644 --- a/backend/src/app/rpc/commands/files.clj +++ b/backend/src/app/rpc/commands/files.clj @@ -384,8 +384,10 @@ f.revn, f.vern, f.is_shared, - ft.media_id AS thumbnail_id + ft.media_id AS thumbnail_id, + p.team_id from file as f + inner join project as p on (p.id = f.project_id) left join file_thumbnail as ft on (ft.file_id = f.id and ft.revn = f.revn and ft.deleted_at is null) @@ -539,7 +541,8 @@ f.modified_at, f.name, f.is_shared, - ft.media_id + ft.media_id, + p.team_id from file as f inner join project as p on (p.id = f.project_id) left join file_thumbnail as ft on (ft.file_id = f.id and ft.revn = f.revn and ft.deleted_at is null) @@ -686,7 +689,8 @@ f.name, f.is_shared, ft.media_id AS thumbnail_id, - row_number() over w as row_num + row_number() over w as row_num, + p.team_id from file as f inner join project as p on (p.id = f.project_id) left join file_thumbnail as ft on (ft.file_id = f.id diff --git a/frontend/src/app/main/data/dashboard.cljs b/frontend/src/app/main/data/dashboard.cljs index 3f0d9bbd3..ddd2206b5 100644 --- a/frontend/src/app/main/data/dashboard.cljs +++ b/frontend/src/app/main/data/dashboard.cljs @@ -16,6 +16,7 @@ [app.main.data.common :as dcm] [app.main.data.event :as ev] [app.main.data.fonts :as df] + [app.main.data.helpers :as dsh] [app.main.data.modal :as modal] [app.main.data.websocket :as dws] [app.main.features :as features] @@ -247,10 +248,10 @@ (ptk/reify ::create-project ptk/WatchEvent (watch [_ state _] - (let [projects (get state :projects) + (let [team-id (:current-team-id state) + projects (dsh/lookup-team-projects state team-id) unames (cfh/get-used-names projects) name (cfh/generate-unique-name unames (str (tr "dashboard.new-project-prefix") " 1")) - team-id (:current-team-id state) params {:name name :team-id team-id} {:keys [on-success on-error] @@ -478,7 +479,7 @@ :or {on-success identity on-error rx/throw}} (meta params) - files (get state :files) + files (dsh/lookup-team-files state) unames (cfh/get-used-names files) name (or name (cfh/generate-unique-name unames (str (tr "dashboard.new-file-prefix") " 1"))) features (-> (features/get-team-enabled-features state) @@ -587,10 +588,10 @@ pparams (:path-params route) in-project? (contains? pparams :project-id) name (if in-project? - (let [files (get state :files) + (let [files (dsh/lookup-team-files state team-id) unames (cfh/get-used-names files)] (cfh/generate-unique-name unames (str (tr "dashboard.new-file-prefix") " 1"))) - (let [projects (get state :projects) + (let [projects (dsh/lookup-team-projects state team-id) unames (cfh/get-used-names projects)] (cfh/generate-unique-name unames (str (tr "dashboard.new-project-prefix") " 1")))) params (if in-project? diff --git a/frontend/src/app/main/data/helpers.cljs b/frontend/src/app/main/data/helpers.cljs index b104af0dc..279e3e0b2 100644 --- a/frontend/src/app/main/data/helpers.cljs +++ b/frontend/src/app/main/data/helpers.cljs @@ -168,3 +168,21 @@ [state] (when-let [{:keys [x y width height]} (get-in state [:workspace-local :vbox])] (gpt/point (+ x (/ width 2)) (+ y (/ height 2))))) + +(defn lookup-team-files + ([state] + (lookup-team-files state (:current-team-id state))) + ([state team-id] + (->> state + :files + (filter #(= team-id (:team-id (val %)))) + (into {})))) + +(defn lookup-team-projects + ([state] + (lookup-team-projects (:current-team-id state))) + ([state team-id] + (->> state + :projects + (filter #(= team-id (:team-id (val %)))) + (into {})))) From 46d23591076916a4bf8745a2e092b6c502d85e91 Mon Sep 17 00:00:00 2001 From: Eva Marco Date: Thu, 13 Feb 2025 15:48:44 +0100 Subject: [PATCH 07/10] :bug: Fix empty translation strings (#5847) --- frontend/src/app/main/data/common.cljs | 2 +- .../app/main/ui/settings/access_tokens.cljs | 1 - .../workspace/sidebar/options/menus/bool.cljs | 4 +-- .../ui/workspace/tokens/modals/themes.cljs | 2 +- frontend/translations/en.po | 25 ++----------------- 5 files changed, 6 insertions(+), 28 deletions(-) diff --git a/frontend/src/app/main/data/common.cljs b/frontend/src/app/main/data/common.cljs index cd8e73186..064d1901d 100644 --- a/frontend/src/app/main/data/common.cljs +++ b/frontend/src/app/main/data/common.cljs @@ -84,7 +84,7 @@ :controls :inline-actions :type :inline :level level - :accept {:label (tr "Refresh") + :accept {:label (tr "labels.refresh") :callback force-reload!} :tag :notification)) diff --git a/frontend/src/app/main/ui/settings/access_tokens.cljs b/frontend/src/app/main/ui/settings/access_tokens.cljs index b555e47e5..198165076 100644 --- a/frontend/src/app/main/ui/settings/access_tokens.cljs +++ b/frontend/src/app/main/ui/settings/access_tokens.cljs @@ -149,7 +149,6 @@ [:input {:type "text" :value (:token created "") :class (stl/css :custom-input-token) - :placeholder (tr "modals.create-access-token.token") :read-only true}] [:button {:title (tr "modals.create-access-token.copy-token") :class (stl/css :copy-btn) diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/bool.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/bool.cljs index e223622b8..c3c2b68de 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/bool.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/bool.cljs @@ -77,12 +77,12 @@ [:& radio-button {:icon i/boolean-intersection :value "intersection" :disabled disabled-bool-btns - :title (str (tr "intersection") " (" (sc/get-tooltip :bool-intersection) ")") + :title (str (tr "workspace.shape.menu.intersection") " (" (sc/get-tooltip :bool-intersection) ")") :id "bool-opt-intersection"}] [:& radio-button {:icon i/boolean-exclude :value "exclude" :disabled disabled-bool-btns - :title (str (tr "exclude") " (" (sc/get-tooltip :bool-exclude) ")") + :title (str (tr "workspace.shape.menu.exclude") " (" (sc/get-tooltip :bool-exclude) ")") :id "bool-opt-exclude"}]]] [:button diff --git a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs index 8e3b935a9..53e303164 100644 --- a/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs +++ b/frontend/src/app/main/ui/workspace/tokens/modals/themes.cljs @@ -120,7 +120,7 @@ (dom/prevent-default e) (dom/stop-propagation e) (st/emit! (wdt/toggle-token-theme-active? group name)))} - [:& switch {:name (tr "workspace.token.theme" name) + [:& switch {:name (tr "workspace.token.theme-name" name) :on-change (constantly nil) :selected? selected?}]] [:> text* {:as "span" :typography "body-medium" :class (stl/css :theme-name)} name]] diff --git a/frontend/translations/en.po b/frontend/translations/en.po index e34b501bf..3bc907e71 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -12,9 +12,8 @@ msgstr "" "X-Generator: Weblate 5.10-dev\n" #: src/app/main/data/common.cljs:87 -#, fuzzy -msgid "Refresh" -msgstr "" +msgid "labels.refresh" +msgstr "Refresh" #: src/app/main/ui/auth/register.cljs:133, src/app/main/ui/static.cljs:155, src/app/main/ui/viewer/login.cljs:98 msgid "auth.already-have-account" @@ -1382,11 +1381,6 @@ msgstr "Email or password is incorrect." msgid "errors.wrong-old-password" msgstr "Old password is incorrect" -#: src/app/main/ui/workspace/sidebar/options/menus/bool.cljs:85 -#, fuzzy -msgid "exclude" -msgstr "" - #: src/app/main/ui/settings/feedback.cljs:74 msgid "feedback.description" msgstr "Description" @@ -1687,11 +1681,6 @@ msgstr "Text" msgid "inspect.tabs.info" msgstr "Info" -#: src/app/main/ui/workspace/sidebar/options/menus/bool.cljs:80 -#, fuzzy -msgid "intersection" -msgstr "" - #: src/app/main/ui/workspace/main_menu.cljs:162 msgid "label.shortcuts" msgstr "Shortcuts" @@ -2454,11 +2443,6 @@ msgstr "Create token" msgid "modals.create-access-token.title" msgstr "Generate access token" -#: src/app/main/ui/settings/access_tokens.cljs:152 -#, fuzzy -msgid "modals.create-access-token.token" -msgstr "" - #: src/app/main/ui/dashboard/team.cljs:921 msgid "modals.create-webhook.submit-label" msgstr "Create webhook" @@ -6617,11 +6601,6 @@ msgstr "Select set." msgid "workspace.token.set-selection-theme" msgstr "Define what token sets should be used as part of this theme option:" -#: src/app/main/ui/workspace/tokens/modals/themes.cljs:123 -#, fuzzy -msgid "workspace.token.theme" -msgstr "" - #: src/app/main/ui/workspace/tokens/modals/themes.cljs #, unused msgid "workspace.token.theme-name" From 5d56d28cb64deefb07aaa4516be5d0b692a8559d Mon Sep 17 00:00:00 2001 From: Andrey Antukh Date: Thu, 13 Feb 2025 17:04:34 +0100 Subject: [PATCH 08/10] :bug: Fix workspace hot reload race condtion (#5851) Mainly ensure that all required paramers for workspace file and page bootstrap are always available from parameters and not taken from context --- frontend/src/app/main/data/dashboard.cljs | 9 ++-- frontend/src/app/main/data/workspace.cljs | 33 +++++++-------- frontend/src/app/main/router.cljs | 5 +++ frontend/src/app/main/ui.cljs | 1 - frontend/src/app/main/ui/workspace.cljs | 41 +++++++------------ .../logic/copying_and_duplicating_test.cljs | 4 +- 6 files changed, 42 insertions(+), 51 deletions(-) diff --git a/frontend/src/app/main/data/dashboard.cljs b/frontend/src/app/main/data/dashboard.cljs index ddd2206b5..7883225ec 100644 --- a/frontend/src/app/main/data/dashboard.cljs +++ b/frontend/src/app/main/data/dashboard.cljs @@ -460,10 +460,11 @@ ptk/UpdateEvent (update [_ state] - (-> state - (assoc-in [:files id] file) - (assoc-in [:recent-files id] file) - (update-in [:projects project-id :count] inc))))) + (let [file (dissoc file :data)] + (-> state + (assoc-in [:files id] file) + (assoc-in [:recent-files id] file) + (update-in [:projects project-id :count] inc)))))) (defn create-file [{:keys [project-id name] :as params}] diff --git a/frontend/src/app/main/data/workspace.cljs b/frontend/src/app/main/data/workspace.cljs index ccffeef9a..b0ef81e1f 100644 --- a/frontend/src/app/main/data/workspace.cljs +++ b/frontend/src/app/main/data/workspace.cljs @@ -319,8 +319,6 @@ ptk/UpdateEvent (update [_ state] (-> state - (dissoc :files) - (dissoc :workspace-ready) (assoc :recent-colors (:recent-colors storage/user)) (assoc :recent-fonts (:recent-fonts storage/user)) (assoc :current-file-id file-id) @@ -395,11 +393,9 @@ (dissoc :current-file-id :workspace-editor-state - :files :workspace-media-objects :workspace-persistence :workspace-presence - :workspace-ready :workspace-undo) (update :workspace-global dissoc :read-only?) (assoc-in [:workspace-global :options-mode] :design))) @@ -427,18 +423,18 @@ (defmethod ptk/resolve ::reload-current-file [_ _] (reload-current-file)) (defn initialize-page - [page-id] - (assert (uuid? page-id) "expected valid uuid for `page-id`") + [file-id page-id] + (assert (uuid? file-id) "expected valid uuid for `file-id`") (ptk/reify ::initialize-page ptk/UpdateEvent (update [_ state] - (if-let [{:keys [id] :as page} (dsh/lookup-page state page-id)] + (if-let [page (dsh/lookup-page state file-id page-id)] ;; we maintain a cache of page state for user convenience with the exception of the ;; selection; when user abandon the current page, the selection is lost - (let [local (dm/get-in state [:workspace-cache id] default-workspace-local)] + (let [local (dm/get-in state [:workspace-cache [file-id page-id]] default-workspace-local)] (-> state - (assoc :current-page-id id) + (assoc :current-page-id page-id) (assoc :workspace-local (assoc local :selected (d/ordered-set))) (assoc :workspace-trimmed-page (dm/select-keys page [:id :name])) @@ -450,24 +446,25 @@ ptk/WatchEvent (watch [_ state _] - (if (dsh/lookup-page state page-id) - (let [file-id (:current-file-id state)] - (rx/of (preload-data-uris page-id) - (dwth/watch-state-changes file-id page-id) - (dwl/watch-component-changes))) - (rx/of (dcm/go-to-workspace)))))) + (if (dsh/lookup-page state file-id page-id) + (rx/of (preload-data-uris page-id) + (dwth/watch-state-changes file-id page-id) + (dwl/watch-component-changes)) + (rx/of (dcm/go-to-workspace :file-id file-id ::rt/replace true)))))) (defn finalize-page - [page-id] + [file-id page-id] + (assert (uuid? file-id) "expected valid uuid for `file-id`") (assert (uuid? page-id) "expected valid uuid for `page-id`") + (ptk/reify ::finalize-page ptk/UpdateEvent (update [_ state] (let [local (-> (:workspace-local state) (dissoc :edition :edit-path :selected)) - exit? (not= :workspace (dm/get-in state [:route :data :name])) + exit? (not= :workspace (rt/lookup-name state)) state (-> state - (update :workspace-cache assoc page-id local) + (update :workspace-cache assoc [file-id page-id] local) (dissoc :current-page-id :workspace-local :workspace-trimmed-page diff --git a/frontend/src/app/main/router.cljs b/frontend/src/app/main/router.cljs index 58e421983..e4c3b16a1 100644 --- a/frontend/src/app/main/router.cljs +++ b/frontend/src/app/main/router.cljs @@ -120,6 +120,11 @@ ([id params & {:as options}] (navigate id params options))) +(defn lookup-name + [state] + (dm/get-in state [:route :data :name])) + +;; FIXME: rename to lookup-params (defn get-params [state] (dm/get-in state [:route :params :query])) diff --git a/frontend/src/app/main/ui.cljs b/frontend/src/app/main/ui.cljs index bf6b1ebaa..71eca09e2 100644 --- a/frontend/src/app/main/ui.cljs +++ b/frontend/src/app/main/ui.cljs @@ -127,7 +127,6 @@ {::mf/props :obj ::mf/private true} [{:keys [team-id children]}] - (mf/with-effect [team-id] (st/emit! (dtm/initialize-team team-id)) (fn [] diff --git a/frontend/src/app/main/ui/workspace.cljs b/frontend/src/app/main/ui/workspace.cljs index a169ae616..24bf92e2e 100644 --- a/frontend/src/app/main/ui/workspace.cljs +++ b/frontend/src/app/main/ui/workspace.cljs @@ -9,7 +9,6 @@ (:require [app.common.data.macros :as dm] [app.main.data.common :as dcm] - [app.main.data.helpers :as dsh] [app.main.data.persistence :as dps] [app.main.data.plugins :as dpl] [app.main.data.workspace :as dw] @@ -43,13 +42,6 @@ [okulary.core :as l] [rumext.v2 :as mf])) -(defn- make-workspace-ready-ref - [file-id] - (l/derived (fn [state] - (and (= file-id (:workspace-ready state)) - (some? (dsh/lookup-file-data state file-id)))) - st/state)) - (mf/defc workspace-content* {::mf/private true} [{:keys [file layout page wglobal]}] @@ -138,22 +130,18 @@ key (events/listen globals/window "blur" focus-out)] (partial events/unlistenByKey key))) - (mf/with-effect [page-id] - (if (some? page-id) - (st/emit! (dw/initialize-page page-id)) - (st/emit! (dcm/go-to-workspace ::rt/replace true))) - + (mf/with-effect [file page-id] + (st/emit! (dw/initialize-page (:id file) page-id)) (fn [] - (when (some? page-id) - (st/emit! (dw/finalize-page page-id))))) + (when page-id + (st/emit! (dw/finalize-page (:id file) page-id))))) (if (some? page) [:> workspace-content* {:file file :page page :wglobal wglobal :layout layout}] - [:& workspace-loader*]))) - + [:> workspace-loader*]))) (def ^:private ref:file-without-data (l/derived (fn [file] @@ -181,10 +169,6 @@ read-only? (mf/deref refs/workspace-read-only?) read-only? (or read-only? (not (:can-edit permissions))) - ready* (mf/with-memo [file-id] - (make-workspace-ready-ref file-id)) - ready? (mf/deref ready*) - design-tokens? (features/use-feature "design-tokens/v1") background-color (:background-color wglobal)] @@ -207,6 +191,10 @@ (st/emit! ::dps/force-persist (dw/finalize-workspace file-id)))) + (mf/with-effect [file page-id] + (when-not page-id + (st/emit! (dcm/go-to-workspace :file-id file-id ::rt/replace true)))) + [:> (mf/provider ctx/current-project-id) {:value project-id} [:> (mf/provider ctx/current-file-id) {:value file-id} [:> (mf/provider ctx/current-page-id) {:value page-id} @@ -219,9 +207,10 @@ :touch-action "none"}} [:> context-menu*] - (if ^boolean ready? - [:> workspace-page* {:page-id page-id - :file file - :wglobal wglobal - :layout layout}] + (if (some? file) + [:> workspace-page* + {:page-id page-id + :file file + :wglobal wglobal + :layout layout}] [:> workspace-loader*])]]]]]]])) diff --git a/frontend/test/frontend_tests/logic/copying_and_duplicating_test.cljs b/frontend/test/frontend_tests/logic/copying_and_duplicating_test.cljs index 3d331c616..a6a59047a 100644 --- a/frontend/test/frontend_tests/logic/copying_and_duplicating_test.cljs +++ b/frontend/test/frontend_tests/logic/copying_and_duplicating_test.cljs @@ -63,10 +63,10 @@ target-container-id (or target-container-id (:parent-id shape))] (filter some? - [(when target-page-id (dw/initialize-page target-page-id)) + [(when target-page-id (dw/initialize-page (:id file) target-page-id)) (dws/select-shape target-container-id) (dw/paste-shapes pdata) - (when target-page-id (dw/initialize-page (:id page)))]))) + (when target-page-id (dw/initialize-page (:id file) (:id page)))]))) (defn- sync-file [file] (map (fn [component-tag] From d836cc66da80f20a2a0ad5db31903102f4ed71f7 Mon Sep 17 00:00:00 2001 From: Pablo Alba Date: Thu, 13 Feb 2025 17:30:33 +0100 Subject: [PATCH 09/10] :bug: Fix unable to drag & drop assets into/outside component groups (#5849) --- .../src/app/main/ui/workspace/sidebar/assets/components.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 bef71e37e..15f81726c 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets/components.cljs @@ -534,7 +534,7 @@ :on-ungroup on-ungroup :on-context-menu on-context-menu :selected-full selected-full - :local ^boolean is-local}]) + :is-local ^boolean is-local}]) [:& cmm/assets-context-menu {:on-close on-close-menu From af93325fd9a8b5840d312606b2d7db1fd499c914 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marina=20L=C3=B3pez?= Date: Thu, 13 Feb 2025 20:06:28 +0100 Subject: [PATCH 10/10] :tada: Consolidate suggested libraries and add library button (#5828) --- frontend/playwright/ui/pages/WorkspacePage.js | 2 +- .../src/app/main/ui/workspace/libraries.cljs | 16 +--------------- .../src/app/main/ui/workspace/libraries.scss | 10 ---------- .../app/main/ui/workspace/sidebar/assets.cljs | 17 ++--------------- frontend/translations/en.po | 8 -------- frontend/translations/es.po | 8 -------- 6 files changed, 4 insertions(+), 57 deletions(-) diff --git a/frontend/playwright/ui/pages/WorkspacePage.js b/frontend/playwright/ui/pages/WorkspacePage.js index 87a2eedab..f905cf8b4 100644 --- a/frontend/playwright/ui/pages/WorkspacePage.js +++ b/frontend/playwright/ui/pages/WorkspacePage.js @@ -221,7 +221,7 @@ export class WorkspacePage extends BaseWebSocketPage { } async openLibrariesModal(clickOptions = {}) { - await this.sidebar.getByText("Libraries").click(clickOptions); + await this.sidebar.getByTestId("libraries").click(clickOptions); await expect(this.librariesModal).toBeVisible(); } diff --git a/frontend/src/app/main/ui/workspace/libraries.cljs b/frontend/src/app/main/ui/workspace/libraries.cljs index ed4e8e4b9..5a07a1a25 100644 --- a/frontend/src/app/main/ui/workspace/libraries.cljs +++ b/frontend/src/app/main/ui/workspace/libraries.cljs @@ -14,7 +14,6 @@ [app.common.types.file :as ctf] [app.common.types.typographies-list :as ctyl] [app.common.uuid :as uuid] - [app.config :as cf] [app.main.data.dashboard :as dd] [app.main.data.modal :as modal] [app.main.data.notifications :as ntf] @@ -354,7 +353,7 @@ (nil? shared-libraries) (tr "workspace.libraries.loading") - (and (str/empty? search-term) (cf/external-feature-flag "templates-03" "test")) + (str/empty? search-term) [:* [:div {:class (stl/css :sample-libraries-info)} (tr "workspace.libraries.empty.no-libraries") @@ -369,19 +368,6 @@ {:library library :importing importing*}])]] - (str/empty? search-term) - [:* - [:span {:class (stl/css :empty-state-icon)} - library-icon] - (tr "workspace.libraries.no-shared-libraries-available") - (when (cf/external-feature-flag "templates-01" "test") - [:div {:class (stl/css :templates-info)} - (tr "workspace.libraries.more-templates") - [:a {:target "_blank" - :class (stl/css :templates-info-link) - :href "https://penpot.app/libraries-templates"} - (tr "workspace.libraries.more-templates-link")]])] - :else (tr "workspace.libraries.no-matches-for" search-term))]))]])) diff --git a/frontend/src/app/main/ui/workspace/libraries.scss b/frontend/src/app/main/ui/workspace/libraries.scss index a1df227fe..41a3747dd 100644 --- a/frontend/src/app/main/ui/workspace/libraries.scss +++ b/frontend/src/app/main/ui/workspace/libraries.scss @@ -326,16 +326,6 @@ padding: $s-0 $s-16; } -.templates-info { - color: var(--color-accent-primary); -} - -.templates-info-link { - color: var(--color-accent-primary); - text-decoration: underline; - font-weight: $fw400; -} - .sample-libraries-info { display: flex; flex-direction: column; diff --git a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs index 893ac6317..10973c9a5 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/assets.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/assets.cljs @@ -8,7 +8,6 @@ (:require-macros [app.main.style :as stl]) (:require [app.common.data.macros :as dm] - [app.config :as cf] [app.main.data.modal :as modal] [app.main.data.workspace :as dw] [app.main.data.workspace.assets :as dwa] @@ -92,12 +91,6 @@ reverse-sort? (= :desc ordering) num-libs (count (mf/deref refs/libraries)) - show-templates-04-test1? - (and (cf/external-feature-flag "templates-04" "test1") (zero? num-libs)) - - show-templates-04-test2? - (and (cf/external-feature-flag "templates-04" "test2") (zero? num-libs)) - toggle-ordering (mf/use-fn (mf/deps ordering) @@ -166,18 +159,12 @@ [:article {:class (stl/css :assets-bar)} [:div {:class (stl/css :assets-header)} (when-not ^boolean read-only? - (cond - show-templates-04-test1? - [:button {:class (stl/css :libraries-button) - :on-click show-libraries-dialog - :data-testid "libraries"} - (tr "workspace.assets.add-library")] - show-templates-04-test2? + (if (= num-libs 1) [:button {:class (stl/css :add-library-button) :on-click show-libraries-dialog :data-testid "libraries"} (tr "workspace.assets.add-library")] - :else + [:button {:class (stl/css :libraries-button) :on-click show-libraries-dialog :data-testid "libraries"} diff --git a/frontend/translations/en.po b/frontend/translations/en.po index 3bc907e71..c185ea192 100644 --- a/frontend/translations/en.po +++ b/frontend/translations/en.po @@ -4786,10 +4786,6 @@ msgstr "Loading…" msgid "workspace.libraries.more-templates" msgstr "You can look for " -#: src/app/main/ui/workspace/libraries.cljs:391 -msgid "workspace.libraries.more-templates-link" -msgstr "more templates in here" - #: src/app/main/ui/workspace/libraries.cljs:481 msgid "workspace.libraries.no-libraries-need-sync" msgstr "There are no Shared Libraries that need update" @@ -4798,10 +4794,6 @@ msgstr "There are no Shared Libraries that need update" msgid "workspace.libraries.no-matches-for" msgstr "No matches found for “%s“" -#: src/app/main/ui/workspace/libraries.cljs:384 -msgid "workspace.libraries.no-shared-libraries-available" -msgstr "There are no Shared Libraries available" - #: src/app/main/ui/workspace/libraries.cljs:337 msgid "workspace.libraries.search-shared-libraries" msgstr "Search shared libraries" diff --git a/frontend/translations/es.po b/frontend/translations/es.po index 89f668712..9ffd59215 100644 --- a/frontend/translations/es.po +++ b/frontend/translations/es.po @@ -4804,10 +4804,6 @@ msgstr "Cargando…" msgid "workspace.libraries.more-templates" msgstr "Puedes buscar " -#: src/app/main/ui/workspace/libraries.cljs:391 -msgid "workspace.libraries.more-templates-link" -msgstr "más plantillas aquí" - #: src/app/main/ui/workspace/libraries.cljs:481 msgid "workspace.libraries.no-libraries-need-sync" msgstr "No hay bibliotecas que necesiten ser actualizadas" @@ -4816,10 +4812,6 @@ msgstr "No hay bibliotecas que necesiten ser actualizadas" msgid "workspace.libraries.no-matches-for" msgstr "No se encuentra “%s“" -#: src/app/main/ui/workspace/libraries.cljs:384 -msgid "workspace.libraries.no-shared-libraries-available" -msgstr "No hay bibliotecas compartidas disponibles" - #: src/app/main/ui/workspace/libraries.cljs:337 msgid "workspace.libraries.search-shared-libraries" msgstr "Buscar bibliotecas compartidas"