mirror of
https://github.com/penpot/penpot.git
synced 2025-05-24 22:26:12 +02:00
Merge remote-tracking branch 'origin/staging' into develop
This commit is contained in:
commit
07881eed65
18 changed files with 92 additions and 84 deletions
|
@ -11,6 +11,7 @@ jobs:
|
||||||
- image: cimg/redis:6.2.6
|
- image: cimg/redis:6.2.6
|
||||||
|
|
||||||
working_directory: ~/repo
|
working_directory: ~/repo
|
||||||
|
resource_class: large
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
# Customize the JVM maximum heap limit
|
# Customize the JVM maximum heap limit
|
||||||
|
|
|
@ -38,6 +38,9 @@
|
||||||
:single-key-in
|
:single-key-in
|
||||||
{:level :warning}
|
{:level :warning}
|
||||||
|
|
||||||
|
:non-arg-vec-return-type-hint
|
||||||
|
{:level :off}
|
||||||
|
|
||||||
:redundant-do
|
:redundant-do
|
||||||
{:level :off}
|
{:level :off}
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
|
|
||||||
### :bug: Bugs fixed
|
### :bug: Bugs fixed
|
||||||
|
|
||||||
|
- Fix shortcut access in main menu [Taiga #3672](https://tree.taiga.io/project/penpot/issue/3672)
|
||||||
|
- Fix modify colors in a row in selected colors [Taiga #3653](https://tree.taiga.io/project/penpot/issue/3653)
|
||||||
- Fix crash when double click on viewer assets [Taiga #3625](https://tree.taiga.io/project/penpot/issue/3625)
|
- Fix crash when double click on viewer assets [Taiga #3625](https://tree.taiga.io/project/penpot/issue/3625)
|
||||||
- Fix right click on typographies assets [Taiga #3638](https://tree.taiga.io/project/penpot/issue/3638)
|
- Fix right click on typographies assets [Taiga #3638](https://tree.taiga.io/project/penpot/issue/3638)
|
||||||
|
|
||||||
|
|
|
@ -51,7 +51,7 @@
|
||||||
(defn profile->props
|
(defn profile->props
|
||||||
[profile]
|
[profile]
|
||||||
(-> profile
|
(-> profile
|
||||||
(select-keys [:is-active :is-muted :auth-backend :email :default-team-id :default-project-id :fullname :lang])
|
(select-keys [:id :is-active :is-muted :auth-backend :email :default-team-id :default-project-id :fullname :lang])
|
||||||
(merge (:props profile))
|
(merge (:props profile))
|
||||||
(d/without-nils)))
|
(d/without-nils)))
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,6 @@
|
||||||
|
|
||||||
(ns app.rpc
|
(ns app.rpc
|
||||||
(:require
|
(:require
|
||||||
[app.common.data :as d]
|
|
||||||
[app.common.exceptions :as ex]
|
[app.common.exceptions :as ex]
|
||||||
[app.common.logging :as l]
|
[app.common.logging :as l]
|
||||||
[app.common.spec :as us]
|
[app.common.spec :as us]
|
||||||
|
@ -132,10 +131,13 @@
|
||||||
(fn [result _]
|
(fn [result _]
|
||||||
(when result
|
(when result
|
||||||
(let [resultm (meta result)
|
(let [resultm (meta result)
|
||||||
profile-id (or (:profile-id params)
|
profile-id (or (::audit/profile-id resultm)
|
||||||
(:profile-id result)
|
(:profile-id result)
|
||||||
(::audit/profile-id resultm))
|
(:profile-id params))
|
||||||
props (d/merge params (::audit/props resultm))]
|
props (or (::audit/replace-props resultm)
|
||||||
|
(-> params
|
||||||
|
(merge (::audit/props resultm))
|
||||||
|
(dissoc :type)))]
|
||||||
(audit :cmd :submit
|
(audit :cmd :submit
|
||||||
:type (or (::audit/type resultm)
|
:type (or (::audit/type resultm)
|
||||||
(::type cfg))
|
(::type cfg))
|
||||||
|
|
|
@ -137,7 +137,8 @@
|
||||||
:exp (dt/in-future "48h")}
|
:exp (dt/in-future "48h")}
|
||||||
|
|
||||||
token (tokens :generate params)]
|
token (tokens :generate params)]
|
||||||
{:token token}))
|
(with-meta {:token token}
|
||||||
|
{::audit/profile-id uuid/zero})))
|
||||||
|
|
||||||
;; --- MUTATION: Register Profile
|
;; --- MUTATION: Register Profile
|
||||||
|
|
||||||
|
@ -175,7 +176,7 @@
|
||||||
resp {:invitation-token token}]
|
resp {:invitation-token token}]
|
||||||
(with-meta resp
|
(with-meta resp
|
||||||
{:transform-response ((:create session) (:id profile))
|
{:transform-response ((:create session) (:id profile))
|
||||||
::audit/props (audit/profile->props profile)
|
::audit/replace-props (audit/profile->props profile)
|
||||||
::audit/profile-id (:id profile)}))
|
::audit/profile-id (:id profile)}))
|
||||||
|
|
||||||
;; If auth backend is different from "penpot" means user is
|
;; If auth backend is different from "penpot" means user is
|
||||||
|
@ -184,7 +185,7 @@
|
||||||
(not= "penpot" (:auth-backend profile))
|
(not= "penpot" (:auth-backend profile))
|
||||||
(with-meta (profile/strip-private-attrs profile)
|
(with-meta (profile/strip-private-attrs profile)
|
||||||
{:transform-response ((:create session) (:id profile))
|
{:transform-response ((:create session) (:id profile))
|
||||||
::audit/props (audit/profile->props profile)
|
::audit/replace-props (audit/profile->props profile)
|
||||||
::audit/profile-id (:id profile)})
|
::audit/profile-id (:id profile)})
|
||||||
|
|
||||||
;; If the `:enable-insecure-register` flag is set, we proceed
|
;; If the `:enable-insecure-register` flag is set, we proceed
|
||||||
|
@ -192,7 +193,7 @@
|
||||||
(true? is-active)
|
(true? is-active)
|
||||||
(with-meta (profile/strip-private-attrs profile)
|
(with-meta (profile/strip-private-attrs profile)
|
||||||
{:transform-response ((:create session) (:id profile))
|
{:transform-response ((:create session) (:id profile))
|
||||||
::audit/props (audit/profile->props profile)
|
::audit/replace-props (audit/profile->props profile)
|
||||||
::audit/profile-id (:id profile)})
|
::audit/profile-id (:id profile)})
|
||||||
|
|
||||||
;; In all other cases, send a verification email.
|
;; In all other cases, send a verification email.
|
||||||
|
@ -214,7 +215,7 @@
|
||||||
:extra-data ptoken})
|
:extra-data ptoken})
|
||||||
|
|
||||||
(with-meta profile
|
(with-meta profile
|
||||||
{::audit/props (audit/profile->props profile)
|
{::audit/replace-props (audit/profile->props profile)
|
||||||
::audit/profile-id (:id profile)}))))))
|
::audit/profile-id (:id profile)}))))))
|
||||||
|
|
||||||
(defn create-profile
|
(defn create-profile
|
||||||
|
|
|
@ -199,6 +199,7 @@
|
||||||
"taiga"
|
"taiga"
|
||||||
(cf/get :telemetry-referer))]
|
(cf/get :telemetry-referer))]
|
||||||
(-> {:referer referer
|
(-> {:referer referer
|
||||||
|
:public-uri (cf/get :public-uri)
|
||||||
:total-teams (retrieve-num-teams conn)
|
:total-teams (retrieve-num-teams conn)
|
||||||
:total-projects (retrieve-num-projects conn)
|
:total-projects (retrieve-num-projects conn)
|
||||||
:total-files (retrieve-num-files conn)
|
:total-files (retrieve-num-files conn)
|
||||||
|
|
|
@ -1,34 +1,48 @@
|
||||||
# Should be set to the public domain where penpot is going to be served.
|
## Should be set to the public domain where penpot is going to be served.
|
||||||
|
##
|
||||||
|
## NOTE: If you are going to serve it under different domain than
|
||||||
|
## 'localhost' without HTTPS, consider setting the
|
||||||
|
## `disable-secure-session-cookies' flag on the 'PENPOT_FLAGS'
|
||||||
|
## setting.
|
||||||
|
|
||||||
PENPOT_PUBLIC_URI=http://localhost:9001
|
PENPOT_PUBLIC_URI=http://localhost:9001
|
||||||
PENPOT_TENANT=pro
|
PENPOT_TENANT=pro
|
||||||
|
|
||||||
# Temporal workaround because of bad builtin default
|
## Feature flags.
|
||||||
|
|
||||||
|
PENPOT_FLAGS="enable-registration enable-login"
|
||||||
|
|
||||||
|
## Temporal workaround because of bad builtin default
|
||||||
|
|
||||||
PENPOT_HTTP_SERVER_HOST=0.0.0.0
|
PENPOT_HTTP_SERVER_HOST=0.0.0.0
|
||||||
|
|
||||||
# Standard database connection parameters (only postgresql is supported):
|
## Standard database connection parameters (only postgresql is supported):
|
||||||
|
|
||||||
PENPOT_DATABASE_URI=postgresql://penpot-postgres/penpot
|
PENPOT_DATABASE_URI=postgresql://penpot-postgres/penpot
|
||||||
PENPOT_DATABASE_USERNAME=penpot
|
PENPOT_DATABASE_USERNAME=penpot
|
||||||
PENPOT_DATABASE_PASSWORD=penpot
|
PENPOT_DATABASE_PASSWORD=penpot
|
||||||
|
|
||||||
# Redis is used for the websockets notifications.
|
## Redis is used for the websockets notifications.
|
||||||
|
|
||||||
PENPOT_REDIS_URI=redis://penpot-redis/0
|
PENPOT_REDIS_URI=redis://penpot-redis/0
|
||||||
|
|
||||||
# By default, files uploaded by users are stored in local filesystem. But it
|
## By default, files uploaded by users are stored in local
|
||||||
# can be configured to store in AWS S3 or completely in de the database.
|
## filesystem. But it can be configured to store in AWS S3.
|
||||||
# Storing in the database makes the backups more easy but will make access to
|
|
||||||
# media less performant.
|
|
||||||
PENPOT_ASSETS_STORAGE_BACKEND=assets-fs
|
PENPOT_ASSETS_STORAGE_BACKEND=assets-fs
|
||||||
PENPOT_STORAGE_ASSETS_FS_DIRECTORY=/opt/data/assets
|
PENPOT_STORAGE_ASSETS_FS_DIRECTORY=/opt/data/assets
|
||||||
|
|
||||||
# Telemetry. When enabled, a periodical process will send anonymous data about
|
## Telemetry. When enabled, a periodical process will send anonymous
|
||||||
# this instance. Telemetry data will enable us to learn on how the application
|
## data about this instance. Telemetry data will enable us to learn on
|
||||||
# is used, based on real scenarios. If you want to help us, please leave it
|
## how the application is used, based on real scenarios. If you want
|
||||||
# enabled.
|
## to help us, please leave it enabled.
|
||||||
|
|
||||||
PENPOT_TELEMETRY_ENABLED=true
|
PENPOT_TELEMETRY_ENABLED=true
|
||||||
|
|
||||||
# Email sending configuration. By default, emails are printed in the console,
|
## Email sending configuration. By default, emails are printed in the
|
||||||
# but for production usage is recommended to setup a real SMTP provider. Emails
|
## console, but for production usage is recommended to setup a real
|
||||||
# are used to confirm user registrations.
|
## SMTP provider. Emails are used to confirm user registrations.
|
||||||
|
|
||||||
PENPOT_SMTP_ENABLED=false
|
PENPOT_SMTP_ENABLED=false
|
||||||
PENPOT_SMTP_DEFAULT_FROM=no-reply@example.com
|
PENPOT_SMTP_DEFAULT_FROM=no-reply@example.com
|
||||||
PENPOT_SMTP_DEFAULT_REPLY_TO=no-reply@example.com
|
PENPOT_SMTP_DEFAULT_REPLY_TO=no-reply@example.com
|
||||||
|
@ -39,34 +53,40 @@ PENPOT_SMTP_DEFAULT_REPLY_TO=no-reply@example.com
|
||||||
# PENPOT_SMTP_TLS=true
|
# PENPOT_SMTP_TLS=true
|
||||||
# PENPOT_SMTP_SSL=false
|
# PENPOT_SMTP_SSL=false
|
||||||
|
|
||||||
# Feature flags. Right now they are only affect frontend, but in
|
## Comma separated list of allowed domains to register. Empty to allow
|
||||||
# future release they will affect to both backend and frontend.
|
## all.
|
||||||
PENPOT_FLAGS="enable-registration"
|
|
||||||
|
|
||||||
# Comma separated list of allowed domains to register. Empty to allow all.
|
|
||||||
# PENPOT_REGISTRATION_DOMAIN_WHITELIST=""
|
# PENPOT_REGISTRATION_DOMAIN_WHITELIST=""
|
||||||
|
|
||||||
## Authentication providers
|
## Authentication providers
|
||||||
|
|
||||||
# Google
|
## Google
|
||||||
|
|
||||||
# PENPOT_GOOGLE_CLIENT_ID=
|
# PENPOT_GOOGLE_CLIENT_ID=
|
||||||
# PENPOT_GOOGLE_CLIENT_SECRET=
|
# PENPOT_GOOGLE_CLIENT_SECRET=
|
||||||
|
|
||||||
# GitHub
|
## GitHub
|
||||||
|
|
||||||
# PENPOT_GITHUB_CLIENT_ID=
|
# PENPOT_GITHUB_CLIENT_ID=
|
||||||
# PENPOT_GITHUB_CLIENT_SECRET=
|
# PENPOT_GITHUB_CLIENT_SECRET=
|
||||||
|
|
||||||
# GitLab
|
## GitLab
|
||||||
|
|
||||||
# PENPOT_GITLAB_BASE_URI=https://gitlab.com
|
# PENPOT_GITLAB_BASE_URI=https://gitlab.com
|
||||||
# PENPOT_GITLAB_CLIENT_ID=
|
# PENPOT_GITLAB_CLIENT_ID=
|
||||||
# PENPOT_GITLAB_CLIENT_SECRET=
|
# PENPOT_GITLAB_CLIENT_SECRET=
|
||||||
|
|
||||||
# OpenID Connect (since 1.5.0)
|
## OpenID Connect (since 1.5.0)
|
||||||
|
|
||||||
# PENPOT_OIDC_BASE_URI=
|
# PENPOT_OIDC_BASE_URI=
|
||||||
# PENPOT_OIDC_CLIENT_ID=
|
# PENPOT_OIDC_CLIENT_ID=
|
||||||
# PENPOT_OIDC_CLIENT_SECRET=
|
# PENPOT_OIDC_CLIENT_SECRET=
|
||||||
|
|
||||||
# LDAP
|
## LDAP
|
||||||
|
##
|
||||||
|
## NOTE: to enable ldap, you will need to put 'enable-login-with-ldap'
|
||||||
|
## on the 'PENPOT_FLAGS' environment variable.
|
||||||
|
|
||||||
# PENPOT_LDAP_HOST=ldap
|
# PENPOT_LDAP_HOST=ldap
|
||||||
# PENPOT_LDAP_PORT=10389
|
# PENPOT_LDAP_PORT=10389
|
||||||
# PENPOT_LDAP_SSL=false
|
# PENPOT_LDAP_SSL=false
|
||||||
|
@ -78,7 +98,3 @@ PENPOT_FLAGS="enable-registration"
|
||||||
# PENPOT_LDAP_ATTRS_EMAIL=mail
|
# PENPOT_LDAP_ATTRS_EMAIL=mail
|
||||||
# PENPOT_LDAP_ATTRS_FULLNAME=cn
|
# PENPOT_LDAP_ATTRS_FULLNAME=cn
|
||||||
# PENPOT_LDAP_ATTRS_PHOTO=jpegPhoto
|
# PENPOT_LDAP_ATTRS_PHOTO=jpegPhoto
|
||||||
# PENPOT_LOGIN_WITH_LDAP=true
|
|
||||||
|
|
||||||
# Exporter
|
|
||||||
PENPOT_DOMAIN_WHITE_LIST=localhost:9001
|
|
||||||
|
|
|
@ -25,15 +25,13 @@
|
||||||
:host "devenv"
|
:host "devenv"
|
||||||
:http-server-port 6061
|
:http-server-port 6061
|
||||||
:http-server-host "localhost"
|
:http-server-host "localhost"
|
||||||
:redis-uri "redis://redis/0"
|
:redis-uri "redis://redis/0"})
|
||||||
:domain-white-list #{"localhost:3449"}})
|
|
||||||
|
|
||||||
(s/def ::http-server-port ::us/integer)
|
(s/def ::http-server-port ::us/integer)
|
||||||
(s/def ::http-server-host ::us/string)
|
(s/def ::http-server-host ::us/string)
|
||||||
(s/def ::public-uri ::us/uri)
|
(s/def ::public-uri ::us/uri)
|
||||||
(s/def ::tenant ::us/string)
|
(s/def ::tenant ::us/string)
|
||||||
(s/def ::host ::us/string)
|
(s/def ::host ::us/string)
|
||||||
(s/def ::domain-white-list ::us/set-of-str)
|
|
||||||
(s/def ::browser-pool-max ::us/integer)
|
(s/def ::browser-pool-max ::us/integer)
|
||||||
(s/def ::browser-pool-min ::us/integer)
|
(s/def ::browser-pool-min ::us/integer)
|
||||||
|
|
||||||
|
@ -44,8 +42,7 @@
|
||||||
::http-server-port
|
::http-server-port
|
||||||
::http-server-host
|
::http-server-host
|
||||||
::browser-pool-max
|
::browser-pool-max
|
||||||
::browser-pool-min
|
::browser-pool-min]))
|
||||||
::domain-white-list]))
|
|
||||||
|
|
||||||
(defn- read-env
|
(defn- read-env
|
||||||
[prefix]
|
[prefix]
|
||||||
|
|
|
@ -70,7 +70,6 @@
|
||||||
(defmulti command-spec :cmd)
|
(defmulti command-spec :cmd)
|
||||||
|
|
||||||
(s/def ::id ::us/string)
|
(s/def ::id ::us/string)
|
||||||
(s/def ::uri ::us/uri)
|
|
||||||
(s/def ::wait ::us/boolean)
|
(s/def ::wait ::us/boolean)
|
||||||
(s/def ::cmd ::us/keyword)
|
(s/def ::cmd ::us/keyword)
|
||||||
|
|
||||||
|
@ -80,24 +79,13 @@
|
||||||
|
|
||||||
(s/def ::params
|
(s/def ::params
|
||||||
(s/and (s/keys :req-un [::cmd]
|
(s/and (s/keys :req-un [::cmd]
|
||||||
:opt-un [::wait ::uri])
|
:opt-un [::wait])
|
||||||
(s/multi-spec command-spec :cmd)))
|
(s/multi-spec command-spec :cmd)))
|
||||||
|
|
||||||
(defn validate-uri!
|
|
||||||
[uri]
|
|
||||||
(let [white-list (cf/get :domain-white-list #{})
|
|
||||||
default (cf/get :public-uri)]
|
|
||||||
(when-not (or (contains? white-list (u/get-domain uri))
|
|
||||||
(= (u/get-domain default) (u/get-domain uri)))
|
|
||||||
(ex/raise :type :validation
|
|
||||||
:code :domain-not-allowed
|
|
||||||
:hint "looks like the uri provided is not part of the white list"))))
|
|
||||||
|
|
||||||
(defn handler
|
(defn handler
|
||||||
[{:keys [:request/params] :as exchange}]
|
[{:keys [:request/params] :as exchange}]
|
||||||
(let [{:keys [cmd uri] :as params} (us/conform ::params params)]
|
(let [{:keys [cmd] :as params} (us/conform ::params params)]
|
||||||
(l/debug :hint "process-request" :cmd cmd)
|
(l/debug :hint "process-request" :cmd cmd)
|
||||||
(some-> uri validate-uri!)
|
|
||||||
(case cmd
|
(case cmd
|
||||||
:get-resource (resources/handler exchange)
|
:get-resource (resources/handler exchange)
|
||||||
:export-shapes (export-shapes/handler exchange params)
|
:export-shapes (export-shapes/handler exchange params)
|
||||||
|
|
|
@ -29,7 +29,6 @@
|
||||||
(s/def ::file-id ::us/uuid)
|
(s/def ::file-id ::us/uuid)
|
||||||
(s/def ::page-id ::us/uuid)
|
(s/def ::page-id ::us/uuid)
|
||||||
(s/def ::object-id ::us/uuid)
|
(s/def ::object-id ::us/uuid)
|
||||||
(s/def ::uri ::us/uri)
|
|
||||||
|
|
||||||
(s/def ::export
|
(s/def ::export
|
||||||
(s/keys :req-un [::file-id ::page-id ::object-id ::name]))
|
(s/keys :req-un [::file-id ::page-id ::object-id ::name]))
|
||||||
|
@ -39,18 +38,18 @@
|
||||||
|
|
||||||
(s/def ::params
|
(s/def ::params
|
||||||
(s/keys :req-un [::exports]
|
(s/keys :req-un [::exports]
|
||||||
:opt-un [::uri ::name]))
|
:opt-un [::name]))
|
||||||
|
|
||||||
(defn handler
|
(defn handler
|
||||||
[{:keys [:request/auth-token] :as exchange} {:keys [exports uri profile-id] :as params}]
|
[{:keys [:request/auth-token] :as exchange} {:keys [exports profile-id] :as params}]
|
||||||
;; NOTE: we need to have the `:type` prop because the exports
|
;; NOTE: we need to have the `:type` prop because the exports
|
||||||
;; datastructure preparation uses it for creating the groups.
|
;; datastructure preparation uses it for creating the groups.
|
||||||
(let [exports (-> (map #(assoc % :type :pdf :scale 1 :suffix "") exports)
|
(let [exports (-> (map #(assoc % :type :pdf :scale 1 :suffix "") exports)
|
||||||
(prepare-exports auth-token uri))]
|
(prepare-exports auth-token))]
|
||||||
(handle-export exchange (assoc params :exports exports))))
|
(handle-export exchange (assoc params :exports exports))))
|
||||||
|
|
||||||
(defn handle-export
|
(defn handle-export
|
||||||
[exchange {:keys [exports wait uri name profile-id] :as params}]
|
[exchange {:keys [exports wait name profile-id] :as params}]
|
||||||
(let [total (count exports)
|
(let [total (count exports)
|
||||||
topic (str profile-id)
|
topic (str profile-id)
|
||||||
resource (rsc/create :pdf (or name (-> exports first :name)))
|
resource (rsc/create :pdf (or name (-> exports first :name)))
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
(s/def ::scale ::us/number)
|
(s/def ::scale ::us/number)
|
||||||
(s/def ::suffix ::us/string)
|
(s/def ::suffix ::us/string)
|
||||||
(s/def ::type ::us/keyword)
|
(s/def ::type ::us/keyword)
|
||||||
(s/def ::uri ::us/uri)
|
|
||||||
(s/def ::wait ::us/boolean)
|
(s/def ::wait ::us/boolean)
|
||||||
|
|
||||||
(s/def ::export
|
(s/def ::export
|
||||||
|
@ -45,11 +44,11 @@
|
||||||
|
|
||||||
(s/def ::params
|
(s/def ::params
|
||||||
(s/keys :req-un [::exports ::profile-id]
|
(s/keys :req-un [::exports ::profile-id]
|
||||||
:opt-un [::uri ::wait ::name]))
|
:opt-un [::wait ::name]))
|
||||||
|
|
||||||
(defn handler
|
(defn handler
|
||||||
[{:keys [:request/auth-token] :as exchange} {:keys [exports uri] :as params}]
|
[{:keys [:request/auth-token] :as exchange} {:keys [exports] :as params}]
|
||||||
(let [exports (prepare-exports exports auth-token uri)]
|
(let [exports (prepare-exports exports auth-token)]
|
||||||
(if (and (= 1 (count exports))
|
(if (and (= 1 (count exports))
|
||||||
(= 1 (count (-> exports first :objects))))
|
(= 1 (count (-> exports first :objects))))
|
||||||
(handle-single-export exchange (-> params
|
(handle-single-export exchange (-> params
|
||||||
|
@ -58,7 +57,7 @@
|
||||||
(handle-multiple-export exchange (assoc params :exports exports)))))
|
(handle-multiple-export exchange (assoc params :exports exports)))))
|
||||||
|
|
||||||
(defn- handle-single-export
|
(defn- handle-single-export
|
||||||
[exchange {:keys [export wait uri profile-id name] :as params}]
|
[exchange {:keys [export wait profile-id name] :as params}]
|
||||||
(let [topic (str profile-id)
|
(let [topic (str profile-id)
|
||||||
resource (rsc/create (:type export) (or name (:name export)))
|
resource (rsc/create (:type export) (or name (:name export)))
|
||||||
|
|
||||||
|
@ -98,7 +97,7 @@
|
||||||
(assoc exchange :response/body (dissoc resource :path)))))
|
(assoc exchange :response/body (dissoc resource :path)))))
|
||||||
|
|
||||||
(defn- handle-multiple-export
|
(defn- handle-multiple-export
|
||||||
[exchange {:keys [exports wait uri profile-id name] :as params}]
|
[exchange {:keys [exports wait profile-id name] :as params}]
|
||||||
(let [resource (rsc/create :zip (or name (-> exports first :name)))
|
(let [resource (rsc/create :zip (or name (-> exports first :name)))
|
||||||
total (count exports)
|
total (count exports)
|
||||||
topic (str profile-id)
|
topic (str profile-id)
|
||||||
|
@ -185,7 +184,7 @@
|
||||||
default-partition-size 50)
|
default-partition-size 50)
|
||||||
|
|
||||||
(defn prepare-exports
|
(defn prepare-exports
|
||||||
[exports token uri]
|
[exports token]
|
||||||
(letfn [(process-group [group]
|
(letfn [(process-group [group]
|
||||||
(sequence (comp (partition-all default-partition-size)
|
(sequence (comp (partition-all default-partition-size)
|
||||||
(map process-partition))
|
(map process-partition))
|
||||||
|
@ -196,7 +195,6 @@
|
||||||
:page-id (:page-id part1)
|
:page-id (:page-id part1)
|
||||||
:name (:name part1)
|
:name (:name part1)
|
||||||
:token token
|
:token token
|
||||||
:uri uri
|
|
||||||
:type (:type part1)
|
:type (:type part1)
|
||||||
:scale (:scale part1)
|
:scale (:scale part1)
|
||||||
:objects (mapv part-entry->object part)})
|
:objects (mapv part-entry->object part)})
|
||||||
|
|
|
@ -20,7 +20,6 @@
|
||||||
(s/def ::file-id ::us/uuid)
|
(s/def ::file-id ::us/uuid)
|
||||||
(s/def ::scale ::us/number)
|
(s/def ::scale ::us/number)
|
||||||
(s/def ::token ::us/string)
|
(s/def ::token ::us/string)
|
||||||
(s/def ::uri ::us/uri)
|
|
||||||
(s/def ::filename ::us/string)
|
(s/def ::filename ::us/string)
|
||||||
|
|
||||||
(s/def ::object
|
(s/def ::object
|
||||||
|
@ -30,8 +29,7 @@
|
||||||
(s/coll-of ::object :min-count 1))
|
(s/coll-of ::object :min-count 1))
|
||||||
|
|
||||||
(s/def ::render-params
|
(s/def ::render-params
|
||||||
(s/keys :req-un [::file-id ::page-id ::scale ::token ::type ::objects]
|
(s/keys :req-un [::file-id ::page-id ::scale ::token ::type ::objects]))
|
||||||
:opt-un [::uri]))
|
|
||||||
|
|
||||||
(defn- render
|
(defn- render
|
||||||
[{:keys [type] :as params} on-object]
|
[{:keys [type] :as params} on-object]
|
||||||
|
|
|
@ -130,9 +130,7 @@
|
||||||
|
|
||||||
(defmethod query :exporter
|
(defmethod query :exporter
|
||||||
[_ params]
|
[_ params]
|
||||||
(let [default {:wait false
|
(let [default {:wait false :blob? false}]
|
||||||
:blob? false
|
|
||||||
:uri (str base-uri)}]
|
|
||||||
(send-export (merge default params))))
|
(send-export (merge default params))))
|
||||||
|
|
||||||
(derive :upload-file-media-object ::multipart-upload)
|
(derive :upload-file-media-object ::multipart-upload)
|
||||||
|
|
|
@ -398,7 +398,9 @@
|
||||||
[:span (tr "labels.github-repo")]]
|
[:span (tr "labels.github-repo")]]
|
||||||
[:li {:on-click #(dom/open-new-window "https://penpot.app/terms.html")}
|
[:li {:on-click #(dom/open-new-window "https://penpot.app/terms.html")}
|
||||||
[:span (tr "auth.terms-of-service")]]
|
[:span (tr "auth.terms-of-service")]]
|
||||||
[:li.separator {:on-click #(st/emit! (rt/nav-new-window* {:rname :settings-feedback}))}
|
[:li.separator {:on-click #(st/emit! (when (contains? layout :collapse-left-sidebar) (dw/toggle-layout-flag :collapse-left-sidebar))
|
||||||
|
(-> (dw/toggle-layout-flag :shortcuts)
|
||||||
|
(vary-meta assoc ::ev/origin "workspace-header")))}
|
||||||
[:span (tr "label.shortcuts")]
|
[:span (tr "label.shortcuts")]
|
||||||
[:span.shortcut (sc/get-tooltip :show-shortcuts)]]
|
[:span.shortcut (sc/get-tooltip :show-shortcuts)]]
|
||||||
|
|
||||||
|
|
|
@ -125,12 +125,11 @@
|
||||||
on-change
|
on-change
|
||||||
(mf/use-fn
|
(mf/use-fn
|
||||||
(fn [new-color old-color]
|
(fn [new-color old-color]
|
||||||
(let [old-color (-> (or @prev-color* old-color)
|
(let [old-color (-> old-color
|
||||||
(dissoc :name)
|
(dissoc :name)
|
||||||
(dissoc :path)
|
(dissoc :path)
|
||||||
(d/without-nils))
|
(d/without-nils))
|
||||||
shapes-by-color (get @grouped-colors* old-color)]
|
shapes-by-color (get @grouped-colors* old-color)]
|
||||||
(reset! prev-color* new-color)
|
|
||||||
(st/emit! (dc/change-color-in-selected new-color shapes-by-color old-color)))))
|
(st/emit! (dc/change-color-in-selected new-color shapes-by-color old-color)))))
|
||||||
|
|
||||||
on-open (mf/use-fn
|
on-open (mf/use-fn
|
||||||
|
|
|
@ -69,6 +69,8 @@
|
||||||
shared-libs (mf/deref refs/workspace-libraries)
|
shared-libs (mf/deref refs/workspace-libraries)
|
||||||
hover-detach (mf/use-state false)
|
hover-detach (mf/use-state false)
|
||||||
|
|
||||||
|
on-change-var (h/use-update-var {:fn on-change})
|
||||||
|
|
||||||
src-colors (if (= (:file-id color) current-file-id)
|
src-colors (if (= (:file-id color) current-file-id)
|
||||||
file-colors
|
file-colors
|
||||||
(get-in shared-libs [(:file-id color) :data :colors]))
|
(get-in shared-libs [(:file-id color) :data :colors]))
|
||||||
|
@ -83,18 +85,18 @@
|
||||||
(when on-detach (on-detach color)))
|
(when on-detach (on-detach color)))
|
||||||
|
|
||||||
change-value (fn [new-value]
|
change-value (fn [new-value]
|
||||||
(when on-change (on-change (-> color
|
(when (:fn @on-change-var) ((:fn @on-change-var) (-> color
|
||||||
(assoc :color new-value)
|
(assoc :color new-value)
|
||||||
(dissoc :gradient)))))
|
(dissoc :gradient)))))
|
||||||
|
|
||||||
change-opacity (fn [new-opacity]
|
change-opacity (fn [new-opacity]
|
||||||
(when on-change (on-change (assoc color
|
(when (:fn @on-change-var) ((:fn @on-change-var) (assoc color
|
||||||
:opacity new-opacity
|
:opacity new-opacity
|
||||||
:id nil
|
:id nil
|
||||||
:file-id nil))))
|
:file-id nil))))
|
||||||
|
|
||||||
handle-pick-color (fn [color]
|
handle-pick-color (fn [color]
|
||||||
(when on-change (on-change (merge uc/empty-color color))))
|
(when (:fn @on-change-var) ((:fn @on-change-var) (merge uc/empty-color color))))
|
||||||
|
|
||||||
handle-select (fn []
|
handle-select (fn []
|
||||||
(select-only color))
|
(select-only color))
|
||||||
|
|
|
@ -43,6 +43,7 @@
|
||||||
(rest keys)
|
(rest keys)
|
||||||
(unchecked-get res key))))))
|
(unchecked-get res key))))))
|
||||||
|
|
||||||
|
#_:clj-kondo/ignore
|
||||||
(defn without
|
(defn without
|
||||||
[obj keys]
|
[obj keys]
|
||||||
(let [keys (cond
|
(let [keys (cond
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue