mirror of
https://github.com/penpot/penpot.git
synced 2025-05-20 14:06:10 +02:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
9e3f8e7827
7 changed files with 218 additions and 60 deletions
|
@ -476,7 +476,7 @@
|
||||||
::oapi/type "string"
|
::oapi/type "string"
|
||||||
::oapi/format "email"}})
|
::oapi/format "email"}})
|
||||||
|
|
||||||
(def non-empty-strings-xf
|
(def xf:filter-word-strings
|
||||||
(comp
|
(comp
|
||||||
(filter string?)
|
(filter string?)
|
||||||
(remove str/empty?)
|
(remove str/empty?)
|
||||||
|
@ -489,11 +489,8 @@
|
||||||
:min 0
|
:min 0
|
||||||
:max 1
|
:max 1
|
||||||
:compile
|
:compile
|
||||||
(fn [{:keys [coerce kind max min] :as props} children _]
|
(fn [{:keys [kind max min] :as props} children _]
|
||||||
(let [xform (if coerce
|
(let [kind (or (last children) kind)
|
||||||
(comp non-empty-strings-xf (map coerce))
|
|
||||||
non-empty-strings-xf)
|
|
||||||
kind (or (last children) kind)
|
|
||||||
|
|
||||||
pred
|
pred
|
||||||
(cond
|
(cond
|
||||||
|
@ -501,9 +498,6 @@
|
||||||
(nil? kind) any?
|
(nil? kind) any?
|
||||||
:else (validator kind))
|
:else (validator kind))
|
||||||
|
|
||||||
encode-child
|
|
||||||
(encoder kind string-transformer)
|
|
||||||
|
|
||||||
pred
|
pred
|
||||||
(cond
|
(cond
|
||||||
(and max min)
|
(and max min)
|
||||||
|
@ -531,31 +525,49 @@
|
||||||
(fn [value]
|
(fn [value]
|
||||||
(every? pred value)))
|
(every? pred value)))
|
||||||
|
|
||||||
decode
|
|
||||||
|
decode-string-child
|
||||||
|
(decoder kind string-transformer)
|
||||||
|
|
||||||
|
decode-string
|
||||||
(fn [v]
|
(fn [v]
|
||||||
(let [v (if (string? v) (str/split v #"[\s,]+") v)]
|
(let [v (if (string? v) (str/split v #"[\s,]+") v)
|
||||||
(into #{} xform v)))
|
x (comp xf:filter-word-strings (map decode-string-child))]
|
||||||
|
(into #{} x v)))
|
||||||
|
|
||||||
|
decode-json-child
|
||||||
|
(decoder kind json-transformer)
|
||||||
|
|
||||||
|
decode-json
|
||||||
|
(fn [v]
|
||||||
|
(let [v (if (string? v) (str/split v #"[\s,]+") v)
|
||||||
|
x (comp xf:filter-word-strings (map decode-json-child))]
|
||||||
|
(into #{} x v)))
|
||||||
|
|
||||||
|
encode-string-child
|
||||||
|
(encoder kind string-transformer)
|
||||||
|
|
||||||
|
encode-string
|
||||||
|
(fn [o]
|
||||||
|
(if (set? o)
|
||||||
|
(str/join ", " (map encode-string-child o))
|
||||||
|
o))
|
||||||
|
|
||||||
encode-json
|
encode-json
|
||||||
(fn [o]
|
(fn [o]
|
||||||
(if (set? o)
|
(if (set? o)
|
||||||
(vec o)
|
(vec o)
|
||||||
o))
|
|
||||||
|
|
||||||
encode-string
|
|
||||||
(fn [o]
|
|
||||||
(if (set? o)
|
|
||||||
(str/join ", " (map encode-child o))
|
|
||||||
o))]
|
o))]
|
||||||
|
|
||||||
|
|
||||||
{:pred pred
|
{:pred pred
|
||||||
:type-properties
|
:type-properties
|
||||||
{:title "set"
|
{:title "set"
|
||||||
:description "Set of Strings"
|
:description "Set of Strings"
|
||||||
:error/message "should be a set of strings"
|
:error/message "should be a set of strings"
|
||||||
:gen/gen (-> kind sg/generator sg/set)
|
:gen/gen (-> kind sg/generator sg/set)
|
||||||
:decode/string decode
|
:decode/string decode-string
|
||||||
:decode/json decode
|
:decode/json decode-json
|
||||||
:encode/string encode-string
|
:encode/string encode-string
|
||||||
:encode/json encode-json
|
:encode/json encode-json
|
||||||
::oapi/type "array"
|
::oapi/type "array"
|
||||||
|
@ -569,21 +581,14 @@
|
||||||
:min 0
|
:min 0
|
||||||
:max 1
|
:max 1
|
||||||
:compile
|
:compile
|
||||||
(fn [{:keys [coerce kind max min] :as props} children _]
|
(fn [{:keys [kind max min] :as props} children _]
|
||||||
(let [xform (if coerce
|
(let [kind (or (last children) kind)
|
||||||
(comp non-empty-strings-xf (map coerce))
|
|
||||||
non-empty-strings-xf)
|
|
||||||
|
|
||||||
kind (or (last children) kind)
|
|
||||||
pred
|
pred
|
||||||
(cond
|
(cond
|
||||||
(fn? kind) kind
|
(fn? kind) kind
|
||||||
(nil? kind) any?
|
(nil? kind) any?
|
||||||
:else (validator kind))
|
:else (validator kind))
|
||||||
|
|
||||||
encode-child
|
|
||||||
(encoder kind string-transformer)
|
|
||||||
|
|
||||||
pred
|
pred
|
||||||
(cond
|
(cond
|
||||||
(and max min)
|
(and max min)
|
||||||
|
@ -611,15 +616,31 @@
|
||||||
(fn [value]
|
(fn [value]
|
||||||
(every? pred value)))
|
(every? pred value)))
|
||||||
|
|
||||||
decode
|
decode-string-child
|
||||||
|
(decoder kind string-transformer)
|
||||||
|
|
||||||
|
decode-json-child
|
||||||
|
(decoder kind json-transformer)
|
||||||
|
|
||||||
|
decode-string
|
||||||
(fn [v]
|
(fn [v]
|
||||||
(let [v (if (string? v) (str/split v #"[\s,]+") v)]
|
(let [v (if (string? v) (str/split v #"[\s,]+") v)
|
||||||
(into [] xform v)))
|
x (comp xf:filter-word-strings (map decode-string-child))]
|
||||||
|
(into #{} x v)))
|
||||||
|
|
||||||
|
decode-json
|
||||||
|
(fn [v]
|
||||||
|
(let [v (if (string? v) (str/split v #"[\s,]+") v)
|
||||||
|
x (comp xf:filter-word-strings (map decode-json-child))]
|
||||||
|
(into #{} x v)))
|
||||||
|
|
||||||
|
encode-string-child
|
||||||
|
(encoder kind string-transformer)
|
||||||
|
|
||||||
encode-string
|
encode-string
|
||||||
(fn [o]
|
(fn [o]
|
||||||
(if (vector? o)
|
(if (vector? o)
|
||||||
(str/join ", " (map encode-child o))
|
(str/join ", " (map encode-string-child o))
|
||||||
o))]
|
o))]
|
||||||
|
|
||||||
{:pred pred
|
{:pred pred
|
||||||
|
@ -628,8 +649,8 @@
|
||||||
:description "Set of Strings"
|
:description "Set of Strings"
|
||||||
:error/message "should be a set of strings"
|
:error/message "should be a set of strings"
|
||||||
:gen/gen (-> kind sg/generator sg/set)
|
:gen/gen (-> kind sg/generator sg/set)
|
||||||
:decode/string decode
|
:decode/string decode-string
|
||||||
:decode/json decode
|
:decode/json decode-json
|
||||||
:encode/string encode-string
|
:encode/string encode-string
|
||||||
::oapi/type "array"
|
::oapi/type "array"
|
||||||
::oapi/format "set"
|
::oapi/format "set"
|
||||||
|
@ -646,7 +667,7 @@
|
||||||
:gen/gen (-> :string sg/generator sg/set)
|
:gen/gen (-> :string sg/generator sg/set)
|
||||||
:decode/string (fn [v]
|
:decode/string (fn [v]
|
||||||
(let [v (if (string? v) (str/split v #"[\s,]+") v)]
|
(let [v (if (string? v) (str/split v #"[\s,]+") v)]
|
||||||
(into #{} non-empty-strings-xf v)))
|
(into #{} xf:filter-word-strings v)))
|
||||||
::oapi/type "array"
|
::oapi/type "array"
|
||||||
::oapi/format "set"
|
::oapi/format "set"
|
||||||
::oapi/items {:type "string"}
|
::oapi/items {:type "string"}
|
||||||
|
@ -662,7 +683,7 @@
|
||||||
:gen/gen (-> :keyword sg/generator sg/set)
|
:gen/gen (-> :keyword sg/generator sg/set)
|
||||||
:decode/string (fn [v]
|
:decode/string (fn [v]
|
||||||
(let [v (if (string? v) (str/split v #"[\s,]+") v)]
|
(let [v (if (string? v) (str/split v #"[\s,]+") v)]
|
||||||
(into #{} (comp non-empty-strings-xf (map keyword)) v)))
|
(into #{} (comp xf:filter-word-strings (map keyword)) v)))
|
||||||
::oapi/type "array"
|
::oapi/type "array"
|
||||||
::oapi/format "set"
|
::oapi/format "set"
|
||||||
::oapi/items {:type "string" :format "keyword"}
|
::oapi/items {:type "string" :format "keyword"}
|
||||||
|
|
|
@ -26,16 +26,24 @@
|
||||||
|
|
||||||
(def ^:private
|
(def ^:private
|
||||||
schema:config
|
schema:config
|
||||||
(sm/define
|
|
||||||
[:map {:title "config"}
|
[:map {:title "config"}
|
||||||
[:public-uri {:optional true} ::sm/uri]
|
[:public-uri {:optional true} ::sm/uri]
|
||||||
[:host {:optional true} :string]
|
[:host {:optional true} :string]
|
||||||
[:tenant {:optional true} :string]
|
[:tenant {:optional true} :string]
|
||||||
[:flags {:optional true} ::sm/set-of-keywords]
|
[:flags {:optional true} [::sm/set :keyword]]
|
||||||
[:redis-uri {:optional true} :string]
|
[:redis-uri {:optional true} :string]
|
||||||
[:tempdir {:optional true} :string]
|
[:tempdir {:optional true} :string]
|
||||||
[:browser-pool-max {:optional true} :int]
|
[:browser-pool-max {:optional true} ::sm/int]
|
||||||
[:browser-pool-min {:optional true} :int]]))
|
[:browser-pool-min {:optional true} ::sm/int]])
|
||||||
|
|
||||||
|
(def ^:private decode-config
|
||||||
|
(sm/decoder schema:config sm/string-transformer))
|
||||||
|
|
||||||
|
(def ^:private explain-config
|
||||||
|
(sm/explainer schema:config))
|
||||||
|
|
||||||
|
(def ^:private valid-config?
|
||||||
|
(sm/validator schema:config))
|
||||||
|
|
||||||
(defn- parse-flags
|
(defn- parse-flags
|
||||||
[config]
|
[config]
|
||||||
|
@ -60,15 +68,15 @@
|
||||||
[]
|
[]
|
||||||
(let [env (read-env "penpot")
|
(let [env (read-env "penpot")
|
||||||
env (d/without-nils env)
|
env (d/without-nils env)
|
||||||
data (merge defaults env)]
|
data (merge defaults env)
|
||||||
|
data (decode-config data)]
|
||||||
|
|
||||||
(try
|
(when-not (valid-config? data)
|
||||||
(sm/conform! schema:config data)
|
(let [explain (explain-config data)]
|
||||||
(catch :default cause
|
|
||||||
(if-let [explain (some->> cause ex-data ::sm/explain)]
|
|
||||||
(println (sm/humanize-explain explain))
|
(println (sm/humanize-explain explain))
|
||||||
(js/console.error cause))
|
(process/exit -1)))
|
||||||
(process/exit -1)))))
|
|
||||||
|
data))
|
||||||
|
|
||||||
(def config
|
(def config
|
||||||
(prepare-config))
|
(prepare-config))
|
||||||
|
|
|
@ -217,9 +217,9 @@
|
||||||
[:team-size
|
[:team-size
|
||||||
[:enum "more-than-50" "31-50" "11-30" "2-10" "freelancer" "personal-project"]]
|
[:enum "more-than-50" "31-50" "11-30" "2-10" "freelancer" "personal-project"]]
|
||||||
[:role
|
[:role
|
||||||
[:enum "designer" "developer" "student-teacher" "graphic-design" "marketing" "manager" "other"]]
|
[:enum "ux" "developer" "student-teacher" "designer" "marketing" "manager" "other"]]
|
||||||
[:responsability
|
[:responsability
|
||||||
[:enum "team-leader" "team-member" "freelancer" "ceo-founder" "director" "student-teacher" "other"]]
|
[:enum "team-leader" "team-member" "freelancer" "ceo-founder" "director" "other"]]
|
||||||
|
|
||||||
[:role-other {:optional true} [::sm/text {:max 512}]]
|
[:role-other {:optional true} [::sm/text {:max 512}]]
|
||||||
[:responsability-other {:optional true} [::sm/text {:max 512}]]]
|
[:responsability-other {:optional true} [::sm/text {:max 512}]]]
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
[app.main.ui.releases.v1-9]
|
[app.main.ui.releases.v1-9]
|
||||||
[app.main.ui.releases.v2-0]
|
[app.main.ui.releases.v2-0]
|
||||||
[app.main.ui.releases.v2-1]
|
[app.main.ui.releases.v2-1]
|
||||||
|
[app.main.ui.releases.v2-2]
|
||||||
[app.util.object :as obj]
|
[app.util.object :as obj]
|
||||||
[app.util.timers :as tm]
|
[app.util.timers :as tm]
|
||||||
[rumext.v2 :as mf]))
|
[rumext.v2 :as mf]))
|
||||||
|
@ -92,4 +93,4 @@
|
||||||
|
|
||||||
(defmethod rc/render-release-notes "0.0"
|
(defmethod rc/render-release-notes "0.0"
|
||||||
[params]
|
[params]
|
||||||
(rc/render-release-notes (assoc params :version "2.1")))
|
(rc/render-release-notes (assoc params :version "2.2")))
|
||||||
|
|
51
frontend/src/app/main/ui/releases/v2_2.cljs
Normal file
51
frontend/src/app/main/ui/releases/v2_2.cljs
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
;; 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 app.main.ui.releases.v2-2
|
||||||
|
(:require-macros [app.main.style :as stl])
|
||||||
|
(:require
|
||||||
|
[app.common.data.macros :as dm]
|
||||||
|
[app.main.ui.releases.common :as c]
|
||||||
|
[rumext.v2 :as mf]))
|
||||||
|
|
||||||
|
(defmethod c/render-release-notes "2.2"
|
||||||
|
[{:keys [slide klass finish version]}]
|
||||||
|
(mf/html
|
||||||
|
(case slide
|
||||||
|
:start
|
||||||
|
[:div {:class (stl/css-case :modal-overlay true)}
|
||||||
|
[:div.animated {:class klass}
|
||||||
|
[:div {:class (stl/css :modal-container)}
|
||||||
|
[:img {:src "images/features/2.0-intro-image.png"
|
||||||
|
:class (stl/css :start-image)
|
||||||
|
:border "0"
|
||||||
|
:alt "A graphic illustration with Penpot style"}]
|
||||||
|
|
||||||
|
[:div {:class (stl/css :modal-content)}
|
||||||
|
[:div {:class (stl/css :modal-header)}
|
||||||
|
[:h1 {:class (stl/css :modal-title)}
|
||||||
|
"What's new in Penpot? "]
|
||||||
|
|
||||||
|
[:div {:class (stl/css :version-tag)}
|
||||||
|
(dm/str "Version " version)]]
|
||||||
|
|
||||||
|
[:div {:class (stl/css :features-block)}
|
||||||
|
[:p {:class (stl/css :feature-content)}
|
||||||
|
"This Penpot 2.2 release focuses on internal changes that are laying out the ground for the upcoming plugin system and substantial performance improvements."]
|
||||||
|
|
||||||
|
[:p {:class (stl/css :feature-content)}
|
||||||
|
"This version also adds full JSON API interoperability and the brand-new Penpot’s Storybook!"]
|
||||||
|
|
||||||
|
[:p {:class (stl/css :feature-content)}
|
||||||
|
"Self-hosted Penpot installations will benefit from better file data storage and Penpot admins can now use the improved automatic snapshotting process when recovering old files."]
|
||||||
|
|
||||||
|
[:p {:class (stl/css :feature-content)}
|
||||||
|
"Thanks again to our awesome community for their amazing contributions to this release!"]]
|
||||||
|
|
||||||
|
[:div {:class (stl/css :navigation)}
|
||||||
|
[:button {:class (stl/css :next-btn)
|
||||||
|
:on-click finish} "Let's go"]]]]]])))
|
||||||
|
|
79
frontend/src/app/main/ui/releases/v2_2.scss
Normal file
79
frontend/src/app/main/ui/releases/v2_2.scss
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
// 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
|
||||||
|
|
||||||
|
@import "refactor/common-refactor.scss";
|
||||||
|
|
||||||
|
.modal-overlay {
|
||||||
|
@extend .modal-overlay-base;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-container {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: $s-324 1fr;
|
||||||
|
height: $s-480;
|
||||||
|
width: $s-888;
|
||||||
|
border-radius: $br-8;
|
||||||
|
background-color: var(--modal-background-color);
|
||||||
|
border: $s-2 solid var(--modal-border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.start-image {
|
||||||
|
width: $s-324;
|
||||||
|
border-radius: $br-8 0 0 $br-8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content {
|
||||||
|
padding: $s-40;
|
||||||
|
display: grid;
|
||||||
|
grid-template-rows: auto 1fr $s-32;
|
||||||
|
gap: $s-24;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-header {
|
||||||
|
display: grid;
|
||||||
|
gap: $s-8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.version-tag {
|
||||||
|
@include flexCenter;
|
||||||
|
@include headlineSmallTypography;
|
||||||
|
height: $s-32;
|
||||||
|
width: $s-96;
|
||||||
|
background-color: var(--communication-tag-background-color);
|
||||||
|
color: var(--communication-tag-foreground-color);
|
||||||
|
border-radius: $br-8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-title {
|
||||||
|
@include headlineLargeTypography;
|
||||||
|
color: var(--modal-title-foreground-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.features-block {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: $s-16;
|
||||||
|
width: $s-440;
|
||||||
|
}
|
||||||
|
|
||||||
|
.feature-content {
|
||||||
|
@include bodyMediumTypography;
|
||||||
|
margin: 0;
|
||||||
|
color: var(--modal-text-foreground-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.navigation {
|
||||||
|
width: 100%;
|
||||||
|
display: grid;
|
||||||
|
grid-template-areas: "bullets button";
|
||||||
|
}
|
||||||
|
|
||||||
|
.next-btn {
|
||||||
|
@extend .button-primary;
|
||||||
|
width: $s-100;
|
||||||
|
justify-self: flex-end;
|
||||||
|
grid-area: button;
|
||||||
|
}
|
|
@ -199,7 +199,6 @@
|
||||||
.height {
|
.height {
|
||||||
@extend .input-element;
|
@extend .input-element;
|
||||||
@include bodySmallTypography;
|
@include bodySmallTypography;
|
||||||
width: $s-108;
|
|
||||||
.icon-text {
|
.icon-text {
|
||||||
padding-top: $s-1;
|
padding-top: $s-1;
|
||||||
}
|
}
|
||||||
|
@ -208,7 +207,6 @@
|
||||||
.margin {
|
.margin {
|
||||||
@extend .input-element;
|
@extend .input-element;
|
||||||
@include bodySmallTypography;
|
@include bodySmallTypography;
|
||||||
width: $s-108;
|
|
||||||
.icon {
|
.icon {
|
||||||
&.rotated svg {
|
&.rotated svg {
|
||||||
transform: rotate(90deg);
|
transform: rotate(90deg);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue