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-13 21:04:52 +01:00
commit 3fd429c72a
30 changed files with 420 additions and 174 deletions

View file

@ -384,8 +384,10 @@
f.revn,
f.vern,
f.is_shared,
ft.media_id AS thumbnail_id
ft.media_id AS thumbnail_id,
p.team_id
from file as f
inner join project as p on (p.id = f.project_id)
left join file_thumbnail as ft on (ft.file_id = f.id
and ft.revn = f.revn
and ft.deleted_at is null)
@ -539,7 +541,8 @@
f.modified_at,
f.name,
f.is_shared,
ft.media_id
ft.media_id,
p.team_id
from file as f
inner join project as p on (p.id = f.project_id)
left join file_thumbnail as ft on (ft.file_id = f.id and ft.revn = f.revn and ft.deleted_at is null)
@ -686,7 +689,8 @@
f.name,
f.is_shared,
ft.media_id AS thumbnail_id,
row_number() over w as row_num
row_number() over w as row_num,
p.team_id
from file as f
inner join project as p on (p.id = f.project_id)
left join file_thumbnail as ft on (ft.file_id = f.id

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.7 KiB

View file

@ -51,13 +51,24 @@ title: 06· Styling
<ol>
<li><strong>Eyedropper</strong> - Allows you to pick any color of the objects at the viewport.</li>
<li><strong>Color profiles</strong> - Select between RGB, the Harmony Wheel or HSV.</li>
<li><strong>Color type</strong> - Solid, linear gradient, radial gradient or image.</li>
<li><strong>Color type</strong> - Solid, gradient, or image.</li>
<li><strong>Sliders</strong> - Easily manage settings like brightness, saturation or opacity.</li>
<li><strong>Values</strong> - Set precise color values of red(R), green(G), blue(B) and transparency(A).</li>
<li><strong>Libraries</strong> - Switch between recent colors and libraries.</li>
<li><strong>Color palette</strong> - A quick launcher of the palette with the selected library.</li>
</ol>
<h3 id="color-picker-gradients">Gradients</h3>
<p>You can apply gradient fills to layers. To do that select the Gradient type at the color picker.</p>
<figure>
<img alt="Gradient" src="/img/styling/color-picker-gradient.webp"/>
</figure>
<p>You can choose between two types of gradients:</p>
<ul>
<li><strong>Linear Gradient:</strong> A smooth transition between two or more colors along a straight line, with the option to adjust the angle.</li>
<li><strong>Radial Gradient:</strong> A circular color transition that starts with one color at the center and gradually shifts to another at the edges, which could be a different color or a fade to transparency.</li>
</ul>
<h2 id="color-palette">Color palette</h2>
<p>The color palette allows you to have a selected color library in plain sight.</p>
<figure>

View file

@ -0,0 +1,115 @@
{
"~:features": {
"~#set": [
"layout/grid",
"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": "10113 - Emtpy lib",
"~:revn": 1,
"~:modified-at": "~m1739365936352",
"~:vern": 0,
"~:id": "~u5b7ebd2b-2907-80db-8005-b9d67c20cf2e",
"~:is-shared": false,
"~:migrations": {
"~#ordered-set": [
"legacy-2",
"legacy-3",
"legacy-5",
"legacy-6",
"legacy-7",
"legacy-8",
"legacy-9",
"legacy-10",
"legacy-11",
"legacy-12",
"legacy-13",
"legacy-14",
"legacy-16",
"legacy-17",
"legacy-18",
"legacy-19",
"legacy-25",
"legacy-26",
"legacy-27",
"legacy-28",
"legacy-29",
"legacy-31",
"legacy-32",
"legacy-33",
"legacy-34",
"legacy-36",
"legacy-37",
"legacy-38",
"legacy-39",
"legacy-40",
"legacy-41",
"legacy-42",
"legacy-43",
"legacy-44",
"legacy-45",
"legacy-46",
"legacy-47",
"legacy-48",
"legacy-49",
"legacy-50",
"legacy-51",
"legacy-52",
"legacy-53",
"legacy-54",
"legacy-55",
"legacy-56",
"legacy-57",
"legacy-59",
"legacy-62",
"legacy-65",
"legacy-66",
"legacy-67"
]
},
"~:version": 67,
"~:project-id": "~u1ad2931c-eb80-8098-8005-b86c1d9d26c2",
"~:created-at": "~m1739365911709",
"~:data": {
"~:pages": [
"~u5b7ebd2b-2907-80db-8005-b9d67c20cf2f"
],
"~:pages-index": {
"~u5b7ebd2b-2907-80db-8005-b9d67c20cf2f": {
"~#penpot/pointer": [
"~u5b7ebd2b-2907-80db-8005-b9d67c21cbd3",
{
"~:created-at": "~m1739365911687"
}
]
}
},
"~:id": "~u5b7ebd2b-2907-80db-8005-b9d67c20cf2e",
"~:options": {
"~:components-v2": true
},
"~:colors": {
"~u84a1567d-3f0f-804e-8005-b9d6907e3c8a": {
"~:path": "",
"~:color": "#0087ff",
"~:name": "#0087ff",
"~:modified-at": "~m1739365936355",
"~:opacity": 1,
"~:id": "~u84a1567d-3f0f-804e-8005-b9d6907e3c8a"
}
}
}
}

View file

@ -0,0 +1,101 @@
{
"~:id": "~u5b7ebd2b-2907-80db-8005-b9d67c21cbd3",
"~:file-id": "~u5b7ebd2b-2907-80db-8005-b9d67c20cf2e",
"~:created-at": "~m1739365911680",
"~:data": {
"~: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.0,
"~:y": 0.0
}
},
{
"~#point": {
"~:x": 0.01,
"~:y": 0.0
}
},
{
"~#point": {
"~:x": 0.01,
"~:y": 0.01
}
},
{
"~#point": {
"~:x": 0.0,
"~:y": 0.01
}
}
],
"~:r2": 0,
"~:proportion-lock": false,
"~:transform-inverse": {
"~#matrix": {
"~:a": 1.0,
"~:b": 0.0,
"~:c": 0.0,
"~:d": 1.0,
"~:e": 0.0,
"~:f": 0.0
}
},
"~:r3": 0,
"~:r1": 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,
"~:r4": 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": "~u5b7ebd2b-2907-80db-8005-b9d67c20cf2f",
"~:name": "Page 1"
}
}

