0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-04-05 03:21:26 -05:00

Merge remote-tracking branch 'origin/staging' into develop

This commit is contained in:
Andrey Antukh 2025-02-12 14:37:20 +01:00
commit 654c070976
12 changed files with 205 additions and 63 deletions

View file

@ -77,6 +77,9 @@ is a number of cores)
- Added upload svg with images method [#5489](https://github.com/penpot/penpot/issues/5489)
- Fix problem with root frame parent reference [Taiga #9437](https://tree.taiga.io/project/penpot/issue/9437)
- Fix change flex direction using plugins API [Taiga #9407](https://tree.taiga.io/project/penpot/issue/9407)
- Fix problem opening url when page-id didn't exist [Taiga #10157](https://tree.taiga.io/project/penpot/issue/10157)
- Fix problem with onboarding to a team [Taiga #10143](https://tree.taiga.io/project/penpot/issue/10143)
- Fix problem with grid layout crashing [Taiga #10127](https://tree.taiga.io/project/penpot/issue/10127)
## 2.4.3

View file

@ -212,8 +212,10 @@
(if (= type :column)
[:column :column-span]
[:row :row-span])
from-idx (dec (get cell prop))
to-idx (+ (dec (get cell prop)) (get cell prop-span))
from-idx (-> (dec (get cell prop))
(mth/clamp 0 (dec (count track-list))))
to-idx (-> (+ (dec (get cell prop)) (get cell prop-span))
(mth/clamp 0 (dec (count track-list))))
tracks (subvec track-list from-idx to-idx)]
(some? (->> tracks (d/seek #(= :flex (:type %)))))))
@ -291,8 +293,10 @@
(fn [allocated cell]
(let [shape-id (first (:shapes cell))
from-idx (dec (get cell prop))
to-idx (+ (dec (get cell prop)) (get cell prop-span))
from-idx (-> (dec (get cell prop))
(mth/clamp 0 (dec (count track-list))))
to-idx (-> (+ (dec (get cell prop)) (get cell prop-span))
(mth/clamp 0 (dec (count track-list))))
indexed-tracks (subvec (d/enumerate track-list) from-idx to-idx)
to-allocate (size-to-allocate type parent (get children-map shape-id) cell bounds objects)
@ -597,11 +601,10 @@
row (nth row-tracks (dec (:row grid-cell)) nil)
column-start-p (:start-p column)
row-start-p (:start-p row)
start-p (gpt/add origin
(gpt/add
(gpt/to-vec origin column-start-p)
(gpt/to-vec origin row-start-p)))]
(assoc grid-cell :start-p start-p)))))
row-start-p (:start-p row)]
(when (and (some? column-start-p) (some? row-start-p))
(let [start-p (gpt/add origin
(gpt/add
(gpt/to-vec origin column-start-p)
(gpt/to-vec origin row-start-p)))]
(assoc grid-cell :start-p start-p)))))))

View file

