mirror of
https://github.com/penpot/penpot.git
synced 2025-07-19 03:27:23 +02:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
c2ba7cdbc7
11 changed files with 2057 additions and 42 deletions
|
@ -63,6 +63,8 @@
|
||||||
- Fix problem with caps and inner shadows [Github #4517](https://github.com/penpot/penpot/issues/4517)
|
- Fix problem with caps and inner shadows [Github #4517](https://github.com/penpot/penpot/issues/4517)
|
||||||
- Fix problem with horizontal/vertical lines and shadows [Github #4516](https://github.com/penpot/penpot/issues/4516)
|
- Fix problem with horizontal/vertical lines and shadows [Github #4516](https://github.com/penpot/penpot/issues/4516)
|
||||||
- Fix problem with layers overflowing panel [Taiga #9021](https://tree.taiga.io/project/penpot/issue/9021)
|
- Fix problem with layers overflowing panel [Taiga #9021](https://tree.taiga.io/project/penpot/issue/9021)
|
||||||
|
- Fix in workspace you can manage rulers on view mode [Taiga #8966](https://tree.taiga.io/project/penpot/issue/8966)
|
||||||
|
- Fix problem with swap components in grid layout [Taiga #9066](https://tree.taiga.io/project/penpot/issue/9066)
|
||||||
|
|
||||||
## 2.2.1
|
## 2.2.1
|
||||||
|
|
||||||
|
|
|
@ -232,6 +232,7 @@
|
||||||
[(:parent-id first-shape)]
|
[(:parent-id first-shape)]
|
||||||
(fn [shape objects]
|
(fn [shape objects]
|
||||||
(-> shape
|
(-> shape
|
||||||
|
(ctl/assign-cells objects)
|
||||||
(ctl/push-into-cell [(:id first-shape)] row column)
|
(ctl/push-into-cell [(:id first-shape)] row column)
|
||||||
(ctl/assign-cells objects)))
|
(ctl/assign-cells objects)))
|
||||||
{:with-objects? true})
|
{:with-objects? true})
|
||||||
|
|
57
frontend/playwright/data/workspace/get-file-9066.json
Normal file
57
frontend/playwright/data/workspace/get-file-9066.json
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
{
|
||||||
|
"~: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
|
||||||
|
},
|
||||||
|
"~:has-media-trimmed": false,
|
||||||
|
"~:comment-thread-seqn": 0,
|
||||||
|
"~:name": "New File 10",
|
||||||
|
"~:revn": 10,
|
||||||
|
"~:modified-at": "~m1729604566305",
|
||||||
|
"~:id": "~ue179d9df-de35-80bf-8005-283bbd5516b0",
|
||||||
|
"~:is-shared": false,
|
||||||
|
"~:version": 55,
|
||||||
|
"~:project-id": "~u3ffbd505-2f26-800f-8004-f34da98bdad8",
|
||||||
|
"~:created-at": "~m1729594560852",
|
||||||
|
"~:data": {
|
||||||
|
"~:pages": [
|
||||||
|
"~ue179d9df-de35-80bf-8005-283bbd5516b1"
|
||||||
|
],
|
||||||
|
"~:pages-index": {
|
||||||
|
"~ue179d9df-de35-80bf-8005-283bbd5516b1": {
|
||||||
|
"~#penpot/pointer": [
|
||||||
|
"~ue179d9df-de35-80bf-8005-2861e849785e",
|
||||||
|
{
|
||||||
|
"~:created-at": "~m1729604566310"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"~:id": "~ue179d9df-de35-80bf-8005-283bbd5516b0",
|
||||||
|
"~:options": {
|
||||||
|
"~:components-v2": true
|
||||||
|
},
|
||||||
|
"~:components": {
|
||||||
|
"~#penpot/pointer": [
|
||||||
|
"~ue179d9df-de35-80bf-8005-2861e849b3f7",
|
||||||
|
{
|
||||||
|
"~:created-at": "~m1729604566311"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,39 @@
|
||||||
|
{
|
||||||
|
"~:id": "~ue179d9df-de35-80bf-8005-2861e849b3f7",
|
||||||
|
"~:file-id": "~ue179d9df-de35-80bf-8005-283bbd5516b0",
|
||||||
|
"~:created-at": "~m1729604566293",
|
||||||
|
"~:data": {
|
||||||
|
"~u6ad3e6b9-c5a0-80cf-8005-283bbe38dba8": {
|
||||||
|
"~:id": "~u6ad3e6b9-c5a0-80cf-8005-283bbe38dba8",
|
||||||
|
"~:name": "F",
|
||||||
|
"~:path": "",
|
||||||
|
"~:modified-at": "~m1729604566311",
|
||||||
|
"~:main-instance-id": "~u6ad3e6b9-c5a0-80cf-8005-283bbe378bcc",
|
||||||
|
"~:main-instance-page": "~ue179d9df-de35-80bf-8005-283bbd5516b1"
|
||||||
|
},
|
||||||
|
"~u6ad3e6b9-c5a0-80cf-8005-283bbe39bb51": {
|
||||||
|
"~:id": "~u6ad3e6b9-c5a0-80cf-8005-283bbe39bb51",
|
||||||
|
"~:name": "E",
|
||||||
|
"~:path": "",
|
||||||
|
"~:modified-at": "~m1729604566311",
|
||||||
|
"~:main-instance-id": "~u6ad3e6b9-c5a0-80cf-8005-283bbe378bcd",
|
||||||
|
"~:main-instance-page": "~ue179d9df-de35-80bf-8005-283bbd5516b1"
|
||||||
|
},
|
||||||
|
"~u6ad3e6b9-c5a0-80cf-8005-283bbe3a9014": {
|
||||||
|
"~:id": "~u6ad3e6b9-c5a0-80cf-8005-283bbe3a9014",
|
||||||
|
"~:name": "C",
|
||||||
|
"~:path": "",
|
||||||
|
"~:modified-at": "~m1729604566311",
|
||||||
|
"~:main-instance-id": "~u6ad3e6b9-c5a0-80cf-8005-283bbe378bcf",
|
||||||
|
"~:main-instance-page": "~ue179d9df-de35-80bf-8005-283bbd5516b1"
|
||||||
|
},
|
||||||
|
"~u6ad3e6b9-c5a0-80cf-8005-283bbe3b1793": {
|
||||||
|
"~:id": "~u6ad3e6b9-c5a0-80cf-8005-283bbe3b1793",
|
||||||
|
"~:name": "B",
|
||||||
|
"~:path": "",
|
||||||
|
"~:modified-at": "~m1729604566311",
|
||||||
|
"~:main-instance-id": "~u6ad3e6b9-c5a0-80cf-8005-283bbe378bd0",
|
||||||
|
"~:main-instance-page": "~ue179d9df-de35-80bf-8005-283bbd5516b1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
1864
frontend/playwright/data/workspace/get-file-fragment-9066-2.json
Normal file
1864
frontend/playwright/data/workspace/get-file-fragment-9066-2.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -174,13 +174,13 @@ export class WorkspacePage extends BaseWebSocketPage {
|
||||||
}
|
}
|
||||||
|
|
||||||
async clickLeafLayer(name, clickOptions = {}) {
|
async clickLeafLayer(name, clickOptions = {}) {
|
||||||
const layer = this.layers.getByText(name);
|
const layer = this.layers.getByText(name).first();
|
||||||
await layer.click(clickOptions);
|
await layer.click(clickOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
async clickToggableLayer(name, clickOptions = {}) {
|
async clickToggableLayer(name, clickOptions = {}) {
|
||||||
const layer = this.layers
|
const layer = this.layers
|
||||||
.getByTestId("layer-item")
|
.getByTestId("layer-row")
|
||||||
.filter({ has: this.page.getByText(name) });
|
.filter({ has: this.page.getByText(name) });
|
||||||
await layer.getByRole("button").click(clickOptions);
|
await layer.getByRole("button").click(clickOptions);
|
||||||
}
|
}
|
||||||
|
|
|
@ -189,3 +189,39 @@ test("Bug 8784 - Use keyboard arrow to move inside a text input does not change
|
||||||
|
|
||||||
await expect(workspacePage.pageName).toHaveText("Page 1");
|
await expect(workspacePage.pageName).toHaveText("Page 1");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("Bug 9066 - Problem with grid layout", async ({ page }) => {
|
||||||
|
const workspacePage = new WorkspacePage(page);
|
||||||
|
await workspacePage.setupEmptyFile(page);
|
||||||
|
await workspacePage.mockRPC(/get\-file\?/, "workspace/get-file-9066.json");
|
||||||
|
await workspacePage.mockRPC(
|
||||||
|
"get-file-fragment?file-id=*&fragment-id=e179d9df-de35-80bf-8005-2861e849b3f7",
|
||||||
|
"workspace/get-file-fragment-9066-1.json",
|
||||||
|
);
|
||||||
|
await workspacePage.mockRPC(
|
||||||
|
"get-file-fragment?file-id=*&fragment-id=e179d9df-de35-80bf-8005-2861e849785e",
|
||||||
|
"workspace/get-file-fragment-9066-2.json",
|
||||||
|
);
|
||||||
|
|
||||||
|
await workspacePage.mockRPC(
|
||||||
|
"update-file?id=*",
|
||||||
|
"workspace/update-file-create-rect.json",
|
||||||
|
);
|
||||||
|
|
||||||
|
await workspacePage.goToWorkspace({
|
||||||
|
fileId: "e179d9df-de35-80bf-8005-283bbd5516b0",
|
||||||
|
pageId: "e179d9df-de35-80bf-8005-283bbd5516b1",
|
||||||
|
});
|
||||||
|
|
||||||
|
await workspacePage.clickToggableLayer("Board");
|
||||||
|
await workspacePage.clickToggableLayer("Group");
|
||||||
|
await page.getByText("A", { exact: true }).click();
|
||||||
|
|
||||||
|
await workspacePage.rightSidebar.getByTestId("swap-component-btn").click();
|
||||||
|
|
||||||
|
await page.getByTitle("C", { exact: true }).click();
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
page.getByTestId("children-6ad3e6b9-c5a0-80cf-8005-283bbe378bcb"),
|
||||||
|
).toHaveText(["CBCDEF"]);
|
||||||
|
});
|
||||||
|
|
|
@ -86,7 +86,8 @@
|
||||||
(when (and (:shapes item) expanded?)
|
(when (and (:shapes item) expanded?)
|
||||||
[:div {:class (stl/css-case
|
[:div {:class (stl/css-case
|
||||||
:element-children true
|
:element-children true
|
||||||
:parent-selected selected?)}
|
:parent-selected selected?)
|
||||||
|
:data-testid (dm/str "children-" id)}
|
||||||
(for [[index id] (reverse (d/enumerate (:shapes item)))]
|
(for [[index id] (reverse (d/enumerate (:shapes item)))]
|
||||||
(when-let [item (get objects id)]
|
(when-let [item (get objects id)]
|
||||||
[:& layer-item
|
[:& layer-item
|
||||||
|
|
|
@ -386,7 +386,7 @@
|
||||||
:element-children true
|
:element-children true
|
||||||
:parent-selected selected?
|
:parent-selected selected?
|
||||||
:sticky-children parent-board?)
|
:sticky-children parent-board?)
|
||||||
:data-id (when ^boolean parent-board? id)}
|
:data-testid (dm/str "children-" id)}
|
||||||
(for [[index id] (reverse (d/enumerate (:shapes item)))]
|
(for [[index id] (reverse (d/enumerate (:shapes item)))]
|
||||||
(when-let [item (get objects id)]
|
(when-let [item (get objects id)]
|
||||||
[:& layer-item
|
[:& layer-item
|
||||||
|
|
|
@ -617,6 +617,7 @@
|
||||||
[:button {:class (stl/css-case :component-name-wrapper true
|
[:button {:class (stl/css-case :component-name-wrapper true
|
||||||
:with-main (and can-swap? (not multi))
|
:with-main (and can-swap? (not multi))
|
||||||
:swappeable (and can-swap? (not swap-opened?)))
|
:swappeable (and can-swap? (not swap-opened?)))
|
||||||
|
:data-testid "swap-component-btn"
|
||||||
:on-click open-component-panel}
|
:on-click open-component-panel}
|
||||||
|
|
||||||
[:span {:class (stl/css :component-icon)}
|
[:span {:class (stl/css :component-icon)}
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
[app.main.refs :as refs]
|
[app.main.refs :as refs]
|
||||||
[app.main.store :as st]
|
[app.main.store :as st]
|
||||||
[app.main.streams :as ms]
|
[app.main.streams :as ms]
|
||||||
|
[app.main.ui.context :as ctx]
|
||||||
[app.main.ui.css-cursors :as cur]
|
[app.main.ui.css-cursors :as cur]
|
||||||
[app.main.ui.formats :as fmt]
|
[app.main.ui.formats :as fmt]
|
||||||
[app.main.ui.workspace.viewport.rulers :as rulers]
|
[app.main.ui.workspace.viewport.rulers :as rulers]
|
||||||
|
@ -56,50 +57,61 @@
|
||||||
|
|
||||||
snap-pixel? (mf/deref refs/snap-pixel?)
|
snap-pixel? (mf/deref refs/snap-pixel?)
|
||||||
|
|
||||||
|
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||||
|
|
||||||
on-pointer-enter
|
on-pointer-enter
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
|
(mf/deps workspace-read-only?)
|
||||||
(fn []
|
(fn []
|
||||||
|
(when-not workspace-read-only?
|
||||||
(st/emit! (dw/set-hover-guide id true))
|
(st/emit! (dw/set-hover-guide id true))
|
||||||
(swap! state assoc :hover true)))
|
(swap! state assoc :hover true))))
|
||||||
|
|
||||||
on-pointer-leave
|
on-pointer-leave
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
|
(mf/deps workspace-read-only?)
|
||||||
(fn []
|
(fn []
|
||||||
|
(when-not workspace-read-only?
|
||||||
(st/emit! (dw/set-hover-guide id false))
|
(st/emit! (dw/set-hover-guide id false))
|
||||||
(swap! state assoc :hover false)))
|
(swap! state assoc :hover false))))
|
||||||
|
|
||||||
on-pointer-down
|
on-pointer-down
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
|
(mf/deps workspace-read-only?)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
|
(when-not workspace-read-only?
|
||||||
(when (= 0 (.-button event))
|
(when (= 0 (.-button event))
|
||||||
(dom/capture-pointer event)
|
(dom/capture-pointer event)
|
||||||
(mf/set-ref-val! dragging-ref true)
|
(mf/set-ref-val! dragging-ref true)
|
||||||
(mf/set-ref-val! start-ref (dom/get-client-position event))
|
(mf/set-ref-val! start-ref (dom/get-client-position event))
|
||||||
(mf/set-ref-val! start-pos-ref (get @ms/mouse-position axis)))))
|
(mf/set-ref-val! start-pos-ref (get @ms/mouse-position axis))))))
|
||||||
|
|
||||||
on-pointer-up
|
on-pointer-up
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(mf/deps (select-keys @state [:new-position :new-frame-id]) on-guide-change)
|
(mf/deps (select-keys @state [:new-position :new-frame-id]) on-guide-change workspace-read-only?)
|
||||||
(fn []
|
(fn []
|
||||||
|
(when-not workspace-read-only?
|
||||||
(when (some? on-guide-change)
|
(when (some? on-guide-change)
|
||||||
(when (some? (:new-position @state))
|
(when (some? (:new-position @state))
|
||||||
(on-guide-change {:position (:new-position @state)
|
(on-guide-change {:position (:new-position @state)
|
||||||
:frame-id (:new-frame-id @state)})))))
|
:frame-id (:new-frame-id @state)}))))))
|
||||||
|
|
||||||
on-lost-pointer-capture
|
on-lost-pointer-capture
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
|
(mf/deps workspace-read-only?)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
|
(when-not workspace-read-only?
|
||||||
(dom/release-pointer event)
|
(dom/release-pointer event)
|
||||||
(mf/set-ref-val! dragging-ref false)
|
(mf/set-ref-val! dragging-ref false)
|
||||||
(mf/set-ref-val! start-ref nil)
|
(mf/set-ref-val! start-ref nil)
|
||||||
(mf/set-ref-val! start-pos-ref nil)
|
(mf/set-ref-val! start-pos-ref nil)
|
||||||
(swap! state assoc :new-position nil)))
|
(swap! state assoc :new-position nil))))
|
||||||
|
|
||||||
on-pointer-move
|
on-pointer-move
|
||||||
(mf/use-callback
|
(mf/use-callback
|
||||||
(mf/deps position zoom snap-pixel?)
|
(mf/deps position zoom snap-pixel? workspace-read-only?)
|
||||||
(fn [event]
|
(fn [event]
|
||||||
|
(when-not workspace-read-only?
|
||||||
(when-let [_ (mf/ref-val dragging-ref)]
|
(when-let [_ (mf/ref-val dragging-ref)]
|
||||||
(let [start-pt (mf/ref-val start-ref)
|
(let [start-pt (mf/ref-val start-ref)
|
||||||
start-pos (mf/ref-val start-pos-ref)
|
start-pos (mf/ref-val start-pos-ref)
|
||||||
|
@ -116,7 +128,7 @@
|
||||||
new-frame-id (:id (get-hover-frame))]
|
new-frame-id (:id (get-hover-frame))]
|
||||||
(swap! state assoc
|
(swap! state assoc
|
||||||
:new-position new-position
|
:new-position new-position
|
||||||
:new-frame-id new-frame-id)))))]
|
:new-frame-id new-frame-id))))))]
|
||||||
{:on-pointer-enter on-pointer-enter
|
{:on-pointer-enter on-pointer-enter
|
||||||
:on-pointer-leave on-pointer-leave
|
:on-pointer-leave on-pointer-leave
|
||||||
:on-pointer-down on-pointer-down
|
:on-pointer-down on-pointer-down
|
||||||
|
@ -407,7 +419,8 @@
|
||||||
on-pointer-move
|
on-pointer-move
|
||||||
state
|
state
|
||||||
frame]}
|
frame]}
|
||||||
(use-guide on-guide-change get-hover-frame zoom {:axis axis})]
|
(use-guide on-guide-change get-hover-frame zoom {:axis axis})
|
||||||
|
workspace-read-only? (mf/use-ctx ctx/workspace-read-only?)]
|
||||||
|
|
||||||
[:g.new-guides
|
[:g.new-guides
|
||||||
(when-not disabled-guides
|
(when-not disabled-guides
|
||||||
|
@ -422,7 +435,8 @@
|
||||||
:on-pointer-up on-pointer-up
|
:on-pointer-up on-pointer-up
|
||||||
:on-lost-pointer-capture on-lost-pointer-capture
|
:on-lost-pointer-capture on-lost-pointer-capture
|
||||||
:on-pointer-move on-pointer-move
|
:on-pointer-move on-pointer-move
|
||||||
:class (if (= axis :x) (cur/get-dynamic "resize-ew" 0) (cur/get-dynamic "resize-ns" 0))
|
:class (when-not workspace-read-only?
|
||||||
|
(if (= axis :x) (cur/get-dynamic "resize-ew" 0) (cur/get-dynamic "resize-ns" 0)))
|
||||||
:style {:fill "none"
|
:style {:fill "none"
|
||||||
:pointer-events "fill"}}]))
|
:pointer-events "fill"}}]))
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue