0
Fork 0
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:
Alejandro 2024-06-07 07:44:04 +02:00 committed by GitHub
commit 7bf4305269
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 481 additions and 10 deletions

View file

@ -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)

View file

@ -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"
}
}

View file

@ -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
}
}
}

View file

@ -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"
}

View file

@ -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);
}
}

View 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);
});
});

View file

@ -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)

View file

@ -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?