Compare commits

...

16 Commits

Author SHA1 Message Date
Andrey Antukh
04f573cb23 WIP 2025-08-19 14:09:07 +02:00
Andrey Antukh
d46ad9d6f1 Add generative test case for openapi json serialization
This will prevent possible regression on introducing schemas without
generators or schema with generators that can't be serialized to json.
2025-08-19 11:34:50 +02:00
Andrey Antukh
2e8d08d047 🐛 Use ::sm/any instead of any for get-file-fragment rpc method schema
The usage of `any?` predicate as-is uses the standard any generator that
causes to generate java.lang.Character instances created that are not
properly serialiable to JSON. The `::sm/any` schema delimits the
generator to a commonly known serializable types on json.
2025-08-19 11:32:41 +02:00
Andrey Antukh
9c57596954 🐛 Add missing generators 2025-08-19 10:49:17 +02:00
Andrey Antukh
cc41fb569d 🔥 Remove already deprecated change spec 2025-08-19 10:49:00 +02:00
Andrey Antukh
79ad322809 📎 Update .gitignore file 2025-08-19 10:49:00 +02:00
Andrey Antukh
362ea401a0 🐛 Add missing attrs to add-component change schema 2025-08-19 10:49:00 +02:00
Andrey Antukh
7afb5abf35 🐛 Add proper schema for decoding :obj on add-obj change 2025-08-19 10:49:00 +02:00
Andrey Antukh
1b16129c45 🐛 Fix incorrect handling of assign operation on changes protocol 2025-08-19 10:49:00 +02:00
Eva Marco
ff2e845f2c 🐛 Fix double click on set name input (#7096) 2025-08-13 09:23:53 +02:00
Alejandro Alonso
8e0a6e4123 🐛 Fix auto height is fixed in the HTML inspect tab for text elements (#7078) 2025-08-11 09:07:43 +02:00
Marina López
0131cd6f8b Display the total price of the subscription and the cap amount (#7088) 2025-08-11 09:07:24 +02:00
Andrey Antukh
288a7b21d6 Merge tag '2.9.0-RC8' 2025-08-08 09:47:42 +02:00
Yamila Moreno
c1aae12327 📎 Improve gh actions 2025-08-07 18:08:25 +02:00
Andrey Antukh
133e6e1e68 Merge tag '2.9.0-RC7' 2025-08-07 16:30:30 +02:00
Francis Santiago
4501d13961 📚 Clarify OpenShift requirements (#6937)
* 📚 Clarify OpenShift requirements

* 📚 Remove the click for expanding
2025-08-01 16:26:04 +02:00
17 changed files with 342 additions and 175 deletions

1
.gitignore vendored
View File

@@ -31,6 +31,7 @@
/.clj-kondo/.cache
/_dump
/notes
/playground/
/backend/*.md
/backend/*.sql
/backend/*.txt

View File

@@ -28,6 +28,8 @@
- Add the ability to show login dialog on profile settings [Github #6871](https://github.com/penpot/penpot/pull/6871)
- Improve the application of tokens with object specific tokens [Taiga #10209](https://tree.taiga.io/project/penpot/us/10209)
- Add info to apply-token event [Taiga #11710](https://tree.taiga.io/project/penpot/task/11710)
- Fix double click on set name input [Taiga #11747](https://tree.taiga.io/project/penpot/issue/11747)
### :bug: Bugs fixed
@@ -58,6 +60,7 @@
- Fix export button width on inspect tab [Taiga #11394](https://tree.taiga.io/project/penpot/issue/11394)
- Fix stroke width token application [Taiga #11724](https://tree.taiga.io/project/penpot/issue/11724)
- Fix number token application on shape [Taiga #11331](https://tree.taiga.io/project/penpot/task/11331)
- Fix auto height is fixed in the HTML inspect tab for text elements [Taiga #11680](https://tree.taiga.io/project/penpot/task/11680)
## 2.8.1

View File

@@ -357,7 +357,7 @@
[:id ::sm/uuid]
[:file-id ::sm/uuid]
[:created-at ::dt/instant]
[:content any?]])
[:content ::sm/any]])
(def schema:get-file-fragment
[:map {:title "get-file-fragment"}

View File

@@ -0,0 +1,36 @@
;; This Source Code Form is subject to the terms of the Mozilla Public
;; License, v. 2.0. If a copy of the MPL was not distributed with this
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
;;
;; Copyright (c) KALEIDOS INC
(ns backend-tests.rpc-doc-test
"Internal binfile test, no RPC involved"
(:require
[app.common.json :as json]
[app.common.pprint :as pp]
[app.common.schema :as sm]
[app.common.schema.generators :as sg]
[app.common.schema.test :as smt]
[app.rpc :as-alias rpc]
[app.rpc.doc :as rpc.doc]
[backend-tests.helpers :as th]
[clojure.test :as t]))
(t/use-fixtures :once th/state-init)
(t/deftest openapi-context-json-encode
(smt/check!
(smt/for [context (->> sg/int
(sg/fmap (fn [_]
(rpc.doc/prepare-openapi-context (::rpc/methods th/*system*)))))]
(try
(json/encode context)
true
(catch Throwable _cause
false)))
{:num 30}))

View File

@@ -177,12 +177,6 @@
:title "Change"
:decode/json #(update % :type keyword)
::smd/simplified true}
[:set-option
;; DEPRECATED: remove before 2.3 release
;;
;; Is still there for not cause error when event is received
[:map {:title "SetOptionChange"}]]
[:set-comment-thread-position
[:map
@@ -195,7 +189,7 @@
[:map {:title "AddObjChange"}
[:type [:= :add-obj]]
[:id ::sm/uuid]
[:obj :map]
[:obj cts/schema:shape]
[:page-id {:optional true} ::sm/uuid]
[:component-id {:optional true} ::sm/uuid]
[:frame-id ::sm/uuid]
@@ -328,7 +322,9 @@
[:id ::sm/uuid]
[:name :string]
[:shapes {:optional true} [:vector {:gen/max 3} ::sm/any]]
[:path {:optional true} :string]]]
[:path {:optional true} :string]
[:main-instance-id ::sm/uuid]
[:main-instance-page ::sm/uuid]]]
[:mod-component
[:map {:title "ModCompoenentChange"}
@@ -546,11 +542,6 @@
#?(:clj (validate-shapes! data result items))
result))))
;; DEPRECATED: remove after 2.3 release
(defmethod process-change :set-option
[data _]
data)
;; --- Comment Threads
(defmethod process-change :set-comment-thread-position
@@ -1090,21 +1081,23 @@
;; === Operations
(def ^:private decode-shape
(sm/decoder cts/schema:shape sm/json-transformer))
(def decode-shape-attrs
(sm/decoder cts/schema:shape-attrs sm/json-transformer))
(defmethod process-operation :assign
[{:keys [type] :as shape} {:keys [value] :as op}]
(let [modifications (assoc value :type type)
modifications (decode-shape modifications)]
modifications (decode-shape-attrs modifications)]
(reduce-kv (fn [shape k v]
(process-operation shape {:type :set
:attr k
:val v
:ignore-touched (:ignore-touched op)
:ignore-geometry (:ignore-geometry op)}))
(if (not= v (get shape k))
(process-operation shape {:type :set
:attr k
:val v
:ignore-touched (:ignore-touched op)
:ignore-geometry (:ignore-geometry op)})
shape))
shape
modifications)))
(dissoc modifications :type))))
(defmethod process-operation :set
[shape op]

View File

@@ -111,7 +111,7 @@
(defmethod visit :fn [_ _ _ _] "FN")
(defmethod visit :vector [_ _ children _]
(str "[" (last children) "]"))
(str "[" (str/trim (last children)) "]"))
(defn -tagged [children] (map (fn [[tag _ c]] (str c " (tag: " tag ")")) children))
@@ -137,8 +137,14 @@
(some? suffix)
(str suffix))))
(defmethod visit :map-of [_ _ children _]
(str "map[" (first children) "," (second children) "]"))
(defmethod visit :map-of
[_ schema children _]
(let [props (m/properties schema)
title (some->> (:title props) str/camel str/capital)]
(str (if title
(str "type " title ": ")
"")
"map[" (first children) "," (second children) "]")))
(defmethod visit :union [_ _ children _]
(str/join " | " children))
@@ -156,61 +162,123 @@
(or (:title props)
"*")))
(defn- format-map
[schema children]
(let [props (m/properties schema)
closed? (get props :closed)
title (some->> (:title props) str/camel str/capital)
level 0
optional (into #{} (comp (filter (m/-comp :optional second))
(map first))
children)
entries (->> children
(map (fn [[k _ s]]
;; NOTE: maybe we can detect multiple lines
;; and then just insert a break line
(str (pad " " level) (str/camel k)
(when (contains? optional k) "?")
": " (str/trim s))))
(str/join ",\n"))
header (cond-> (str "type " title)
closed? (str "!")
(some? title) (str " "))]
(str (pad header level) "{\n" entries "\n" (pad "}\n" level))))
(defmethod visit :map
[_ schema children {:keys [::level ::max-level] :as options}]
(let [props (m/properties schema)
closed? (:closed props)
title (some->> (:title props) str/camel str/capital)]
(let [props (m/properties schema)
closed? (get props :closed)
title (some->> (:title props) str/camel str/capital)
extracted? (get props ::extracted false)]
(if (>= level max-level)
(or (some-> title str)
"<untitled>")
(let [optional (into #{} (comp (filter (m/-comp :optional second))
(map first))
children)
entries (->> children
(map (fn [[k _ s]]
(str (pad " " level) (str/camel k)
(when (contains? optional k) "?")
": " s)))
(str/join ",\n"))
(if (= level 0)
(format-map schema children)
header (cond-> (str "type " title)
closed? (str "!")
(some? title) (str " "))]
(if title
(if extracted?
(format-map schema children)
(let [schema (mu/update-properties schema assoc ::extracted true)]
(swap! *definitions* conj (describe* schema options))
(pad title level)))
(format-map schema children)))))
(str (pad header level) "{\n" entries "\n" (pad "}\n" level))))))
(defn format-multi
[s children]
(let [props (m/properties s)
title (some-> (:title props) str/camel str/capital)
dispatcher (or (-> s m/properties :dispatch-description)
(-> s m/properties :dispatch))
(defmethod visit :multi
[_ s children {:keys [::level ::max-level] :as options}]
(let [props (m/properties s)
title (some-> (:title props) str/camel str/capital)]
(if (>= level max-level)
title
(let [dispatcher (or (-> s m/properties :dispatch-description)
(-> s m/properties :dispatch))
entries (->> children
(map (fn [[_ _ shape]]
(str shape)))
(str/join ",\n"))
prefix (apply str (take (inc level) (repeat " ")))
entries (->> children
(map (fn [[_ _ shape]]
(str prefix shape)))
(str/join ",\n"))
header (cond-> "multi"
header (cond-> "multi"
(some? title) (str " " title)
:always (str " [dispatch=" (d/name dispatcher) "]"))]
(str header " {\n" entries "\n" (pad "}" level))))))
(str header " {\n" entries "\n}")))
(defmethod visit :multi
[_ schema children {:keys [::level ::max-level] :as options}]
(let [props (m/properties schema)
title (some-> (:title props) str/camel str/capital)
extracted? (get props ::extracted false)]
(cond
(zero? level)
(format-multi schema children)
(and title extracted?)
(format-multi schema children)
(and title (not extracted?))
(let [schema (mu/update-properties schema assoc ::extracted true)]
(swap! *definitions* conj (describe* schema options))
(pad title level))
:else
(format-multi schema children))))
(defn- format-merge
[schema children]
(let [props (m/properties schema)
entries (->> children
(map (fn [shape]
(str shape)))
(str/join ",\n"))
title (some-> (:title props) str/camel str/capital)
header (str "merge type " title)]
(str header " {\n" entries "\n}")))
(defmethod visit :merge
[_ schema children _]
(let [entries (str/join ",\n" children)
props (m/properties schema)
title (or (some-> (:title props) str/camel str/capital)
"<untitled>")]
(str "merge type " title " { \n" entries "\n}\n")))
[_ schema children {:keys [::level ::max-level] :as options}]
(let [props (m/properties schema)
title (some-> (:title props) str/camel str/capital)
extracted? (get props ::extracted false)]
(cond
(zero? level)
(format-merge schema children)
(and title extracted?)
(format-merge schema children)
(and title (not extracted?))
(let [schema (mu/update-properties schema assoc ::extracted true)]
(swap! *definitions* conj (describe* schema options))
(pad title level))
:else
(format-merge schema children))))
(defmethod visit ::sm/one-of
[_ _ children _]
@@ -219,8 +287,21 @@
(map d/name)
(str/join "|")) ")")))
(defmethod visit :schema [_ schema children options]
(visit ::m/schema schema children options))
(defmethod visit :schema
[_ schema children options]
(let [props (m/properties schema)
title (some-> (:title props) str/camel str/capital)
extracted? (get props ::extracted false)]
(if title
(if extracted?
(str "type " title ": "
(visit ::m/schema schema children options))
(let [schema (mu/update-properties schema assoc ::extracted true)]
(swap! *definitions* conj (describe* schema options))
title))
(visit ::m/schema schema children options))))
(defmethod visit ::m/schema
[_ schema _ {:keys [::level ::limit ::max-level] :as options}]
@@ -239,9 +320,12 @@
(describe* schema' options)))
(and ref title)
(do
(when (<= limit max-level)
(swap! *definitions* conj (describe* schema' (assoc options ::base-limit limit))))
(let [options (-> options
(assoc ::base-level level)
)]
;; (when (<= limit max-level)
(swap! *definitions* conj (describe* schema' options))
title)
@@ -254,10 +338,11 @@
(describe* schema' (assoc options ::base-level level ::base-limit limit)))))
(defn describe* [s options]
(letfn [(walk-fn [schema path children {:keys [::base-level ::base-limit] :or {base-level 0 base-limit 0} :as options}]
(let [options (assoc options
::limit (+ base-limit (count path))
::level (+ base-level (count path)))]
(letfn [(walk-fn [schema path children {:keys [::base-level ::base-limit]
:or {base-level 0 base-limit 0} :as options}]
(let [options (-> options
(assoc ::limit (+ base-limit (count path)))
(assoc ::level (+ base-level (count path))))]
(visit (m/type schema) schema children options)))]
(m/walk s walk-fn options)))

View File

@@ -24,7 +24,7 @@
(def schema:plugin-data
(sm/register!
^{::sm/type ::plugin-data}
[:map-of {:gen/max 5}
[:map-of {:gen/max 5 :title "PluginsData"}
schema:keyword
[:map-of {:gen/max 5}
schema:string

View File

@@ -185,50 +185,50 @@
[:height ::sm/safe-number]])
(def schema:shape-generic-attrs
[:map {:title "ShapeAttrs"}
[:page-id {:optional true} ::sm/uuid]
[:component-id {:optional true} ::sm/uuid]
[:component-file {:optional true} ::sm/uuid]
[:component-root {:optional true} :boolean]
[:main-instance {:optional true} :boolean]
[:remote-synced {:optional true} :boolean]
[:shape-ref {:optional true} ::sm/uuid]
[:touched {:optional true} [:maybe [:set :keyword]]]
[:blocked {:optional true} :boolean]
[:collapsed {:optional true} :boolean]
[:locked {:optional true} :boolean]
[:hidden {:optional true} :boolean]
[:masked-group {:optional true} :boolean]
[:fills {:optional true}
[:vector {:gen/max 2} schema:fill]]
[:proportion {:optional true} ::sm/safe-number]
[:proportion-lock {:optional true} :boolean]
[:constraints-h {:optional true}
[::sm/one-of horizontal-constraint-types]]
[:constraints-v {:optional true}
[::sm/one-of vertical-constraint-types]]
[:fixed-scroll {:optional true} :boolean]
[:r1 {:optional true} ::sm/safe-number]
[:r2 {:optional true} ::sm/safe-number]
[:r3 {:optional true} ::sm/safe-number]
[:r4 {:optional true} ::sm/safe-number]
[:opacity {:optional true} ::sm/safe-number]
[:grids {:optional true}
[:vector {:gen/max 2} ::ctg/grid]]
[:exports {:optional true}
[:vector {:gen/max 2} ::ctse/export]]
[:strokes {:optional true}
[:vector {:gen/max 2} schema:stroke]]
[:blend-mode {:optional true}
[::sm/one-of blend-modes]]
[:map {:title "ShapeGenericAttrs"}
;; [:page-id {:optional true} ::sm/uuid]
;; [:component-id {:optional true} ::sm/uuid]
;; [:component-file {:optional true} ::sm/uuid]
;; [:component-root {:optional true} :boolean]
;; [:main-instance {:optional true} :boolean]
;; [:remote-synced {:optional true} :boolean]
;; [:shape-ref {:optional true} ::sm/uuid]
;; [:touched {:optional true} [:maybe [:set :keyword]]]
;; [:blocked {:optional true} :boolean]
;; [:collapsed {:optional true} :boolean]
;; [:locked {:optional true} :boolean]
;; [:hidden {:optional true} :boolean]
;; [:masked-group {:optional true} :boolean]
;; [:fills {:optional true}
;; [:vector {:gen/max 2} schema:fill]]
;; [:proportion {:optional true} ::sm/safe-number]
;; [:proportion-lock {:optional true} :boolean]
;; [:constraints-h {:optional true}
;; [::sm/one-of horizontal-constraint-types]]
;; [:constraints-v {:optional true}
;; [::sm/one-of vertical-constraint-types]]
;; [:fixed-scroll {:optional true} :boolean]
;; [:r1 {:optional true} ::sm/safe-number]
;; [:r2 {:optional true} ::sm/safe-number]
;; [:r3 {:optional true} ::sm/safe-number]
;; [:r4 {:optional true} ::sm/safe-number]
;; [:opacity {:optional true} ::sm/safe-number]
;; [:grids {:optional true}
;; [:vector {:gen/max 2} ::ctg/grid]]
;; [:exports {:optional true}
;; [:vector {:gen/max 2} ::ctse/export]]
;; [:strokes {:optional true}
;; [:vector {:gen/max 2} schema:stroke]]
;; [:blend-mode {:optional true}
;; [::sm/one-of blend-modes]]
[:interactions {:optional true}
[:vector {:gen/max 2} ::ctsi/interaction]]
[:shadow {:optional true}
[:vector {:gen/max 1} ctss/schema:shadow]]
[:blur {:optional true} ::ctsb/blur]
;; [:shadow {:optional true}
;; [:vector {:gen/max 1} ctss/schema:shadow]]
;; [:blur {:optional true} ::ctsb/blur]
[:grow-type {:optional true}
[::sm/one-of grow-types]]
[:applied-tokens {:optional true} cto/schema:applied-tokens]
;; [:applied-tokens {:optional true} cto/schema:applied-tokens]
[:plugin-data {:optional true} ::ctpg/plugin-data]])
(def schema:group-attrs
@@ -306,6 +306,15 @@
(merge attrs1 shape attrs2 attrs3)))))
(sg/fmap create-shape)))
(def kaka
[:merge {:title "BoolShape"}
ctsl/schema:layout-child-attrs
schema:bool-attrs
schema:shape-generic-attrs
schema:shape-base-attrs])
(def schema:shape-attrs
[:multi {:dispatch :type
:decode/json (fn [shape]

View File

@@ -175,21 +175,23 @@
[:url :string]])
(def schema:interaction
[:and {:title "Interaction"
:gen/gen (sg/one-of (sg/generator schema:navigate-interaction)
(sg/generator schema:open-overlay-interaction)
(sg/generator schema:close-overlay-interaction)
(sg/generator schema:toggle-overlay-interaction)
(sg/generator schema:prev-scren-interaction)
(sg/generator schema:open-url-interaction))}
schema:interaction-attrs
[:multi {:dispatch :action-type}
[:navigate schema:navigate-interaction]
[:open-overlay schema:open-overlay-interaction]
[:toggle-overlay schema:toggle-overlay-interaction]
[:close-overlay schema:close-overlay-interaction]
[:prev-screen schema:prev-scren-interaction]
[:open-url schema:open-url-interaction]]])
[:schema {:title "Interaction"
:gen/gen (sg/one-of (sg/generator schema:navigate-interaction)
(sg/generator schema:open-overlay-interaction)
(sg/generator schema:close-overlay-interaction)
(sg/generator schema:toggle-overlay-interaction)
(sg/generator schema:prev-scren-interaction)
(sg/generator schema:open-url-interaction))}
[:and
schema:interaction-attrs
[:multi {:dispatch :action-type}
;; [:navigate schema:navigate-interaction]
;; [:open-overlay schema:open-overlay-interaction]
;; [:toggle-overlay schema:toggle-overlay-interaction]
;; [:close-overlay schema:close-overlay-interaction]
;; [:prev-screen schema:prev-scren-interaction]
[:open-url schema:open-url-interaction]
]]])
(sm/register! ::interaction schema:interaction)

View File

@@ -8,6 +8,7 @@
(:require
[app.common.data :as d]
[app.common.schema :as sm]
[app.common.schema.desc-js-like :as smdj]
[clojure.data :as data]
[clojure.set :as set]
[malli.util :as mu]))
@@ -51,7 +52,8 @@
(into #{} (keys token-type->dtcg-token-type)))
(def token-name-ref
[:and :string [:re #"^(?!\$)([a-zA-Z0-9-$_]+\.?)*(?<!\.)$"]])
[:schema {:title "TokenNameRef"}
[:and :string [:re #"^(?!\$)([a-zA-Z0-9-$_]+\.?)*(?<!\.)$"]]])
(def ^:private schema:color
[:map
@@ -61,7 +63,7 @@
(def color-keys (schema-keys schema:color))
(def ^:private schema:border-radius
[:map
[:map {:title "BorderRadiusTokenAttrs"}
[:r1 {:optional true} token-name-ref]
[:r2 {:optional true} token-name-ref]
[:r3 {:optional true} token-name-ref]
@@ -76,7 +78,7 @@
(def stroke-width-keys (schema-keys schema:stroke-width))
(def ^:private schema:sizing
[:map
[:map {:title "SizingTokenAttrs"}
[:width {:optional true} token-name-ref]
[:height {:optional true} token-name-ref]
[:layout-item-min-w {:optional true} token-name-ref]
@@ -87,44 +89,46 @@
(def sizing-keys (schema-keys schema:sizing))
(def ^:private schema:opacity
[:map
[:map {:title "OpacityTokenAttrs"}
[:opacity {:optional true} token-name-ref]])
(def opacity-keys (schema-keys schema:opacity))
(def ^:private schema:spacing-gap
[:map
[:map {:title "SpacingGapTokenAttrs"}
[:row-gap {:optional true} token-name-ref]
[:column-gap {:optional true} token-name-ref]])
(def ^:private schema:spacing-padding
[:map
[:map {:title "SpacingPaddingTokenAttrs"}
[:p1 {:optional true} token-name-ref]
[:p2 {:optional true} token-name-ref]
[:p3 {:optional true} token-name-ref]
[:p4 {:optional true} token-name-ref]])
(def ^:private schema:spacing-margin
[:map
[:map {:title "SpacingMarginTokenAttrs"}
[:m1 {:optional true} token-name-ref]
[:m2 {:optional true} token-name-ref]
[:m3 {:optional true} token-name-ref]
[:m4 {:optional true} token-name-ref]])
(def ^:private schema:spacing
(reduce mu/union [schema:spacing-gap
schema:spacing-padding
schema:spacing-margin]))
(-> (reduce mu/union [schema:spacing-gap
schema:spacing-padding
schema:spacing-margin])
(mu/update-properties assoc :title "SpacingTokenAttrs")))
(def spacing-margin-keys (schema-keys schema:spacing-margin))
(def spacing-keys (schema-keys schema:spacing))
(def ^:private schema:dimensions
(reduce mu/union [schema:sizing
schema:spacing
schema:stroke-width
schema:border-radius]))
(-> (reduce mu/union [schema:sizing
schema:spacing
schema:stroke-width
schema:border-radius])
(mu/update-properties assoc :title "DimensionsTokenAttrs")))
(def dimensions-keys (schema-keys schema:dimensions))
@@ -135,22 +139,20 @@
(def axis-keys (schema-keys schema:axis))
(def ^:private schema:rotation
[:map
[:map {:title "RotationTokenAttrs"}
[:rotation {:optional true} token-name-ref]])
(def rotation-keys (schema-keys schema:rotation))
(def ^:private schema:font-size
[:map
[:map {:title "FontSizeTokenAttrs"}
[:font-size {:optional true} token-name-ref]])
(def font-size-keys (schema-keys schema:font-size))
(def ^:private schema:letter-spacing
[:map
[:map {:title "LetterSpacingTokenAttrs"}
[:letter-spacing {:optional true} token-name-ref]])
(def letter-spacing-keys (schema-keys schema:letter-spacing))
@@ -162,8 +164,9 @@
(def ff-typography-keys (set/difference typography-keys font-size-keys))
(def ^:private schema:number
(reduce mu/union [[:map [:line-height {:optional true} token-name-ref]]
schema:rotation]))
(-> (reduce mu/union [[:map [:line-height {:optional true} token-name-ref]]
schema:rotation])
(mu/update-properties assoc :title "NumberTokenAttrs")))
(def number-keys (schema-keys schema:number))
@@ -180,10 +183,10 @@
number-keys))
(def ^:private schema:tokens
[:map {:title "Applied Tokens"}])
[:map {:title "GenericTokenAttrs"}])
(def schema:applied-tokens
[:merge
[:merge {:title "AppliedTokens"}
schema:tokens
schema:border-radius
schema:sizing

View File

@@ -472,18 +472,17 @@
(get-ordered-set-names [_] "get an ordered sequence of all sets names in the library")
(get-set [_ set-name] "get one set looking for name"))
(def schema:token-set-node
[:schema {:registry {::node [:or [:fn token-set?]
[:and
[:map-of {:gen/max 5} :string [:ref ::node]]
[:fn d/ordered-map?]]]}}
(def ^:private schema:token-set-node
[:schema {:registry {::node
[:or [:fn token-set?]
[:and
[:map-of {:gen/max 5} :string [:ref ::node]]
[:fn d/ordered-map?]]]}}
[:ref ::node]])
(def schema:token-sets
[:and
[:map-of {:title "TokenSets"}
:string
schema:token-set-node]
(def ^:private schema:token-sets
[:and {:title "TokenSets"}
[:map-of :string schema:token-set-node]
[:fn d/ordered-map?]])
(def ^:private check-token-sets

View File

@@ -150,7 +150,16 @@
:class (stl/css :input-field)}]]
[:div {:class (stl/css :editors-cost)}
[:span {:class (stl/css :modal-text-small)}
(tr "subscription.settings.management.dialog.price-month" (or (get-in @form [:clean-data :min-members]) 0))]
(when (> (get-in @form [:clean-data :min-members]) 25)
[:> i18n/tr-html*
{:class (stl/css :modal-text-cap)
:tag-name "span"
:content (tr "subscription.settings.management.dialog.price-month" "175")}])
[:> i18n/tr-html*
{:class (stl/css-case :text-strikethrough (> (get-in @form [:clean-data :min-members]) 25))
:tag-name "span"
:content (tr "subscription.settings.management.dialog.price-month"
(* 7 (or (get-in @form [:clean-data :min-members]) 0)))}]]
[:span {:class (stl/css :modal-text-small)}
(tr "subscription.settings.management.dialog.payment-explanation")]]]

View File

@@ -199,6 +199,20 @@
@include t.use-typography("body-small");
}
.modal-text-cap {
margin-inline-end: var(--sp-s);
}
.text-strikethrough {
text-decoration: line-through;
}
.modal-text-small strong,
.text-strikethrough strong,
.modal-text-cap strong {
font-weight: $fw700;
}
.modal-content,
.modal-end {
color: var(--color-foreground-secondary);

View File

@@ -59,7 +59,7 @@
:type "text"
:on-blur on-submit
:on-key-down on-key-down
:maxlength "256"
:max-length "256"
:auto-focus true
:placeholder (tr "workspace.tokens.set-edit-placeholder")
:default-value default-value}]))
@@ -210,7 +210,7 @@
(mf/defc sets-tree-set*
[{:keys [id set label tree-depth tree-path tree-index is-selected is-active is-draggable is-editing
on-select on-drop on-toggle on-start-edition on-reset-edition on-edit-submit]}]
on-select on-drop on-toggle on-start-edition on-reset-edition on-edit-submit is-new]}]
(let [set-name (ctob/get-name set)
can-edit? (mf/use-ctx ctx/can-edit?)
@@ -239,7 +239,11 @@
:path tree-path})))))
on-double-click
(mf/use-fn (mf/deps id) #(on-start-edition id))
(mf/use-fn
(mf/deps id is-new)
(fn []
(when-not is-new
(on-start-edition id))))
on-checkbox-click
(mf/use-fn
@@ -392,7 +396,7 @@
:is-editing true
:is-active true
:is-selected true
:is-new true
:tree-path path
:tree-depth depth
:tree-index index
@@ -416,6 +420,7 @@
:tree-path path
:tree-depth depth
:tree-index index
:is-new false
:tree-parent-path parent-path
:on-toggle on-toggle-set
:edition-id edition-id

View File

@@ -116,13 +116,17 @@
(let [root? (contains? (:root-shapes options) (:id shape))]
(if (and root? (ctl/any-layout? shape))
:fill
(get-shape-size shape objects :width))))
;; Don't set fixed width for auto-width text shapes
(when-not (and (cfh/text-shape? shape) (= (:grow-type shape) :auto-width))
(get-shape-size shape objects :width)))))
(defmethod get-value :height
[_ shape objects options]
(let [root? (contains? (:root-shapes options) (:id shape))]
(when-not (and root? (ctl/any-layout? shape))
(get-shape-size shape objects :height))))
;; Don't set fixed height for auto-height text shapes
(when-not (and (cfh/text-shape? shape) (= (:grow-type shape) :auto-height))
(get-shape-size shape objects :height)))))
(defmethod get-value :flex-grow
[_ shape _ options]

View File

@@ -4441,8 +4441,10 @@ msgid "subscription.settings.management.dialog.payment-explanation"
msgstr "(No payment will be made now)"
#: src/app/main/ui/settings/subscription.cljs:124
#, markdown
msgid "subscription.settings.management.dialog.price-month"
msgstr "$7 per editor/month x %s"
msgstr ""
"**$%s** per month"
#: src/app/main/ui/settings/subscription.cljs:112
msgid "subscription.settings.management.dialog.select-editors"

View File

@@ -4474,8 +4474,10 @@ msgid "subscription.settings.management.dialog.payment-explanation"
msgstr "(Ahora no se efectuará ningún pago)"
#: src/app/main/ui/settings/subscription.cljs:124
#, markdown
msgid "subscription.settings.management.dialog.price-month"
msgstr "$7 por editor/mes x %s"
msgstr ""
"**$%s** por mes"
#: src/app/main/ui/settings/subscription.cljs:112
msgid "subscription.settings.management.dialog.select-editors"