View file

@ -0,0 +1,5 @@
{
"~:id": "~u5b7ebd2b-2907-80db-8005-b9d67c20cf2e",
"~:name": "10113 - Emtpy lib",
"~:is-shared": true
}

View file

@ -227,7 +227,7 @@ export class WorkspacePage extends BaseWebSocketPage {
}
async openLibrariesModal(clickOptions = {}) {
await this.sidebar.getByText("Libraries").click(clickOptions);
await this.sidebar.getByTestId("libraries").click(clickOptions);
await expect(this.librariesModal).toBeVisible();
}

View file

@ -72,3 +72,41 @@ test("Bug 9056 - 'More info' doesn't open the update tab", async ({ page }) => {
/library updates/i,
);
});
test("Bug 10113 - Empty library modal for non-empty library", async ({
page,
}) => {
const workspace = new WorkspacePage(page);
await workspace.setupEmptyFile(page);
await workspace.mockRPC(/get\-file\?/, "workspace/get-file-10113.json");
await workspace.mockRPC(
"get-file-fragment?file-id=*&fragment-id=*",
"workspace/get-file-fragment-10113.json",
);
await workspace.mockRPC(/get\-file\?/, "workspace/get-file-10113.json");
await workspace.mockRPC(
"get-team-shared-files?team-id=*",
"workspace/get-team-shared-files-empty.json",
);
await workspace.mockRPC(
"set-file-shared",
"workspace/set-file-shared-10113.json",
);
await workspace.goToWorkspace({
fileId: "5b7ebd2b-2907-80db-8005-b9d67c20cf2e",
pageId: "5b7ebd2b-2907-80db-8005-b9d67c20cf2f",
});
await workspace.clickAssets();
await workspace.openLibrariesModal();
await workspace.librariesModal
.getByRole("button", { name: "Publish" })
.click();
await expect(
workspace.page.getByText("Publish empty library"),
).not.toBeVisible();
});

