mirror of
https://github.com/penpot/penpot.git
synced 2026-01-02 03:18:44 -05:00
Compare commits
6 Commits
superalex-
...
staging
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
824ca1bbca | ||
|
|
48e3f35bb3 | ||
|
|
d3ee50daf5 | ||
|
|
de052b5161 | ||
|
|
8a3b33797f | ||
|
|
13fd20f76f |
14
.github/workflows/build-staging-render.yml
vendored
Normal file
14
.github/workflows/build-staging-render.yml
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
name: _STAGING RENDER
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: '36 5-20 * * 1-5'
|
||||
|
||||
jobs:
|
||||
build-bundle:
|
||||
uses: ./.github/workflows/build-bundle.yml
|
||||
secrets: inherit
|
||||
with:
|
||||
gh_ref: "staging-render"
|
||||
build_wasm: "yes"
|
||||
build_storybook: "yes"
|
||||
@@ -1,6 +1,12 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 2.12.0 (Unreleased)
|
||||
## 2.12.1
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
- Fix setting a portion of text as bold or underline messes things up [Github #7980](https://github.com/penpot/penpot/issues/7980)
|
||||
|
||||
## 2.12.0
|
||||
|
||||
### :boom: Breaking changes & Deprecations
|
||||
|
||||
|
||||
@@ -23,30 +23,25 @@ tmux -2 new-session -d -s penpot
|
||||
tmux rename-window -t penpot:0 'frontend watch'
|
||||
tmux select-window -t penpot:0
|
||||
tmux send-keys -t penpot 'cd penpot/frontend' enter C-l
|
||||
tmux send-keys -t penpot 'yarn run watch' enter
|
||||
tmux send-keys -t penpot './scripts/watch app' enter
|
||||
|
||||
tmux new-window -t penpot:1 -n 'frontend shadow'
|
||||
tmux new-window -t penpot:1 -n 'frontend storybook'
|
||||
tmux select-window -t penpot:1
|
||||
tmux send-keys -t penpot 'cd penpot/frontend' enter C-l
|
||||
tmux send-keys -t penpot 'yarn run watch:app' enter
|
||||
tmux send-keys -t penpot './scripts/watch storybook' enter
|
||||
|
||||
tmux new-window -t penpot:2 -n 'frontend storybook'
|
||||
tmux new-window -t penpot:2 -n 'exporter'
|
||||
tmux select-window -t penpot:2
|
||||
tmux send-keys -t penpot 'cd penpot/frontend' enter C-l
|
||||
tmux send-keys -t penpot 'yarn run watch:storybook' enter
|
||||
|
||||
tmux new-window -t penpot:3 -n 'exporter'
|
||||
tmux select-window -t penpot:3
|
||||
tmux send-keys -t penpot 'cd penpot/exporter' enter C-l
|
||||
tmux send-keys -t penpot 'rm -f target/app.js*' enter C-l
|
||||
tmux send-keys -t penpot 'yarn run watch' enter
|
||||
tmux send-keys -t penpot './scripts/watch' enter
|
||||
|
||||
tmux split-window -v
|
||||
tmux send-keys -t penpot 'cd penpot/exporter' enter C-l
|
||||
tmux send-keys -t penpot './scripts/wait-and-start.sh' enter
|
||||
|
||||
tmux new-window -t penpot:4 -n 'backend'
|
||||
tmux select-window -t penpot:4
|
||||
tmux new-window -t penpot:3 -n 'backend'
|
||||
tmux select-window -t penpot:3
|
||||
tmux send-keys -t penpot 'cd penpot/backend' enter C-l
|
||||
tmux send-keys -t penpot './scripts/start-dev' enter
|
||||
|
||||
|
||||
@@ -30,8 +30,8 @@
|
||||
},
|
||||
"scripts": {
|
||||
"clear:shadow-cache": "rm -rf .shadow-cljs && rm -rf target",
|
||||
"watch:app": "clojure -M:dev:shadow-cljs watch main",
|
||||
"watch": "yarn run clear:shadow-cache && yarn run watch:app",
|
||||
"watch:app": "yarn run clear:shadow-cache && clojure -M:dev:shadow-cljs watch main",
|
||||
"watch": "yarn run watch:app",
|
||||
"build:app": "clojure -M:dev:shadow-cljs release main",
|
||||
"build": "yarn run clear:shadow-cache && yarn run build:app",
|
||||
"fmt:clj:check": "cljfmt check --parallel=false src/",
|
||||
|
||||
7
exporter/scripts/watch
Executable file
7
exporter/scripts/watch
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
TARGET=${1:-app};
|
||||
|
||||
set -ex
|
||||
|
||||
exec yarn run watch:$TARGET
|
||||
@@ -47,10 +47,9 @@
|
||||
"watch:app:libs": "node ./scripts/build-libs.js --watch",
|
||||
"watch:app:main": "clojure -M:dev:shadow-cljs watch main worker storybook",
|
||||
"clear:shadow-cache": "rm -rf .shadow-cljs",
|
||||
"watch:app": "yarn run clear:shadow-cache && concurrently \"yarn run watch:app:main\" \"yarn run watch:app:libs\"",
|
||||
"watch": "yarn run watch:app:assets",
|
||||
"watch:storybook": "yarn run build:storybook:assets && concurrently \"storybook dev -p 6006 --no-open\" \"yarn run watch:storybook:assets\"",
|
||||
"watch:storybook:assets": "node ./scripts/watch-storybook.js"
|
||||
"watch": "exit 0",
|
||||
"watch:app": "yarn run clear:shadow-cache && concurrently --kill-others-on-fail \"yarn run watch:app:assets\" \"yarn run watch:app:main\" \"yarn run watch:app:libs\"",
|
||||
"watch:storybook": "yarn run build:storybook:assets && concurrently --kill-others-on-fail \"storybook dev -p 6006 --no-open\" \"node ./scripts/watch-storybook.js\""
|
||||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "1.52.0",
|
||||
|
||||
@@ -73,7 +73,7 @@ export function isJsFile(path) {
|
||||
export async function compileSass(worker, path, options) {
|
||||
path = ph.resolve(path);
|
||||
|
||||
log.info("compile:", path);
|
||||
// log.info("compile:", path);
|
||||
return worker.exec("compileSass", [path, options]);
|
||||
}
|
||||
|
||||
|
||||
7
frontend/scripts/watch
Executable file
7
frontend/scripts/watch
Executable file
@@ -0,0 +1,7 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
TARGET=${1:-app};
|
||||
|
||||
set -ex
|
||||
|
||||
exec yarn run watch:$TARGET
|
||||
@@ -50,7 +50,8 @@
|
||||
touched? (and (contains? (:data @form) input-name)
|
||||
(get-in @form [:touched input-name]))
|
||||
|
||||
error (get-in @form [:errors input-name])
|
||||
error (or (get-in @form [:errors input-name])
|
||||
(get-in @form [:extra-errors input-name]))
|
||||
|
||||
value (get-in @form [:data input-name] "")
|
||||
|
||||
|
||||
@@ -18,16 +18,18 @@
|
||||
|
||||
(defn- on-error
|
||||
[form error]
|
||||
(case (:code (ex-data error))
|
||||
:old-password-not-match
|
||||
(swap! form assoc-in [:errors :password-old]
|
||||
{:message (tr "errors.wrong-old-password")})
|
||||
:email-as-password
|
||||
(swap! form assoc-in [:errors :password-1]
|
||||
{:message (tr "errors.email-as-password")})
|
||||
(let [data (ex-data error)]
|
||||
(case (:code data)
|
||||
:old-password-not-match
|
||||
(swap! form assoc-in [:extra-errors :password-old]
|
||||
{:message (tr "errors.wrong-old-password")})
|
||||
|
||||
(let [msg (tr "generic.error")]
|
||||
(st/emit! (ntf/error msg)))))
|
||||
:email-as-password
|
||||
(swap! form assoc-in [:extra-errors :password-1]
|
||||
{:message (tr "errors.email-as-password")})
|
||||
|
||||
(let [msg (tr "generic.error")]
|
||||
(st/emit! (ntf/error msg))))))
|
||||
|
||||
(defn- on-success
|
||||
[form]
|
||||
|
||||
@@ -106,9 +106,11 @@
|
||||
:overflowWrap "initial"
|
||||
:lineBreak "auto"
|
||||
:whiteSpace "break-spaces"
|
||||
:textRendering "geometricPrecision"
|
||||
:display "inline-block"
|
||||
:verticalAlign "top"}
|
||||
:textRendering "geometricPrecision"}
|
||||
base (cond-> base
|
||||
(= (:line-height data) "0")
|
||||
(-> (obj/set! "display" "inline-block")
|
||||
(obj/set! "verticalAlign" "top")))
|
||||
fills
|
||||
(cond
|
||||
;; DEPRECATED: still here for backward compatibility with
|
||||
|
||||
@@ -48,7 +48,11 @@
|
||||
(let [props (m/properties schema)
|
||||
tprops (m/type-properties schema)
|
||||
field (or (first in)
|
||||
(:error/field props))]
|
||||
(:error/field props))
|
||||
|
||||
field (if (vector? field)
|
||||
field
|
||||
[field])]
|
||||
|
||||
(if (contains? acc field)
|
||||
acc
|
||||
@@ -58,30 +62,30 @@
|
||||
|
||||
(or (= type :malli.core/missing-key)
|
||||
(nil? value))
|
||||
(assoc acc field {:message (tr "errors.field-missing")})
|
||||
(assoc-in acc field {:message (tr "errors.field-missing")})
|
||||
|
||||
;; --- CHECK on schema props
|
||||
(contains? props :error/fn)
|
||||
(assoc acc field (handle-error-fn props problem))
|
||||
(assoc-in acc field (handle-error-fn props problem))
|
||||
|
||||
(contains? props :error/message)
|
||||
(assoc acc field (handle-error-message props))
|
||||
(assoc-in acc field (handle-error-message props))
|
||||
|
||||
(contains? props :error/code)
|
||||
(assoc acc field (handle-error-code props))
|
||||
(assoc-in acc field (handle-error-code props))
|
||||
|
||||
;; --- CHECK on type props
|
||||
(contains? tprops :error/fn)
|
||||
(assoc acc field (handle-error-fn tprops problem))
|
||||
(assoc-in acc field (handle-error-fn tprops problem))
|
||||
|
||||
(contains? tprops :error/message)
|
||||
(assoc acc field (handle-error-message tprops))
|
||||
(assoc-in acc field (handle-error-message tprops))
|
||||
|
||||
(contains? tprops :error/code)
|
||||
(assoc acc field (handle-error-code tprops))
|
||||
(assoc-in acc field (handle-error-code tprops))
|
||||
|
||||
:else
|
||||
(assoc acc field {:message (tr "errors.invalid-data")})))))
|
||||
(assoc-in acc field {:message (tr "errors.invalid-data")})))))
|
||||
|
||||
(defn- use-rerender-fn
|
||||
[]
|
||||
@@ -114,20 +118,35 @@
|
||||
[f {:keys [schema validators]}]
|
||||
(fn [& args]
|
||||
(let [state (apply f args)
|
||||
cleaned (sm/decode schema (:data state) sm/string-transformer)
|
||||
cleaned (sm/decode schema (:data state) sm/json-transformer)
|
||||
valid? (sm/validate schema cleaned)
|
||||
errors (when-not valid?
|
||||
(collect-schema-errors schema validators state))]
|
||||
|
||||
errors
|
||||
(when-not valid?
|
||||
(collect-schema-errors schema validators state))
|
||||
|
||||
extra-errors
|
||||
(not-empty (:extra-errors state))]
|
||||
|
||||
(assoc state
|
||||
:errors errors
|
||||
:clean-data (when valid? cleaned)
|
||||
:valid (and (not errors) valid?)))))
|
||||
:valid (and (not errors)
|
||||
(not extra-errors)
|
||||
valid?)))))
|
||||
|
||||
|
||||
(defn- make-initial-state
|
||||
[initial-data]
|
||||
(let [initial (if (fn? initial-data) (initial-data) initial-data)
|
||||
initial (d/nilv initial {})]
|
||||
{:initial initial
|
||||
:data initial
|
||||
:errors {}
|
||||
:touched {}}))
|
||||
|
||||
(defn- create-form-mutator
|
||||
[internal-state rerender-fn wrap-update-fn initial opts]
|
||||
(mf/set-ref-val! internal-state initial)
|
||||
|
||||
[internal-state rerender-fn wrap-update-fn opts]
|
||||
(reify
|
||||
IDeref
|
||||
(-deref [_]
|
||||
@@ -136,7 +155,10 @@
|
||||
IReset
|
||||
(-reset! [_ new-value]
|
||||
(if (nil? new-value)
|
||||
(mf/set-ref-val! internal-state (if (fn? initial) (initial) initial))
|
||||
(let [initial (-> (mf/ref-val internal-state)
|
||||
(get :initial)
|
||||
(make-initial-state))]
|
||||
(mf/set-ref-val! internal-state initial))
|
||||
(mf/set-ref-val! internal-state new-value))
|
||||
(rerender-fn))
|
||||
|
||||
@@ -162,24 +184,25 @@
|
||||
(rerender-fn)))))
|
||||
|
||||
(defn use-form
|
||||
[& {:keys [initial] :as opts}]
|
||||
[& {:keys [initial schema validators] :as opts}]
|
||||
(let [rerender-fn (use-rerender-fn)
|
||||
|
||||
initial
|
||||
(mf/with-memo [initial]
|
||||
{:data (if (fn? initial) (initial) initial)
|
||||
:errors {}
|
||||
:touched {}})
|
||||
(make-initial-state initial))
|
||||
|
||||
internal-state
|
||||
(mf/use-ref nil)
|
||||
(mf/use-ref initial)
|
||||
|
||||
form-mutator
|
||||
(mf/with-memo [initial]
|
||||
(create-form-mutator internal-state rerender-fn wrap-update-schema-fn initial opts))]
|
||||
(mf/with-memo [schema validators]
|
||||
(let [mutator (create-form-mutator internal-state rerender-fn wrap-update-schema-fn
|
||||
(select-keys opts [:schema :validators]))]
|
||||
(swap! mutator identity)
|
||||
mutator))]
|
||||
|
||||
;; Initialize internal state once
|
||||
(mf/with-layout-effect []
|
||||
(mf/with-effect []
|
||||
(mf/set-ref-val! internal-state initial))
|
||||
|
||||
(mf/with-effect [initial]
|
||||
@@ -191,11 +214,16 @@
|
||||
([form field value]
|
||||
(on-input-change form field value false))
|
||||
([form field value trim?]
|
||||
(swap! form (fn [state]
|
||||
(-> state
|
||||
(assoc-in [:touched field] true)
|
||||
(assoc-in [:data field] (if trim? (str/trim value) value))
|
||||
(update :errors dissoc field))))))
|
||||
(letfn [(clean-errors [errors]
|
||||
(-> errors
|
||||
(dissoc field)
|
||||
(not-empty)))]
|
||||
(swap! form (fn [state]
|
||||
(-> state
|
||||
(assoc-in [:touched field] true)
|
||||
(assoc-in [:data field] (if trim? (str/trim value) value))
|
||||
(update :errors clean-errors)
|
||||
(update :extra-errors clean-errors)))))))
|
||||
|
||||
(defn update-input-value!
|
||||
[form field value]
|
||||
|
||||
Reference in New Issue
Block a user