mirror of
https://github.com/penpot/penpot.git
synced 2025-02-12 18:18:24 -05:00
Merge pull request #4682 from penpot/ladybenko-7686-mixed-constraints
Fix constraints dropdown not showing "Mixed"
This commit is contained in:
commit
7bf4305269
8 changed files with 481 additions and 10 deletions
|
@ -11,6 +11,7 @@
|
|||
### :sparkles: New features
|
||||
|
||||
- Fix clickable area of Penptot logo in the viewer [Taiga #7988](https://tree.taiga.io/project/penpot/issue/7988)
|
||||
- Fix constraints dropdown when selecting multiple shapes [Taiga #7686](https://tree.taiga.io/project/penpot/issue/7686)
|
||||
- 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)
|
||||
|
|
|
@ -0,0 +1,363 @@
|
|||
{
|
||||
"~:id": "~u03bff843-920f-81a1-8004-7563acdc8ca1",
|
||||
"~:file-id": "~u03bff843-920f-81a1-8004-756365e1eb6a",
|
||||
"~:created-at": "~m1717592543081",
|
||||
"~: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": [
|
||||
"~ub574c052-1a31-80bb-8004-75636879759b"
|
||||
]
|
||||
}
|
||||
},
|
||||
"~ub574c052-1a31-80bb-8004-75636879759b": {
|
||||
"~#shape": {
|
||||
"~:y": 128,
|
||||
"~: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,
|
||||
"~:grow-type": "~:fixed",
|
||||
"~:hide-in-viewer": false,
|
||||
"~:name": "Board",
|
||||
"~:width": 256,
|
||||
"~:type": "~:frame",
|
||||
"~:points": [
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 128,
|
||||
"~:y": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 384,
|
||||
"~:y": 128
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 384,
|
||||
"~:y": 384
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 128,
|
||||
"~:y": 384
|
||||
}
|
||||
}
|
||||
],
|
||||
"~: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": "~ub574c052-1a31-80bb-8004-75636879759b",
|
||||
"~:parent-id": "~u00000000-0000-0000-0000-000000000000",
|
||||
"~:frame-id": "~u00000000-0000-0000-0000-000000000000",
|
||||
"~:strokes": [],
|
||||
"~:x": 128,
|
||||
"~:proportion": 1,
|
||||
"~:selrect": {
|
||||
"~#rect": {
|
||||
"~:x": 128,
|
||||
"~:y": 128,
|
||||
"~:width": 256,
|
||||
"~:height": 256,
|
||||
"~:x1": 128,
|
||||
"~:y1": 128,
|
||||
"~:x2": 384,
|
||||
"~:y2": 384
|
||||
}
|
||||
},
|
||||
"~:fills": [
|
||||
{
|
||||
"~:fill-color": "#FFFFFF",
|
||||
"~:fill-opacity": 1
|
||||
}
|
||||
],
|
||||
"~:flip-x": null,
|
||||
"~:height": 256,
|
||||
"~:flip-y": null,
|
||||
"~:shapes": [
|
||||
"~ub574c052-1a31-80bb-8004-75636a9b8205",
|
||||
"~ub574c052-1a31-80bb-8004-756392461069"
|
||||
]
|
||||
}
|
||||
},
|
||||
"~ub574c052-1a31-80bb-8004-75636a9b8205": {
|
||||
"~#shape": {
|
||||
"~:y": 136,
|
||||
"~: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": 64,
|
||||
"~:type": "~:rect",
|
||||
"~:points": [
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 136,
|
||||
"~:y": 136
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 200,
|
||||
"~:y": 136
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 200,
|
||||
"~:y": 199.99999999999997
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 136,
|
||||
"~:y": 199.99999999999997
|
||||
}
|
||||
}
|
||||
],
|
||||
"~: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": "~ub574c052-1a31-80bb-8004-75636a9b8205",
|
||||
"~:parent-id": "~ub574c052-1a31-80bb-8004-75636879759b",
|
||||
"~:frame-id": "~ub574c052-1a31-80bb-8004-75636879759b",
|
||||
"~:strokes": [],
|
||||
"~:x": 136,
|
||||
"~:proportion": 1,
|
||||
"~:selrect": {
|
||||
"~#rect": {
|
||||
"~:x": 136,
|
||||
"~:y": 136,
|
||||
"~:width": 64,
|
||||
"~:height": 63.99999999999997,
|
||||
"~:x1": 136,
|
||||
"~:y1": 136,
|
||||
"~:x2": 200,
|
||||
"~:y2": 199.99999999999997
|
||||
}
|
||||
},
|
||||
"~:fills": [
|
||||
{
|
||||
"~:fill-color": "#B1B2B5",
|
||||
"~:fill-opacity": 1
|
||||
}
|
||||
],
|
||||
"~:flip-x": null,
|
||||
"~:ry": 0,
|
||||
"~:height": 63.99999999999997,
|
||||
"~:flip-y": null
|
||||
}
|
||||
},
|
||||
"~ub574c052-1a31-80bb-8004-756392461069": {
|
||||
"~#shape": {
|
||||
"~:y": 136,
|
||||
"~: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": 64,
|
||||
"~:type": "~:circle",
|
||||
"~:points": [
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 256,
|
||||
"~:y": 136
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 320,
|
||||
"~:y": 136
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 320,
|
||||
"~:y": 200
|
||||
}
|
||||
},
|
||||
{
|
||||
"~#point": {
|
||||
"~:x": 256,
|
||||
"~:y": 200
|
||||
}
|
||||
}
|
||||
],
|
||||
"~:proportion-lock": false,
|
||||
"~:transform-inverse": {
|
||||
"~#matrix": {
|
||||
"~:a": 1.0,
|
||||
"~:b": 0.0,
|
||||
"~:c": 0.0,
|
||||
"~:d": 1.0,
|
||||
"~:e": 0.0,
|
||||
"~:f": 0.0
|
||||
}
|
||||
},
|
||||
"~:constraints-v": "~:bottom",
|
||||
"~:constraints-h": "~:right",
|
||||
"~:id": "~ub574c052-1a31-80bb-8004-756392461069",
|
||||
"~:parent-id": "~ub574c052-1a31-80bb-8004-75636879759b",
|
||||
"~:frame-id": "~ub574c052-1a31-80bb-8004-75636879759b",
|
||||
"~:strokes": [],
|
||||
"~:x": 256,
|
||||
"~:proportion": 1,
|
||||
"~:selrect": {
|
||||
"~#rect": {
|
||||
"~:x": 256,
|
||||
"~:y": 136,
|
||||
"~:width": 64,
|
||||
"~:height": 64,
|
||||
"~:x1": 256,
|
||||
"~:y1": 136,
|
||||
"~:x2": 320,
|
||||
"~:y2": 200
|
||||
}
|
||||
},
|
||||
"~:fills": [
|
||||
{
|
||||
"~:fill-color": "#B1B2B5",
|
||||
"~:fill-opacity": 1
|
||||
}
|
||||
],
|
||||
"~:flip-x": null,
|
||||
"~:height": 64,
|
||||
"~:flip-y": null
|
||||
}
|
||||
}
|
||||
},
|
||||
"~:id": "~u03bff843-920f-81a1-8004-756365e1eb6b",
|
||||
"~:name": "Page 1"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
{
|
||||
"~: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 2",
|
||||
"~:revn": 9,
|
||||
"~:modified-at": "~m1717592543083",
|
||||
"~:id": "~u03bff843-920f-81a1-8004-756365e1eb6a",
|
||||
"~:is-shared": false,
|
||||
"~:version": 48,
|
||||
"~:project-id": "~u0515a066-e303-8169-8004-73eb401b5d55",
|
||||
"~:created-at": "~m1717592470408",
|
||||
"~:data": {
|
||||
"~:pages": [
|
||||
"~u03bff843-920f-81a1-8004-756365e1eb6b"
|
||||
],
|
||||
"~:pages-index": {
|
||||
"~u03bff843-920f-81a1-8004-756365e1eb6b": {
|
||||
"~#penpot/pointer": [
|
||||
"~u03bff843-920f-81a1-8004-7563acdc8ca1",
|
||||
{
|
||||
"~:created-at": "~m1717592543090"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"~:id": "~u03bff843-920f-81a1-8004-756365e1eb6a",
|
||||
"~:options": {
|
||||
"~:components-v2": true
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"03bff843-920f-81a1-8004-756365e1eb6a/03bff843-920f-81a1-8004-756365e1eb6b/b574c052-1a31-80bb-8004-75636879759b/frame": "http://localhost:3449/assets/by-id/bdc9e592-f685-4b08-9a44-127ce20efee6"
|
||||
}
|
|
@ -45,12 +45,11 @@ export class WorkspacePage extends BaseWebSocketPage {
|
|||
this.rootShape = page.locator(`[id="shape-00000000-0000-0000-0000-000000000000"]`);
|
||||
this.rectShapeButton = page.getByRole("button", { name: "Rectangle (R)" });
|
||||
this.colorpicker = page.getByTestId("colorpicker");
|
||||
this.layers = page.getByTestId("layers");
|
||||
}
|
||||
|
||||
async goToWorkspace() {
|
||||
await this.page.goto(
|
||||
`/#/workspace/${WorkspacePage.anyProjectId}/${WorkspacePage.anyFileId}?page-id=${WorkspacePage.anyPageId}`,
|
||||
);
|
||||
async goToWorkspace({ fileId = WorkspacePage.anyFileId, pageId = WorkspacePage.anyPageId } = {}) {
|
||||
await this.page.goto(`/#/workspace/${WorkspacePage.anyProjectId}/${fileId}?page-id=${pageId}`);
|
||||
|
||||
this.#ws = await this.waitForNotificationsWebSocket();
|
||||
await this.#ws.mockOpen();
|
||||
|
@ -97,4 +96,14 @@ export class WorkspacePage extends BaseWebSocketPage {
|
|||
await this.viewport.hover({ position: { x: x + width, y: y + height } });
|
||||
await this.page.mouse.up();
|
||||
}
|
||||
|
||||
async clickLeafLayer(name, clickOptions = {}) {
|
||||
const layer = this.layers.getByText(name);
|
||||
await layer.click(clickOptions);
|
||||
}
|
||||
|
||||
async clickToggableLayer(name, clickOptions = {}) {
|
||||
const layer = this.layers.getByTestId("layer-item").filter({ has: this.page.getByText(name) });
|
||||
await layer.getByRole("button").click(clickOptions);
|
||||
}
|
||||
}
|
||||
|
|
46
frontend/playwright/ui/specs/design-tab.spec.js
Normal file
46
frontend/playwright/ui/specs/design-tab.spec.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
import { test, expect } from "@playwright/test";
|
||||
import { WorkspacePage } from "../pages/WorkspacePage";
|
||||
|
||||
test.beforeEach(async ({ page }) => {
|
||||
await WorkspacePage.init(page);
|
||||
});
|
||||
|
||||
const multipleConstraintsFileId = `03bff843-920f-81a1-8004-756365e1eb6a`;
|
||||
const multipleConstraintsPageId = `03bff843-920f-81a1-8004-756365e1eb6b`;
|
||||
|
||||
const setupFileWithMultipeConstraints = async (workspace) => {
|
||||
await workspace.setupEmptyFile();
|
||||
await workspace.mockRPC(/get\-file\?/, "design/get-file-multiple-constraints.json");
|
||||
await workspace.mockRPC(
|
||||
"get-file-object-thumbnails?file-id=*",
|
||||
"design/get-file-object-thumbnails-multiple-constraints.json",
|
||||
);
|
||||
await workspace.mockRPC(
|
||||
"get-file-fragment?file-id=*",
|
||||
"design/get-file-fragment-multiple-constraints.json",
|
||||
);
|
||||
};
|
||||
|
||||
test.describe("Constraints", () => {
|
||||
test("Constraint dropdown shows 'Mixed' when multiple layers are selected with different constraints", 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"] });
|
||||
|
||||
const constraintVDropdown = workspace.page.getByTestId("constraint-v-select");
|
||||
await expect(constraintVDropdown).toContainText("Mixed");
|
||||
const constraintHDropdown = workspace.page.getByTestId("constraint-h-select");
|
||||
await expect(constraintHDropdown).toContainText("Mixed");
|
||||
|
||||
expect(false);
|
||||
});
|
||||
});
|
|
@ -69,7 +69,7 @@
|
|||
highlighted (mf/deref refs/highlighted-shapes)
|
||||
highlighted (hooks/use-equal-memo highlighted)
|
||||
root (get objects uuid/zero)]
|
||||
[:div {:class (stl/css :element-list)}
|
||||
[:div {:class (stl/css :element-list) :data-testid "layer-item"}
|
||||
[:& hooks/sortable-container {}
|
||||
(for [[index id] (reverse (d/enumerate (:shapes root)))]
|
||||
(when-let [obj (get objects id)]
|
||||
|
@ -510,7 +510,7 @@
|
|||
(mf/use-fn
|
||||
#(st/emit! (dw/toggle-focus-mode)))]
|
||||
|
||||
[:div#layers {:class (stl/css :layers)}
|
||||
[:div#layers {:class (stl/css :layers) :data-testid "layers"}
|
||||
(if (d/not-empty? focus)
|
||||
[:div {:class (stl/css :tool-window-bar)}
|
||||
[:button {:class (stl/css :focus-title)
|
||||
|
|
|
@ -207,14 +207,14 @@
|
|||
:on-click on-constraint-button-clicked}
|
||||
[:span {:class (stl/css :resalted-area)}]]]]
|
||||
[:div {:class (stl/css :contraints-selects)}
|
||||
[:div {:class (stl/css :horizontal-select)}
|
||||
[:div {:class (stl/css :horizontal-select) :data-testid "constraint-h-select"}
|
||||
[:& select
|
||||
{:default-value (d/nilv (d/name constraints-h) "scale")
|
||||
{:default-value (if (not= constraints-h :multiple) (d/nilv (d/name constraints-h) "scale") "")
|
||||
:options options-h
|
||||
:on-change on-constraint-h-select-changed}]]
|
||||
[:div {:class (stl/css :vertical-select)}
|
||||
[:div {:class (stl/css :vertical-select) :data-testid "constraint-v-select"}
|
||||
[:& select
|
||||
{:default-value (d/nilv (d/name constraints-v) "scale")
|
||||
{:default-value (if (not= constraints-v :multiple) (d/nilv (d/name constraints-v) "scale") "")
|
||||
:options options-v
|
||||
:on-change on-constraint-v-select-changed}]]
|
||||
(when first-level?
|
||||
|
|
Loading…
Add table
Reference in a new issue