View file

@ -84,7 +84,7 @@
:controls :inline-actions
:type :inline
:level level
:accept {:label (tr "Refresh")
:accept {:label (tr "labels.refresh")
:callback force-reload!}
:tag :notification))

View file

@ -16,6 +16,7 @@
[app.main.data.common :as dcm]
[app.main.data.event :as ev]
[app.main.data.fonts :as df]
[app.main.data.helpers :as dsh]
[app.main.data.modal :as modal]
[app.main.data.websocket :as dws]
[app.main.features :as features]
@ -248,15 +249,18 @@
(ptk/reify ::create-project
ptk/WatchEvent
(watch [_ state _]
(let [unames (cfh/get-used-names (get state :projects))
(let [team-id (:current-team-id state)
projects (dsh/lookup-team-projects state team-id)
unames (cfh/get-used-names projects)
base-name (tr "dashboard.new-project-prefix")
name (cfh/generate-unique-name base-name unames :immediate-suffix? true)
team-id (:current-team-id state)
params {:name name
:team-id team-id}
name (cfh/generate-unique-name base-name unames :immediate-suffix? true)
team-id (:current-team-id state)
params {:name name
:team-id team-id}
{:keys [on-success on-error]
:or {on-success identity
on-error rx/throw}} (meta params)]
on-error rx/throw}}
(meta params)]
(->> (rp/cmd! :create-project params)
(rx/tap on-success)
(rx/map project-created)
@ -465,10 +469,11 @@
ptk/UpdateEvent
(update [_ state]
(-> state
(assoc-in [:files id] file)
(assoc-in [:recent-files id] file)
(update-in [:projects project-id :count] inc)))))
(let [file (dissoc file :data)]
(-> state
(assoc-in [:files id] file)
(assoc-in [:recent-files id] file)
(update-in [:projects project-id :count] inc))))))
(defn create-file
[{:keys [project-id name] :as params}]
@ -482,8 +487,11 @@
(watch [it state _]
(let [{:keys [on-success on-error]
:or {on-success identity
on-error rx/throw}} (meta params)
unames (cfh/get-used-names (get state :files))
on-error rx/throw}}
(meta params)
files (dsh/lookup-team-files state)
unames (cfh/get-used-names files)
base-name (tr "dashboard.new-file-prefix")
name (or name
(cfh/generate-unique-name base-name unames :immediate-suffix? true))
@ -597,10 +605,10 @@
pparams (:path-params route)
in-project? (contains? pparams :project-id)
name (if in-project?
(let [files (get state :files)
(let [files (dsh/lookup-team-files state team-id)
unames (cfh/get-used-names files)]
(cfh/generate-unique-name (tr "dashboard.new-file-prefix") unames :immediate-suffix? true))
(let [projects (get state :projects)
(let [projects (dsh/lookup-team-projects state team-id)
unames (cfh/get-used-names projects)]
(cfh/generate-unique-name (tr "dashboard.new-project-prefix") unames :immediate-suffix? true)))
params (if in-project?

View file

@ -168,3 +168,21 @@
[state]
(when-let [{:keys [x y width height]} (get-in state [:workspace-local :vbox])]
(gpt/point (+ x (/ width 2)) (+ y (/ height 2)))))
(defn lookup-team-files
([state]
(lookup-team-files state (:current-team-id state)))
([state team-id]
(->> state
:files
(filter #(= team-id (:team-id (val %))))
(into {}))))
(defn lookup-team-projects
([state]
(lookup-team-projects (:current-team-id state)))
([state team-id]
(->> state
:projects
(filter #(= team-id (:team-id (val %))))
(into {}))))

View file

@ -8,6 +8,7 @@
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.exceptions :as ex]
[app.common.logging :as log]
[app.common.schema :as sm]
[app.common.types.team :as ctt]
@ -118,8 +119,10 @@
(let [team-id (:current-team-id state)
teams (get state :teams)
team (get teams team-id)]
(rx/of (set-current-team team)
(fetch-members))))))
(if (not team)
(rx/throw (ex/error :type :authentication))
(rx/of (set-current-team team)
(fetch-members)))))))
(defn initialize-team
[team-id]

View file

@ -319,8 +319,6 @@
ptk/UpdateEvent
(update [_ state]
(-> state
(dissoc :files)
(dissoc :workspace-ready)
(assoc :recent-colors (:recent-colors storage/user))
(assoc :recent-fonts (:recent-fonts storage/user))
(assoc :current-file-id file-id)
@ -395,12 +393,9 @@
(dissoc
:current-file-id
:workspace-editor-state
:files
:workspace-media-objects
:workspace-persistence
:workspace-presence
:workspace-tokens
:workspace-ready
:workspace-undo)
(update :workspace-global dissoc :read-only?)
(assoc-in [:workspace-global :options-mode] :design)))
@ -428,18 +423,18 @@
(defmethod ptk/resolve ::reload-current-file [_ _] (reload-current-file))
(defn initialize-page
[page-id]
(assert (uuid? page-id) "expected valid uuid for `page-id`")
[file-id page-id]
(assert (uuid? file-id) "expected valid uuid for `file-id`")
(ptk/reify ::initialize-page
ptk/UpdateEvent
(update [_ state]
(if-let [{:keys [id] :as page} (dsh/lookup-page state page-id)]
(if-let [page (dsh/lookup-page state file-id page-id)]
;; we maintain a cache of page state for user convenience with the exception of the
;; selection; when user abandon the current page, the selection is lost
(let [local (dm/get-in state [:workspace-cache id] default-workspace-local)]
(let [local (dm/get-in state [:workspace-cache [file-id page-id]] default-workspace-local)]
(-> state
(assoc :current-page-id id)
(assoc :current-page-id page-id)
(assoc :workspace-local (assoc local :selected (d/ordered-set)))
(assoc :workspace-trimmed-page (dm/select-keys page [:id :name]))
@ -451,24 +446,25 @@
ptk/WatchEvent
(watch [_ state _]
(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))))))
(if (dsh/lookup-page state file-id page-id)
(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 :file-id file-id ::rt/replace true))))))
(defn finalize-page
[page-id]
[file-id page-id]
(assert (uuid? file-id) "expected valid uuid for `file-id`")
(assert (uuid? page-id) "expected valid uuid for `page-id`")
(ptk/reify ::finalize-page
ptk/UpdateEvent
(update [_ state]
(let [local (-> (:workspace-local state)
(dissoc :edition :edit-path :selected))
exit? (not= :workspace (dm/get-in state [:route :data :name]))
exit? (not= :workspace (rt/lookup-name state))
state (-> state
(update :workspace-cache assoc page-id local)
(update :workspace-cache assoc [file-id page-id] local)
(dissoc :current-page-id
:workspace-local
:workspace-trimmed-page

View file

@ -741,12 +741,12 @@
redirect-to-page
(fn [page-id shape-id]
(rx/merge
(rx/of (dcm/go-to-workspace :page-id page-id))
(->> stream
(rx/filter (ptk/type? ::initialize-page))
(rx/filter (ptk/type? ::dw/initialize-page))
(rx/take 1)
(rx/observe-on :async)
(rx/mapcat (fn [_] (select-and-zoom shape-id))))))]
(rx/mapcat (fn [_] (select-and-zoom shape-id))))
(rx/of (dcm/go-to-workspace :page-id page-id))))]
(when-let [component (dm/get-in data [:components id])]
(let [page-id (:main-instance-page component)

View file

@ -120,6 +120,11 @@
([id params & {:as options}]
(navigate id params options)))
(defn lookup-name
[state]
(dm/get-in state [:route :data :name]))
;; FIXME: rename to lookup-params
(defn get-params
[state]
(dm/get-in state [:route :params :query]))

View file

@ -127,7 +127,6 @@
{::mf/props :obj
::mf/private true}
[{:keys [team-id children]}]
(mf/with-effect [team-id]
(st/emit! (dtm/initialize-team team-id))
(fn []

View file

@ -237,9 +237,14 @@
(str/last-index-of (subs node-text 0 offset) "@")
mention-text
(subs node-text current-at-symbol)]
(subs node-text current-at-symbol)
(if (re-matches #"@\w*" mention-text)
at-symbol-inside-word?
(and (> current-at-symbol 0)
(str/word? (str/slice node-text (- current-at-symbol 1) current-at-symbol)))]
(if (and (not at-symbol-inside-word?)
(re-matches #"@\w*" mention-text))
(do
(reset! cur-mention mention-text)
(rx/push! mentions-s {:type :display-mentions})
@ -305,6 +310,17 @@
(when (fn? on-change)
(on-change (parse-nodes node))))))))
handle-insert-at-symbol
(mf/use-fn
(fn []
(let [node (mf/ref-val local-ref) [span-node] (current-text-node node)]
(when span-node
(let [node-text (dom/get-text span-node)
at-symbol (if (blank-content? node-text) "@" " @")]
(dom/set-html! span-node (str/concat node-text at-symbol))
(wapi/set-cursor-after! span-node))))))
handle-key-down
(mf/use-fn
(mf/deps on-esc on-ctrl-enter handle-select handle-input)
@ -386,6 +402,8 @@
(case type
:insert-mention
(handle-insert-mention data)
:insert-at-symbol
(handle-insert-at-symbol)
nil))))))
@ -521,15 +539,25 @@
{::mf/props :obj
::mf/private true}
[]
(let [mentions-s (mf/use-ctx mentions-context)
(let [mentions-s (mf/use-ctx mentions-context)
display-mentions* (mf/use-state false)
handle-mouse-down
handle-pointer-down
(mf/use-fn
(mf/deps @display-mentions*)
(fn [event]
(dom/prevent-default event)
(dom/stop-propagation event)
(rx/push! mentions-s {:type :display-mentions})))]
(if @display-mentions*
(rx/push! mentions-s {:type :hide-mentions})
(rx/push! mentions-s {:type :insert-at-symbol}))))
handle-key-down
(mf/use-fn
(mf/deps @display-mentions*)
(fn [event]
(when (or (kbd/enter? event) (kbd/space? event))
(handle-pointer-down event))))]
(mf/use-effect
(fn []
@ -545,8 +573,9 @@
[:> icon-button*
{:variant "ghost"
:aria-label (tr "labels.options")
:on-pointer-down handle-mouse-down
:aria-label (tr "labels.mention")
:on-pointer-down handle-pointer-down
:on-key-down handle-key-down
:icon-class (stl/css-case :open-mentions-button true
:is-toggled @display-mentions*)
:icon "at"}]))

View file

@ -255,7 +255,6 @@
}
.open-mentions-button {
cursor: pointer;
stroke: none;
fill: var(--color-foreground-secondary);

View file

@ -149,7 +149,6 @@
[:input {:type "text"
:value (:token created "")
:class (stl/css :custom-input-token)
:placeholder (tr "modals.create-access-token.token")
:read-only true}]
[:button {:title (tr "modals.create-access-token.copy-token")
:class (stl/css :copy-btn)

View file

@ -9,7 +9,6 @@
(:require
[app.common.data.macros :as dm]
[app.main.data.common :as dcm]
[app.main.data.helpers :as dsh]
[app.main.data.persistence :as dps]
[app.main.data.plugins :as dpl]
[app.main.data.workspace :as dw]
@ -43,13 +42,6 @@
[okulary.core :as l]
[rumext.v2 :as mf]))
(defn- make-workspace-ready-ref
[file-id]
(l/derived (fn [state]
(and (= file-id (:workspace-ready state))
(some? (dsh/lookup-file-data state file-id))))
st/state))
(mf/defc workspace-content*
{::mf/private true}
[{:keys [file layout page wglobal]}]
@ -138,22 +130,18 @@
key (events/listen globals/window "blur" focus-out)]
(partial events/unlistenByKey key)))
(mf/with-effect [page-id]
(if (some? page-id)
(st/emit! (dw/initialize-page page-id))
(st/emit! (dcm/go-to-workspace ::rt/replace true)))
(mf/with-effect [file page-id]
(st/emit! (dw/initialize-page (:id file) page-id))
(fn []
(when (some? page-id)
(st/emit! (dw/finalize-page page-id)))))
(when page-id
(st/emit! (dw/finalize-page (:id file) page-id)))))
(if (some? page)
[:> workspace-content* {:file file
:page page
:wglobal wglobal
:layout layout}]
[:& workspace-loader*])))
[:> workspace-loader*])))
(def ^:private ref:file-without-data
(l/derived (fn [file]
@ -181,10 +169,6 @@
read-only? (mf/deref refs/workspace-read-only?)
read-only? (or read-only? (not (:can-edit permissions)))
ready* (mf/with-memo [file-id]
(make-workspace-ready-ref file-id))
ready? (mf/deref ready*)
design-tokens? (features/use-feature "design-tokens/v1")
background-color (:background-color wglobal)]
@ -207,6 +191,10 @@
(st/emit! ::dps/force-persist
(dw/finalize-workspace file-id))))
(mf/with-effect [file page-id]
(when-not page-id
(st/emit! (dcm/go-to-workspace :file-id file-id ::rt/replace true))))
[:> (mf/provider ctx/current-project-id) {:value project-id}
[:> (mf/provider ctx/current-file-id) {:value file-id}
[:> (mf/provider ctx/current-page-id) {:value page-id}
@ -219,9 +207,10 @@
:touch-action "none"}}
[:> context-menu*]
(if ^boolean ready?
[:> workspace-page* {:page-id page-id
:file file
:wglobal wglobal
:layout layout}]
(if (some? file)
[:> workspace-page*
{:page-id page-id
:file file
:wglobal wglobal
:layout layout}]
[:> workspace-loader*])]]]]]]]))

View file

@ -14,7 +14,6 @@
[app.common.types.file :as ctf]
[app.common.types.typographies-list :as ctyl]
[app.common.uuid :as uuid]
[app.config :as cf]
[app.main.data.dashboard :as dd]
[app.main.data.modal :as modal]
[app.main.data.notifications :as ntf]
@ -176,15 +175,7 @@
(defn- empty-library?
"Check if currentt library summary has elements or not"
[summary]
(let [colors (or (-> summary :colors :count) 0)
components (or (-> summary :components :count) 0)
media (or (-> summary :media :count) 0)
typographies (or (-> summary :typographies :count) 0)]
(and (zero? colors)
(zero? components)
(zero? media)
(zero? typographies))))
(boolean (:is-empty summary)))
(mf/defc libraries-tab*
{::mf/props :obj
@ -362,7 +353,7 @@
(nil? shared-libraries)
(tr "workspace.libraries.loading")
(and (str/empty? search-term) (cf/external-feature-flag "templates-03" "test"))
(str/empty? search-term)
[:*
[:div {:class (stl/css :sample-libraries-info)}
(tr "workspace.libraries.empty.no-libraries")
@ -377,19 +368,6 @@
{:library library
:importing importing*}])]]
(str/empty? search-term)
[:*
[:span {:class (stl/css :empty-state-icon)}
library-icon]
(tr "workspace.libraries.no-shared-libraries-available")
(when (cf/external-feature-flag "templates-01" "test")
[:div {:class (stl/css :templates-info)}
(tr "workspace.libraries.more-templates")
[:a {:target "_blank"
:class (stl/css :templates-info-link)
:href "https://penpot.app/libraries-templates"}
(tr "workspace.libraries.more-templates-link")]])]
:else
(tr "workspace.libraries.no-matches-for" search-term))]))]]))

