From 058a72b81772518edf4246ca5775e7fb43057e45 Mon Sep 17 00:00:00 2001 From: Alejandro Alonso Date: Mon, 10 Jun 2024 11:02:17 +0200 Subject: [PATCH] :bug: Fix internal error when I set up a stroke for some objects without and with stroke --- CHANGES.md | 3 +- .../design/get-file-multiple-attributes.json | 343 ++++++++++++++++++ ...object-thumbnails-multiple-attributes.json | 1 + .../playwright/ui/specs/design-tab.spec.js | 48 +++ .../workspace/sidebar/options/menus/blur.cljs | 1 + .../workspace/sidebar/options/menus/fill.cljs | 1 + .../sidebar/options/menus/shadow.cljs | 1 + .../sidebar/options/menus/stroke.cljs | 7 +- 8 files changed, 401 insertions(+), 4 deletions(-) create mode 100644 frontend/playwright/data/design/get-file-multiple-attributes.json create mode 100644 frontend/playwright/data/design/get-file-object-thumbnails-multiple-attributes.json diff --git a/CHANGES.md b/CHANGES.md index 2a1895142..e5a698f34 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -36,8 +36,9 @@ - Fix "Attribute overrides in copies are not exported in zip file" [Taiga #8072](https://tree.taiga.io/project/penpot/issue/8072) - Fix group not automatically selected in the Layers panel after creation [Taiga #8078](https://tree.taiga.io/project/penpot/issue/8078) - Fix export boards loses opacity [Taiga #7592](https://tree.taiga.io/project/penpot/issue/7592) -- Fix show in view mode and interactions workflow - Fix change color on imported svg also changes the stroke alignment[Taiga #7673](https://github.com/penpot/penpot/pull/7673) +- Fix show in view mode and interactions workflow [Taiga #4711](https://github.com/penpot/penpot/pull/4711) +- Fix internal error when I set up a stroke for some objects without and with stroke [Taiga #7558](https://tree.taiga.io/project/penpot/issue/7558) ## 2.0.3 diff --git a/frontend/playwright/data/design/get-file-multiple-attributes.json b/frontend/playwright/data/design/get-file-multiple-attributes.json new file mode 100644 index 000000000..c0a67da95 --- /dev/null +++ b/frontend/playwright/data/design/get-file-multiple-attributes.json @@ -0,0 +1,343 @@ +{ + "~:features":{ + "~#set":[ + "layout/grid", + "styles/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":"New File 12", + "~:revn":2, + "~:modified-at":"~m1718012938567", + "~:id":"~u1795a568-0df0-8095-8004-7ba741f56be2", + "~:is-shared":false, + "~:version":48, + "~:project-id":"~u4dc640b0-5cbf-11ec-a7c5-91e9eb4f238d", + "~:created-at":"~m1718012912598", + "~:data":{ + "~:pages":[ + "~u1795a568-0df0-8095-8004-7ba741f56be3" + ], + "~:pages-index":{ + "~u1795a568-0df0-8095-8004-7ba741f56be3":{ + "~: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, + "~:y":0 + } + }, + { + "~#point":{ + "~:x":0.01, + "~:y":0 + } + }, + { + "~#point":{ + "~:x":0.01, + "~:y":0.01 + } + }, + { + "~#point":{ + "~:x":0, + "~:y":0.01 + } + } + ], + "~:proportion-lock":false, + "~:transform-inverse":{ + "~#matrix":{ + "~:a":1.0, + "~:b":0.0, + "~:c":0.0, + "~:d":1.0, + "~:e":0.0, + "~:f":0.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, + "~: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":[ + "~u2ace9ce8-8e01-8086-8004-7ba745d4305a", + "~u2ace9ce8-8e01-8086-8004-7ba748566e02" + ] + } + }, + "~u2ace9ce8-8e01-8086-8004-7ba745d4305a":{ + "~#shape":{ + "~:y":221, + "~:rx":0, + "~:transform":{ + "~#matrix":{ + "~:a":1.0, + "~:b":0.0, + "~:c":0.0, + "~:d":1.0, + "~:e":0.0, + "~:f":0.0 + } + }, + "~:rotation":0, + "~:grow-type":"~:fixed", + "~:hide-in-viewer":false, + "~:name":"Rectangle", + "~:width":105, + "~:type":"~:rect", + "~:points":[ + { + "~#point":{ + "~:x":165, + "~:y":221 + } + }, + { + "~#point":{ + "~:x":270, + "~:y":221 + } + }, + { + "~#point":{ + "~:x":270, + "~:y":316 + } + }, + { + "~#point":{ + "~:x":165, + "~:y":316 + } + } + ], + "~:proportion-lock":false, + "~:transform-inverse":{ + "~#matrix":{ + "~:a":1.0, + "~:b":0.0, + "~:c":0.0, + "~:d":1.0, + "~:e":0.0, + "~:f":0.0 + } + }, + "~:id":"~u2ace9ce8-8e01-8086-8004-7ba745d4305a", + "~:parent-id":"~u00000000-0000-0000-0000-000000000000", + "~:frame-id":"~u00000000-0000-0000-0000-000000000000", + "~:strokes":[ + + ], + "~:x":165, + "~:proportion":1, + "~:selrect":{ + "~#rect":{ + "~:x":165, + "~:y":221, + "~:width":105, + "~:height":95, + "~:x1":165, + "~:y1":221, + "~:x2":270, + "~:y2":316 + } + }, + "~:fills":[ + { + "~:fill-color":"#B1B2B5", + "~:fill-opacity":1 + } + ], + "~:flip-x":null, + "~:ry":0, + "~:height":95, + "~:flip-y":null + } + }, + "~u2ace9ce8-8e01-8086-8004-7ba748566e02":{ + "~#shape":{ + "~:y":228, + "~:transform":{ + "~#matrix":{ + "~:a":1.0, + "~:b":0.0, + "~:c":0.0, + "~:d":1.0, + "~:e":0.0, + "~:f":0.0 + } + }, + "~:rotation":0, + "~:grow-type":"~:fixed", + "~:hide-in-viewer":false, + "~:name":"Ellipse", + "~:width":85, + "~:type":"~:circle", + "~:points":[ + { + "~#point":{ + "~:x":344, + "~:y":228 + } + }, + { + "~#point":{ + "~:x":429, + "~:y":228 + } + }, + { + "~#point":{ + "~:x":429, + "~:y":308 + } + }, + { + "~#point":{ + "~:x":344, + "~:y":308 + } + } + ], + "~:proportion-lock":false, + "~:transform-inverse":{ + "~#matrix":{ + "~:a":1.0, + "~:b":0.0, + "~:c":0.0, + "~:d":1.0, + "~:e":0.0, + "~:f":0.0 + } + }, + "~:blur":{ + "~:id":"~u2ace9ce8-8e01-8086-8004-7ba757cdd271", + "~:type":"~:layer-blur", + "~:value":4, + "~:hidden":false + }, + "~:id":"~u2ace9ce8-8e01-8086-8004-7ba748566e02", + "~:parent-id":"~u00000000-0000-0000-0000-000000000000", + "~:frame-id":"~u00000000-0000-0000-0000-000000000000", + "~:strokes":[ + { + "~:stroke-alignment":"~:inner", + "~:stroke-style":"~:solid", + "~:stroke-color":"#000000", + "~:stroke-opacity":1, + "~:stroke-width":1 + } + ], + "~:x":344, + "~:proportion":1, + "~:shadow":[ + { + "~:color":{ + "~:color":"#000000", + "~:opacity":0.2 + }, + "~:spread":0, + "~:offset-y":4, + "~:style":"~:drop-shadow", + "~:blur":4, + "~:hidden":false, + "~:id":"~u2ace9ce8-8e01-8086-8004-7ba756ddebd5", + "~:offset-x":4 + } + ], + "~:selrect":{ + "~#rect":{ + "~:x":344, + "~:y":228, + "~:width":85, + "~:height":80, + "~:x1":344, + "~:y1":228, + "~:x2":429, + "~:y2":308 + } + }, + "~:fills":[ + { + "~:fill-color":"#1247e7", + "~:fill-opacity":1 + } + ], + "~:flip-x":null, + "~:height":80, + "~:flip-y":null + } + } + }, + "~:id":"~u1795a568-0df0-8095-8004-7ba741f56be3", + "~:name":"Page 1" + } + }, + "~:id":"~u1795a568-0df0-8095-8004-7ba741f56be2", + "~:recent-colors":[ + { + "~:color":"#1247e7", + "~:opacity":1 + } + ] + } +} \ No newline at end of file diff --git a/frontend/playwright/data/design/get-file-object-thumbnails-multiple-attributes.json b/frontend/playwright/data/design/get-file-object-thumbnails-multiple-attributes.json new file mode 100644 index 000000000..0637a088a --- /dev/null +++ b/frontend/playwright/data/design/get-file-object-thumbnails-multiple-attributes.json @@ -0,0 +1 @@ +[] \ No newline at end of file diff --git a/frontend/playwright/ui/specs/design-tab.spec.js b/frontend/playwright/ui/specs/design-tab.spec.js index 0d637bace..0c890c07e 100644 --- a/frontend/playwright/ui/specs/design-tab.spec.js +++ b/frontend/playwright/ui/specs/design-tab.spec.js @@ -7,6 +7,8 @@ test.beforeEach(async ({ page }) => { const multipleConstraintsFileId = `03bff843-920f-81a1-8004-756365e1eb6a`; const multipleConstraintsPageId = `03bff843-920f-81a1-8004-756365e1eb6b`; +const multipleAttributesFileId = `1795a568-0df0-8095-8004-7ba741f56be2`; +const multipleAttributesPageId = `1795a568-0df0-8095-8004-7ba741f56be3`; const setupFileWithMultipeConstraints = async (workspace) => { await workspace.setupEmptyFile(); @@ -21,6 +23,15 @@ const setupFileWithMultipeConstraints = async (workspace) => { ); }; +const setupFileWithMultipeAttributes = async (workspace) => { + await workspace.setupEmptyFile(); + await workspace.mockRPC(/get\-file\?/, "design/get-file-multiple-attributes.json"); + await workspace.mockRPC( + "get-file-object-thumbnails?file-id=*", + "design/get-file-object-thumbnails-multiple-attributes.json", + ); +}; + test.describe("Constraints", () => { test("Constraint dropdown shows 'Mixed' when multiple layers are selected with different constraints", async ({ page, @@ -44,3 +55,40 @@ test.describe("Constraints", () => { expect(false); }); }); + +test.describe("Multiple shapes attributes", () => { + test("User selects multiple shapes with sames fills, strokes, shadows and blur", async ({ page }) => { + const workspace = new WorkspacePage(page); + await setupFileWithMultipeConstraints(workspace); + await workspace.goToWorkspace({ + fileId: multipleConstraintsFileId, + pageId: multipleConstraintsPageId, + }); + + await workspace.clickToggableLayer("Board"); + await workspace.clickLeafLayer("Ellipse"); + await workspace.clickLeafLayer("Rectangle", { modifiers: ["Shift"] }); + + await expect(workspace.page.getByTestId("add-fill")).toBeVisible(); + await expect(workspace.page.getByTestId("add-stroke")).toBeVisible(); + await expect(workspace.page.getByTestId("add-shadow")).toBeVisible(); + await expect(workspace.page.getByTestId("add-blur")).toBeVisible(); + }); + + test("User selects multiple shapes with different fills, strokes, shadows and blur", async ({ page }) => { + const workspace = new WorkspacePage(page); + await setupFileWithMultipeAttributes(workspace); + await workspace.goToWorkspace({ + fileId: multipleAttributesFileId, + pageId: multipleAttributesPageId, + }); + + await workspace.clickLeafLayer("Ellipse"); + await workspace.clickLeafLayer("Rectangle", { modifiers: ["Shift"] }); + + await expect(workspace.page.getByTestId("add-fill")).toBeHidden(); + await expect(workspace.page.getByTestId("add-stroke")).toBeHidden(); + await expect(workspace.page.getByTestId("add-shadow")).toBeHidden(); + await expect(workspace.page.getByTestId("add-blur")).toBeHidden(); + }); +}); diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs index cd1573982..b943680e8 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/blur.cljs @@ -87,6 +87,7 @@ :class (stl/css-case :title-spacing-blur (not has-value?))} (when-not has-value? [:button {:class (stl/css :add-blur) + :data-testid "add-blur" :on-click handle-add} i/add])]] (when (and open? has-value?) [:div {:class (stl/css :element-set-content)} diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs index 7dfc6f075..3d8574ef1 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/fill.cljs @@ -146,6 +146,7 @@ (when (and (not disable-remove?) (not (= :multiple fills))) [:button {:class (stl/css :add-fill) + :data-testid "add-fill" :on-click on-add} i/add])]] (when open? diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/shadow.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/shadow.cljs index ab65f806a..db3b28f85 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/shadow.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/shadow.cljs @@ -298,6 +298,7 @@ (when-not (= :multiple shadows) [:button {:class (stl/css :add-shadow) + :data-testid "add-shadow" :on-click on-add-shadow} i/add])]] (when open? diff --git a/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs b/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs index 3539f693f..9f7969f2c 100644 --- a/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs +++ b/frontend/src/app/main/ui/workspace/sidebar/options/menus/stroke.cljs @@ -169,9 +169,10 @@ :on-collapsed toggle-content :title label :class (stl/css-case :title-spacing-stroke (not has-strokes?))} - - [:button {:class (stl/css :add-stroke) - :on-click on-add-stroke} i/add]]] + (when (not (= :multiple strokes)) + [:button {:class (stl/css :add-stroke) + :data-testid "add-stroke" + :on-click on-add-stroke} i/add])]] (when open? [:div {:class (stl/css-case :element-content true :empty-content (not has-strokes?))}