diff --git a/CHANGES.md b/CHANGES.md index 8375a6517..eb5fa43d1 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -10,6 +10,7 @@ ### :sparkles: New features +- Fix clickable area of Penptot logo in the viewer [Taiga #7988](https://tree.taiga.io/project/penpot/issue/7988) - Improve auth process [Taiga #7094](https://tree.taiga.io/project/penpot/us/7094) - Add locking degrees increment (hold shift) on path edition [Taiga #7761](https://tree.taiga.io/project/penpot/issue/7761) - Persistence & Concurrent Edition Enhancements [Taiga #5657](https://tree.taiga.io/project/penpot/us/5657) diff --git a/frontend/playwright/data/viewer/get-file-fragment-empty-file.json b/frontend/playwright/data/viewer/get-file-fragment-empty-file.json new file mode 100644 index 000000000..544c559f7 --- /dev/null +++ b/frontend/playwright/data/viewer/get-file-fragment-empty-file.json @@ -0,0 +1,97 @@ +{ + "~:id": "~u0515a066-e303-8169-8004-73eb58e899c2", + "~:file-id": "~uc7ce0794-0992-8105-8004-38f280443849", + "~:created-at": "~m1717493890966", + "~:content": { + "~: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": [] + } + } + }, + "~:id": "~uc7ce0794-0992-8105-8004-38f28044384a", + "~:name": "Page 1" + } +} \ No newline at end of file diff --git a/frontend/playwright/data/viewer/get-view-only-bundle-empty-file.json b/frontend/playwright/data/viewer/get-view-only-bundle-empty-file.json new file mode 100644 index 000000000..ef001224a --- /dev/null +++ b/frontend/playwright/data/viewer/get-view-only-bundle-empty-file.json @@ -0,0 +1,86 @@ +{ + "~:users": [ + { + "~:id": "~uc7ce0794-0992-8105-8004-38e630f29a9b", + "~:email": "leia@example.com", + "~:name": "Princesa Leia", + "~:fullname": "Princesa Leia", + "~:is-active": true + } + ], + "~:fonts": [], + "~:project": { + "~:id": "~uc7ce0794-0992-8105-8004-38e630f7920b", + "~:name": "Drafts", + "~:team-id": "~uc7ce0794-0992-8105-8004-38e630f40f6d" + }, + "~:share-links": [], + "~:libraries": [], + "~:file": { + "~:features": { + "~#set": [ + "layout/grid", + "styles/v2", + "fdata/pointer-map", + "fdata/objects-map", + "components/v2", + "fdata/shape-data-type" + ] + }, + "~:has-media-trimmed": false, + "~:comment-thread-seqn": 0, + "~:name": "New File 1", + "~:revn": 0, + "~:modified-at": "~m1717493891000", + "~:id": "~uc7ce0794-0992-8105-8004-38f280443849", + "~:is-shared": false, + "~:version": 48, + "~:project-id": "~uc7ce0794-0992-8105-8004-38e630f7920b", + "~:created-at": "~m1717493891000", + "~:data": { + "~:id": "~uc7ce0794-0992-8105-8004-38e630f7920b", + "~:options": { + "~:components-v2": true + }, + "~:pages": [ + "~uc7ce0794-0992-8105-8004-38f28044384a" + ], + "~:pages-index": { + "~uc7ce0794-0992-8105-8004-38f28044384a": { + "~#penpot/pointer": [ + "~u0515a066-e303-8169-8004-73eb58e899c2", + { + "~:created-at": "~m1717493890978" + } + ] + } + } + } + }, + "~:team": { + "~:id": "~uc7ce0794-0992-8105-8004-38e630f40f6d", + "~:created-at": "~m1717493865581", + "~:modified-at": "~m1717493865581", + "~:name": "Default", + "~:is-default": true, + "~:features": { + "~#set": [ + "layout/grid", + "styles/v2", + "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, + "~:in-team": true + } +} \ No newline at end of file diff --git a/frontend/playwright/ui/pages/ViewerPage.js b/frontend/playwright/ui/pages/ViewerPage.js new file mode 100644 index 000000000..cd328eb65 --- /dev/null +++ b/frontend/playwright/ui/pages/ViewerPage.js @@ -0,0 +1,48 @@ +import { BaseWebSocketPage } from "./BaseWebSocketPage"; + +export class ViewerPage extends BaseWebSocketPage { + static anyFileId = "c7ce0794-0992-8105-8004-38f280443849"; + static anyPageId = "c7ce0794-0992-8105-8004-38f28044384a"; + + /** + * This should be called on `test.beforeEach`. + * + * @param {Page} page + * @returns + */ + static async init(page) { + await BaseWebSocketPage.initWebSockets(page); + } + + async setupLoggedInUser() { + await this.mockRPC("get-profile", "logged-in-user/get-profile-logged-in.json"); + } + + async setupEmptyFile() { + await this.mockRPC(/get\-view\-only\-bundle\?/, "viewer/get-view-only-bundle-empty-file.json"); + await this.mockRPC("get-comment-threads?file-id=*", "workspace/get-comment-threads-empty.json"); + await this.mockRPC( + "get-file-fragment?file-id=*&fragment-id=*", + "viewer/get-file-fragment-empty-file.json", + ); + } + + #ws = null; + + constructor(page) { + super(page); + } + + async goToViewer() { + await this.page.goto( + `/#/view/${ViewerPage.anyFileId}?page-id=${ViewerPage.anyPageId}§ion=interactions&index=0`, + ); + + this.#ws = await this.waitForNotificationsWebSocket(); + await this.#ws.mockOpen(); + } + + async cleanUp() { + await this.#ws.mockClose(); + } +} diff --git a/frontend/playwright/ui/specs/viewer-header.spec.js b/frontend/playwright/ui/specs/viewer-header.spec.js new file mode 100644 index 000000000..01cfb8634 --- /dev/null +++ b/frontend/playwright/ui/specs/viewer-header.spec.js @@ -0,0 +1,23 @@ +import { test, expect } from "@playwright/test"; +import { ViewerPage } from "../pages/ViewerPage"; + +test.beforeEach(async ({ page }) => { + await ViewerPage.init(page); +}); + +test("Clips link area of the logo", async ({ page }) => { + const viewerPage = new ViewerPage(page); + await viewerPage.setupLoggedInUser(); + await viewerPage.setupEmptyFile(); + + await viewerPage.goToViewer(); + + const viewerUrl = page.url(); + + const logoLink = viewerPage.page.getByTestId("penpot-logo-link"); + await expect(logoLink).toBeVisible(); + + const { x, y } = await logoLink.boundingBox(); + await viewerPage.page.mouse.click(x, y + 100); + await expect(page.url()).toBe(viewerUrl); +}); diff --git a/frontend/src/app/main/ui/viewer/header.cljs b/frontend/src/app/main/ui/viewer/header.cljs index abf81479f..03dd06548 100644 --- a/frontend/src/app/main/ui/viewer/header.cljs +++ b/frontend/src/app/main/ui/viewer/header.cljs @@ -256,6 +256,10 @@ [:span {:class (stl/css :frame-name)} frame-name] [:span {:class (stl/css :icon)} i/arrow]]]])) +(def ^:private penpot-logo-icon + (i/icon-xref :penpot-logo-icon (stl/css :logo-icon))) + + (mf/defc header [{:keys [project file page frame zoom section permissions index interactions-mode shown-thumbnails]}] (let [go-to-dashboard @@ -303,10 +307,10 @@ ;; If the user doesn't have permission we disable the link [:a {:class (stl/css :home-link) :on-click go-to-dashboard + :data-testid "penpot-logo-link" :style {:cursor (when-not (:in-team permissions) "auto") :pointer-events (when-not (:in-team permissions) "none")}} - [:span {:class (stl/css :logo-icon)} - i/logo-icon]] + penpot-logo-icon] [:& header-sitemap {:project project :file file diff --git a/frontend/src/app/main/ui/viewer/header.scss b/frontend/src/app/main/ui/viewer/header.scss index c131e07b4..1a338aac0 100644 --- a/frontend/src/app/main/ui/viewer/header.scss +++ b/frontend/src/app/main/ui/viewer/header.scss @@ -34,16 +34,14 @@ .home-link { padding: 0; + display: grid; + place-content: center; } .logo-icon { - @include flexCenter; - width: $s-32; - height: $s-32; - svg { - width: $s-28; - fill: var(--icon-foreground-hover); - } + width: $s-28; + height: $s-28; + fill: var(--icon-foreground-hover); } .sitemap-zone {