View file

@ -326,16 +326,6 @@
padding: $s-0 $s-16;
}
.templates-info {
color: var(--color-accent-primary);
}
.templates-info-link {
color: var(--color-accent-primary);
text-decoration: underline;
font-weight: $fw400;
}
.sample-libraries-info {
display: flex;
flex-direction: column;

View file

@ -8,7 +8,6 @@
(:require-macros [app.main.style :as stl])
(:require
[app.common.data.macros :as dm]
[app.config :as cf]
[app.main.data.modal :as modal]
[app.main.data.workspace :as dw]
[app.main.data.workspace.assets :as dwa]
@ -92,12 +91,6 @@
reverse-sort? (= :desc ordering)
num-libs (count (mf/deref refs/libraries))
show-templates-04-test1?
(and (cf/external-feature-flag "templates-04" "test1") (zero? num-libs))
show-templates-04-test2?
(and (cf/external-feature-flag "templates-04" "test2") (zero? num-libs))
toggle-ordering
(mf/use-fn
(mf/deps ordering)
@ -166,18 +159,12 @@
[:article {:class (stl/css :assets-bar)}
[:div {:class (stl/css :assets-header)}
(when-not ^boolean read-only?
(cond
show-templates-04-test1?
[:button {:class (stl/css :libraries-button)
:on-click show-libraries-dialog
:data-testid "libraries"}
(tr "workspace.assets.add-library")]
show-templates-04-test2?
(if (= num-libs 1)
[:button {:class (stl/css :add-library-button)
:on-click show-libraries-dialog
:data-testid "libraries"}
(tr "workspace.assets.add-library")]
:else
[:button {:class (stl/css :libraries-button)
:on-click show-libraries-dialog
:data-testid "libraries"}

View file

@ -534,7 +534,7 @@
:on-ungroup on-ungroup
:on-context-menu on-context-menu
:selected-full selected-full
:local ^boolean is-local}])
:is-local ^boolean is-local}])
[:& cmm/assets-context-menu
{:on-close on-close-menu

View file

@ -77,12 +77,12 @@
[:& radio-button {:icon i/boolean-intersection
:value "intersection"
:disabled disabled-bool-btns
:title (str (tr "intersection") " (" (sc/get-tooltip :bool-intersection) ")")
:title (str (tr "workspace.shape.menu.intersection") " (" (sc/get-tooltip :bool-intersection) ")")
:id "bool-opt-intersection"}]
[:& radio-button {:icon i/boolean-exclude
:value "exclude"
:disabled disabled-bool-btns
:title (str (tr "exclude") " (" (sc/get-tooltip :bool-exclude) ")")
:title (str (tr "workspace.shape.menu.exclude") " (" (sc/get-tooltip :bool-exclude) ")")
:id "bool-opt-exclude"}]]]
[:button

View file

@ -120,7 +120,7 @@
(dom/prevent-default e)
(dom/stop-propagation e)
(st/emit! (wdt/toggle-token-theme-active? group name)))}
[:& switch {:name (tr "workspace.token.theme" name)
[:& switch {:name (tr "workspace.token.theme-name" name)
:on-change (constantly nil)
:selected? selected?}]]
[:> text* {:as "span" :typography "body-medium" :class (stl/css :theme-name)} name]]

View file

@ -63,10 +63,10 @@
target-container-id (or target-container-id (:parent-id shape))]
(filter some?
[(when target-page-id (dw/initialize-page target-page-id))
[(when target-page-id (dw/initialize-page (:id file) target-page-id))
(dws/select-shape target-container-id)
(dw/paste-shapes pdata)
(when target-page-id (dw/initialize-page (:id page)))])))
(when target-page-id (dw/initialize-page (:id file) (:id page)))])))
(defn- sync-file [file]
(map (fn [component-tag]

View file

@ -12,9 +12,8 @@ msgstr ""
"X-Generator: Weblate 5.10-dev\n"
#: src/app/main/data/common.cljs:87
#, fuzzy
msgid "Refresh"
msgstr ""
msgid "labels.refresh"
msgstr "Refresh"
#: src/app/main/ui/auth/register.cljs:133, src/app/main/ui/static.cljs:155, src/app/main/ui/viewer/login.cljs:98
msgid "auth.already-have-account"
@ -1386,11 +1385,6 @@ msgstr "Email or password is incorrect."
msgid "errors.wrong-old-password"
msgstr "Old password is incorrect"
#: src/app/main/ui/workspace/sidebar/options/menus/bool.cljs:85
#, fuzzy
msgid "exclude"
msgstr ""
#: src/app/main/ui/settings/feedback.cljs:74
msgid "feedback.description"
msgstr "Description"
@ -1691,11 +1685,6 @@ msgstr "Text"
msgid "inspect.tabs.info"
msgstr "Info"
#: src/app/main/ui/workspace/sidebar/options/menus/bool.cljs:80
#, fuzzy
msgid "intersection"
msgstr ""
#: src/app/main/ui/workspace/main_menu.cljs:162
msgid "label.shortcuts"
msgstr "Shortcuts"
@ -2020,6 +2009,10 @@ msgstr "Member"
msgid "labels.members"
msgstr "Members"
#: src/app/main/ui/comments.cljs:558
msgid "labels.mention"
msgstr "Mention"
#: src/app/main/ui/settings/password.cljs:84
msgid "labels.new-password"
msgstr "New password"
@ -2458,11 +2451,6 @@ msgstr "Create token"
msgid "modals.create-access-token.title"
msgstr "Generate access token"
#: src/app/main/ui/settings/access_tokens.cljs:152
#, fuzzy
msgid "modals.create-access-token.token"
msgstr ""
#: src/app/main/ui/dashboard/team.cljs:921
msgid "modals.create-webhook.submit-label"
msgstr "Create webhook"
@ -4806,10 +4794,6 @@ msgstr "Loading…"
msgid "workspace.libraries.more-templates"
msgstr "You can look for "
#: src/app/main/ui/workspace/libraries.cljs:391
msgid "workspace.libraries.more-templates-link"
msgstr "more templates in here"
#: src/app/main/ui/workspace/libraries.cljs:481
msgid "workspace.libraries.no-libraries-need-sync"
msgstr "There are no Shared Libraries that need update"
@ -4818,10 +4802,6 @@ msgstr "There are no Shared Libraries that need update"
msgid "workspace.libraries.no-matches-for"
msgstr "No matches found for “%s“"
#: src/app/main/ui/workspace/libraries.cljs:384
msgid "workspace.libraries.no-shared-libraries-available"
msgstr "There are no Shared Libraries available"
#: src/app/main/ui/workspace/libraries.cljs:337
msgid "workspace.libraries.search-shared-libraries"
msgstr "Search shared libraries"
@ -6625,11 +6605,6 @@ msgstr "Select set."
msgid "workspace.token.set-selection-theme"
msgstr "Define what token sets should be used as part of this theme option:"
#: src/app/main/ui/workspace/tokens/modals/themes.cljs:123
#, fuzzy
msgid "workspace.token.theme"
msgstr ""
#: src/app/main/ui/workspace/tokens/modals/themes.cljs
#, unused
msgid "workspace.token.theme-name"

View file

@ -2015,6 +2015,10 @@ msgstr "Integrante"
msgid "labels.members"
msgstr "Integrantes"
#: src/app/main/ui/comments.cljs:558
msgid "labels.mention"
msgstr "Mencionar"
#: src/app/main/ui/settings/password.cljs:84
msgid "labels.new-password"
msgstr "Nueva contraseña"
@ -4800,10 +4804,6 @@ msgstr "Cargando…"
msgid "workspace.libraries.more-templates"
msgstr "Puedes buscar "
#: src/app/main/ui/workspace/libraries.cljs:391
msgid "workspace.libraries.more-templates-link"
msgstr "más plantillas aquí"
#: src/app/main/ui/workspace/libraries.cljs:481
msgid "workspace.libraries.no-libraries-need-sync"
msgstr "No hay bibliotecas que necesiten ser actualizadas"
@ -4812,10 +4812,6 @@ msgstr "No hay bibliotecas que necesiten ser actualizadas"
msgid "workspace.libraries.no-matches-for"
msgstr "No se encuentra “%s“"
#: src/app/main/ui/workspace/libraries.cljs:384
msgid "workspace.libraries.no-shared-libraries-available"
msgstr "No hay bibliotecas compartidas disponibles"
#: src/app/main/ui/workspace/libraries.cljs:337
msgid "workspace.libraries.search-shared-libraries"
msgstr "Buscar bibliotecas compartidas"