@ -114,61 +114,62 @@
(defn child-position-delta
[parent child child-bounds child-width child-height layout-data cell-data]
(let [cell-bounds (cell-bounds layout-data cell-data)
child-origin (gpo/origin child-bounds)
(if-let [cell-bounds (cell-bounds layout-data cell-data)]
(let [child-origin (gpo/origin child-bounds)
align (:layout-align-items parent)
justify (:layout-justify-items parent)
align-self (:align-self cell-data)
justify-self (:justify-self cell-data)
align (:layout-align-items parent)
justify (:layout-justify-items parent)
align-self (:align-self cell-data)
justify-self (:justify-self cell-data)
align-self (when (and align-self (not= align-self :auto)) align-self)
justify-self (when (and justify-self (not= justify-self :auto)) justify-self)
align-self (when (and align-self (not= align-self :auto)) align-self)
justify-self (when (and justify-self (not= justify-self :auto)) justify-self)
align (or align-self align)
justify (or justify-self justify)
align (or align-self align)
justify (or justify-self justify)
origin-h (gpo/project-point cell-bounds :h child-origin)
origin-v (gpo/project-point cell-bounds :v child-origin)
hv (partial gpo/start-hv cell-bounds)
vv (partial gpo/start-vv cell-bounds)
origin-h (gpo/project-point cell-bounds :h child-origin)
origin-v (gpo/project-point cell-bounds :v child-origin)
hv (partial gpo/start-hv cell-bounds)
vv (partial gpo/start-vv cell-bounds)
[top-m right-m bottom-m left-m] (ctl/child-margins child)
[top-m right-m bottom-m left-m] (ctl/child-margins child)
;; Adjust alignment/justify
[from-h to-h]
(case justify
:end
[(gpt/add origin-h (hv child-width))
(gpt/subtract (nth cell-bounds 1) (hv right-m))]
;; Adjust alignment/justify
[from-h to-h]
(case justify
:end
[(gpt/add origin-h (hv child-width))
(gpt/subtract (nth cell-bounds 1) (hv right-m))]
:center
[(gpt/add origin-h (hv (/ child-width 2)))
(-> (gpo/project-point cell-bounds :h (gpo/center cell-bounds))
(gpt/add (hv (/ left-m 2)))
(gpt/subtract (hv (/ right-m 2))))]
:center
[(gpt/add origin-h (hv (/ child-width 2)))
(-> (gpo/project-point cell-bounds :h (gpo/center cell-bounds))
(gpt/add (hv (/ left-m 2)))
(gpt/subtract (hv (/ right-m 2))))]
[origin-h
(gpt/add (first cell-bounds) (hv left-m))])
[origin-h
(gpt/add (first cell-bounds) (hv left-m))])
[from-v to-v]
(case align
:end
[(gpt/add origin-v (vv child-height))
(gpt/subtract (nth cell-bounds 3) (vv bottom-m))]
[from-v to-v]
(case align
:end
[(gpt/add origin-v (vv child-height))
(gpt/subtract (nth cell-bounds 3) (vv bottom-m))]
:center
[(gpt/add origin-v (vv (/ child-height 2)))
(-> (gpo/project-point cell-bounds :v (gpo/center cell-bounds))
(gpt/add (vv top-m))
(gpt/subtract (vv bottom-m)))]
:center
[(gpt/add origin-v (vv (/ child-height 2)))
(-> (gpo/project-point cell-bounds :v (gpo/center cell-bounds))
(gpt/add (vv top-m))
(gpt/subtract (vv bottom-m)))]
[origin-v
(gpt/add (first cell-bounds) (vv top-m))])]
[origin-v
(gpt/add (first cell-bounds) (vv top-m))])]
(-> (gpt/point)
(gpt/add (gpt/to-vec from-h to-h))
(gpt/add (gpt/to-vec from-v to-v)))))
(-> (gpt/point)
(gpt/add (gpt/to-vec from-h to-h))
(gpt/add (gpt/to-vec from-v to-v))))
(gpt/point 0 0)))
(defn child-modifiers
[parent parent-bounds child child-bounds layout-data cell-data]

View file

@ -0,0 +1 @@
{}

View file

@ -0,0 +1,48 @@
[
{
"~: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
},
"~:name": "Default",
"~:modified-at": "~m1713533116375",
"~:id": "~uc7ce0794-0992-8105-8004-38e630f40f6d",
"~:created-at": "~m1713533116375",
"~: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
},
"~:name": "Second team",
"~:modified-at": "~m1701164272671",
"~:id": "~udd33ff88-f4e5-8033-8003-8096cc07bdf3",
"~:created-at": "~m1701164272671",
"~:is-default": false
}
]

View file

@ -155,6 +155,9 @@ export class DashboardPage extends BaseWebSocketPage {
await this.mockRPC("search-files", "dashboard/search-files.json", {
method: "POST",
});
await this.mockRPC("delete-team", "dashboard/delete-team.json", {
method: "POST",
});
await this.mockRPC("search-files", "dashboard/search-files.json");
await this.mockRPC("get-teams", "logged-in-user/get-teams-complete.json");
}

View file

@ -84,6 +84,33 @@ test("User has context menu options for edit file", async ({ page }) => {
await expect(dashboardPage.page.getByText("delete")).toBeVisible();
});
test("Multiple elements in context", async ({ page }) => {
await DashboardPage.mockRPC(
page,
"get-all-projects",
"dashboard/get-all-projects.json",
);
const dashboardPage = new DashboardPage(page);
await dashboardPage.setupDrafts();
await dashboardPage.goToDrafts();
const button = dashboardPage.page.getByRole("button", { name: /New File 1/ });
await button.click();
const button2 = dashboardPage.page.getByRole("button", {
name: /New File 2/,
});
await button2.click({ modifiers: ["Shift"] });
await button.click({ button: "right" });
await expect(button.getByTestId("duplicate-multi")).toBeVisible();
await expect(button.getByTestId("file-move-multi")).toBeVisible();
await expect(button.getByTestId("file-binary-export-multi")).toBeVisible();
await expect(button.getByTestId("file-delete-multi")).toBeVisible();
});
test("User has create file button", async ({ page }) => {
const dashboardPage = new DashboardPage(page);
await dashboardPage.setupDrafts();
@ -131,3 +158,31 @@ test("Bug 9927, Don't show the banner to invite team members if the user has dis
await expect(page.getByText("Second team")).toBeVisible();
await expect(page.getByText("Team Up")).not.toBeVisible();
});
test("Bug 10141, The team does not disappear from the team list after deletion", async ({
page,
}) => {
const dashboardPage = new DashboardPage(page);
await dashboardPage.setupDashboardFull();
await DashboardPage.mockRPC(
page,
"get-teams",
"logged-in-user/get-teams-complete-owner.json",
);
await dashboardPage.goToDashboard();
await dashboardPage.teamDropdown.click();
await expect(page.getByText("Second Team")).toBeVisible();
await page.getByText("Second Team").click();
await page.getByRole("button", { name: "team-management" }).click();
await page.getByTestId("delete-team").click();
await DashboardPage.mockRPC(
page,
"get-teams",
"logged-in-user/get-teams-default.json",
);
await page.getByRole("button", { name: "Delete team" }).click();
await dashboardPage.teamDropdown.click();
await expect(page.getByText("Second Team")).not.toBeVisible();
});

View file

@ -15,6 +15,17 @@ test("User loads worskpace with empty file", async ({ page }) => {
await expect(workspacePage.pageName).toHaveText("Page 1");
});
test("User opens a file with a bad page id", async ({ page }) => {
const workspacePage = new WorkspacePage(page);
await workspacePage.setupEmptyFile(page);
await workspacePage.goToWorkspace({
pageId: "badpage",
});
await expect(workspacePage.pageName).toHaveText("Page 1");
});
test("User receives presence notifications updates in the workspace", async ({
page,
}) => {

View file

@ -474,6 +474,13 @@
(rx/tap on-success)
(rx/catch on-error))))))
(defn- team-deleted
[id]
(ptk/reify ::team-deleted
ptk/UpdateEvent
(update [_ state]
(update state :teams dissoc id))))
(defn delete-team
[{:keys [id] :as params}]
(ptk/reify ::delete-team
@ -485,7 +492,10 @@
(meta params)]
(->> (rp/cmd! :delete-team {:id id})
(rx/mapcat on-success)
(rx/mapcat (fn [result]
(rx/concat
(rx/of (team-deleted id))
(on-success result))))
(rx/catch on-error))))))
(defn delete-webhook

View file

@ -450,10 +450,12 @@
ptk/WatchEvent
(watch [_ state _]
(let [file-id (:current-file-id state)]
(rx/of (preload-data-uris page-id)
(dwth/watch-state-changes file-id page-id)
(dwl/watch-component-changes))))))
(if (dsh/lookup-page state page-id)
(let [file-id (:current-file-id state)]
(rx/of (preload-data-uris page-id)
(dwth/watch-state-changes file-id page-id)
(dwl/watch-component-changes)))
(rx/of (dcm/go-to-workspace))))))
(defn finalize-page
[page-id]

View file

@ -333,7 +333,7 @@
on-context-menu
(mf/use-fn
(mf/deps is-library-view)
(mf/deps on-menu-click is-library-view)
(fn [event]
(dom/stop-propagation event)
(dom/prevent-default event)

View file

@ -10,6 +10,7 @@
[app.main.data.event :as-alias ev]
[app.main.data.notifications :as ntf]
[app.main.data.profile :as du]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
@ -22,6 +23,7 @@
(let [state* (mf/use-state #(do {:newsletter-updates false
:newsletter-news false}))
state (deref state*)
team (mf/deref refs/team)
on-change
(mf/use-fn
@ -33,7 +35,7 @@
on-next
(mf/use-fn
(mf/deps state)
(mf/deps state team)
(fn []
(when (or (:newsletter-updates state)
(:newsletter-news state))
@ -44,7 +46,10 @@
(assoc :label "newsletter:subscriptions")
(assoc :step 6))]
(st/emit! (ptk/data-event ::ev/event params)
(du/update-profile-props state)))))]
(du/update-profile-props
(cond-> state
(not (:is-default team))
(assoc :onboarding-viewed true)))))))]
[:div {:class (stl/css-case
:modal-overlay true)}