mirror of
https://github.com/penpot/penpot.git
synced 2025-12-29 17:39:13 -05:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e369b70aeb | ||
|
|
c3970255e6 | ||
|
|
7823eaf890 | ||
|
|
ec0079461e | ||
|
|
70a1a7a5ea | ||
|
|
c3dc165c4c | ||
|
|
5a3619c737 | ||
|
|
227f06c1ec | ||
|
|
946dac3c9f | ||
|
|
b160ba1793 | ||
|
|
33d51a51d1 | ||
|
|
ab4be85669 | ||
|
|
6c0dce580d |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -74,3 +74,5 @@ node_modules
|
||||
/playwright-report/
|
||||
/blob-report/
|
||||
/playwright/.cache/
|
||||
/render-wasm/target/
|
||||
/**/.yarn/*
|
||||
|
||||
20
CHANGES.md
20
CHANGES.md
@@ -1,5 +1,25 @@
|
||||
# CHANGELOG
|
||||
|
||||
## 2.3.2
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
- Fix null pointer exception on number checking functions
|
||||
- Fix problem with grid layout ordering after moving [Taiga #9179](https://tree.taiga.io/project/penpot/issue/9179)
|
||||
|
||||
### :books: Documentation
|
||||
|
||||
- Add initial documentation for Kubernetes
|
||||
|
||||
|
||||
## 2.3.1
|
||||
|
||||
### :bug: Bugs fixed
|
||||
|
||||
- Fix unexpected issue on interaction between plugins sandbox and
|
||||
internal impl of promise
|
||||
|
||||
|
||||
## 2.3.0
|
||||
|
||||
### :rocket: Epics and highlights
|
||||
|
||||
@@ -391,13 +391,14 @@
|
||||
(-> (pcb/update-shapes
|
||||
[parent-id]
|
||||
(fn [frame objects]
|
||||
(-> frame
|
||||
;; Assign the cell when pushing into a specific grid cell
|
||||
(cond-> (some? cell)
|
||||
(-> (ctl/free-cell-shapes ids)
|
||||
(ctl/push-into-cell ids (:row cell) (:column cell))
|
||||
(ctl/assign-cells objects)))
|
||||
(ctl/assign-cell-positions objects)))
|
||||
(let [[row column] cell]
|
||||
(-> frame
|
||||
;; Assign the cell when pushing into a specific grid cell
|
||||
(cond-> (some? cell)
|
||||
(-> (ctl/free-cell-shapes ids)
|
||||
(ctl/push-into-cell ids row column)
|
||||
(ctl/assign-cells objects)))
|
||||
(ctl/assign-cell-positions objects))))
|
||||
{:with-objects? true})
|
||||
(pcb/reorder-grid-children [parent-id])))
|
||||
|
||||
|
||||
@@ -681,8 +681,8 @@
|
||||
(let [pred int?
|
||||
pred (if (some? min)
|
||||
(fn [v]
|
||||
(and (>= v min)
|
||||
(pred v)))
|
||||
(and (pred v)
|
||||
(>= v min)))
|
||||
pred)
|
||||
pred (if (some? max)
|
||||
(fn [v]
|
||||
@@ -719,8 +719,8 @@
|
||||
(let [pred double?
|
||||
pred (if (some? min)
|
||||
(fn [v]
|
||||
(and (>= v min)
|
||||
(pred v)))
|
||||
(and (pred v)
|
||||
(>= v min)))
|
||||
pred)
|
||||
pred (if (some? max)
|
||||
(fn [v]
|
||||
@@ -749,8 +749,8 @@
|
||||
(let [pred number?
|
||||
pred (if (some? min)
|
||||
(fn [v]
|
||||
(and (>= v min)
|
||||
(pred v)))
|
||||
(and (pred v)
|
||||
(>= v min)))
|
||||
pred)
|
||||
pred (if (some? max)
|
||||
(fn [v]
|
||||
|
||||
@@ -256,6 +256,142 @@ Postgres database and another one for the assets uploaded by your users (images
|
||||
clips). There may be more volumes if you enable other features, as explained in the file
|
||||
itself.
|
||||
|
||||
|
||||
## Install with Kubernetes
|
||||
|
||||
This section details everything you need to know to get Penpot up and running in
|
||||
production environments using a Kubernetes cluster of your choice. To do this, we have
|
||||
created a <a href="https://helm.sh/" target="_blank">Helm<a> repository with everything
|
||||
you need.
|
||||
|
||||
Therefore, your prerequisite will be to have a Kubernetes cluster on which we can install
|
||||
Helm.
|
||||
|
||||
|
||||
### What is Helm
|
||||
|
||||
*Helm* is the package manager for Kubernetes. A *Chart* is a Helm package. It contains
|
||||
all of the resource definitions necessary to run an application, tool, or service inside
|
||||
of a Kubernetes cluster. Think of it like the Kubernetes equivalent of a Homebrew
|
||||
formula, an Apt dpkg, or a Yum RPM file.
|
||||
|
||||
A Repository is the place where charts can be collected and shared. It's like Perl's CPAN
|
||||
archive or the Fedora Package Database, but for Kubernetes packages.
|
||||
|
||||
A Release is an instance of a chart running in a Kubernetes cluster. One chart can often
|
||||
be installed many times into the same cluster. And each time it is installed, a new
|
||||
release is created. Consider a MySQL chart. If you want two databases running in your
|
||||
cluster, you can install that chart twice. Each one will have its own release, which will
|
||||
in turn have its own release name.
|
||||
|
||||
With these concepts in mind, we can now explain Helm like this:
|
||||
|
||||
> Helm installs charts into Kubernetes clusters, creating a new release for each
|
||||
> installation. And to find new charts, you can search Helm chart repositories.
|
||||
|
||||
|
||||
### Install Helm
|
||||
|
||||
<p class="advice">
|
||||
Skip this section if you already have Helm installed in your system.
|
||||
</p>
|
||||
|
||||
You can install Helm by following the <a href="https://helm.sh/docs/intro/install/" target="_blank">official guide</a>.
|
||||
There are different ways to install Helm, depending on your infrastructure and operating
|
||||
system.
|
||||
|
||||
|
||||
### Add Penpot repository
|
||||
|
||||
To add the Penpot Helm repository, run the following command:
|
||||
|
||||
```bash
|
||||
helm repo add penpot http://helm.penpot.app
|
||||
```
|
||||
|
||||
This will add the Penpot repository to your Helm configuration, so you can install all
|
||||
the Penpot charts stored there.
|
||||
|
||||
|
||||
### Install Penpot Chart
|
||||
|
||||
To install the chart with the release name `my-release`:
|
||||
|
||||
```bash
|
||||
helm install my-release penpot/penpot
|
||||
```
|
||||
|
||||
You can customize the installation specify each parameter using the `--set key=value[,key=value]`
|
||||
argument to helm install. For example,
|
||||
|
||||
```bash
|
||||
helm install my-release \
|
||||
--set global.postgresqlEnabled=true \
|
||||
--set global.redisEnabled=true \
|
||||
--set persistence.assets.enabled=true \
|
||||
penpot/penpot
|
||||
```
|
||||
|
||||
Alternatively, a YAML file that specifies the values for the above parameters can be
|
||||
provided while installing the chart. For example,
|
||||
|
||||
```bash
|
||||
helm install my-release -f values.yaml penpot/penpot
|
||||
```
|
||||
|
||||
|
||||
### Configure Penpot with Helm Chart
|
||||
|
||||
In the previous section we have shown how to configure penpot during installation by
|
||||
using parameters or by using a yaml file.
|
||||
|
||||
The default values are defined in the
|
||||
<a href="https://github.com/penpot/penpot-helm/blob/main/charts/penpot/values.yaml" target="_blank">`values.yml`</a>
|
||||
file itself, which you can use as a basis for creating your own settings.
|
||||
|
||||
You can also consult the list of parameters on the
|
||||
<a href="https://artifacthub.io/packages/helm/penpot/penpot#parameters" target="_blank">ArtifactHub page of the project</a>.
|
||||
|
||||
|
||||
### Upgrade Penpot
|
||||
|
||||
When a new version of Penpot's chart is released, or when you want to change the
|
||||
configuration of your release, you can use the helm upgrade command.
|
||||
|
||||
```bash
|
||||
helm upgrade my-release -f values.yaml penpot/penpot
|
||||
```
|
||||
|
||||
An upgrade takes an existing release and upgrades it according to the information you
|
||||
provide. Because Kubernetes charts can be large and complex, Helm tries to perform the
|
||||
least invasive upgrade. It will only update things that have changed since the last
|
||||
release.
|
||||
|
||||
After each upgrade, a new *revision* will be generated. You can check the revision
|
||||
history of a release with `helm history my-release` and go back to the previous revision
|
||||
if something went wrong with `helm rollback my-release 1` (`1` is the revision number of
|
||||
the previous release revision).
|
||||
|
||||
|
||||
### Backup Penpot
|
||||
|
||||
The Penpot's Helm Chart uses different Persistent Volumes to store all persistent data.
|
||||
This allows you to delete and recreate the instance whenever you want without losing
|
||||
information.
|
||||
|
||||
You back up data from a Persistent Volume via snapshots, so you will want to ensure that
|
||||
your container storage interface (CSI) supports volume snapshots. There are a couple of
|
||||
different options for the CSI driver that you choose. All of the major cloud providers
|
||||
have their respective CSI drivers.
|
||||
|
||||
At last, there are two Persistent Volumes used: one for the Postgres database and another
|
||||
one for the assets uploaded by your users (images and svg clips). There may be more
|
||||
volumes if you enable other features, as explained in the file itself.
|
||||
|
||||
You have to back up your custom settings too (the yaml file or the list of parameters you
|
||||
are using during you setup).
|
||||
|
||||
|
||||
## Unofficial self-host options
|
||||
|
||||
There are some other options, **NOT SUPPORTED BY PENPOT**:
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.store :as st]
|
||||
[beicon.v2.core :as rx]
|
||||
[cljs.core :as c]
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
@@ -30,6 +31,12 @@
|
||||
(dissoc :type)
|
||||
(assoc :name type)))
|
||||
|
||||
ptk/WatchEvent
|
||||
(watch [_ _ _]
|
||||
(rx/of (ptk/event
|
||||
::ev/event
|
||||
{::ev/name "show-modal" :type type})))
|
||||
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(assoc state ::modal {:id id
|
||||
|
||||
@@ -40,8 +40,7 @@
|
||||
[app.plugins.viewport :as viewport]
|
||||
[app.util.code-gen :as cg]
|
||||
[app.util.object :as obj]
|
||||
[beicon.v2.core :as rx]
|
||||
[promesa.core :as p]))
|
||||
[beicon.v2.core :as rx]))
|
||||
|
||||
;;
|
||||
;; PLUGINS PUBLIC API - The plugins will able to access this functions
|
||||
@@ -174,7 +173,7 @@
|
||||
|
||||
:else
|
||||
(let [file-id (:current-file-id @st/state)]
|
||||
(p/create
|
||||
(js/Promise.
|
||||
(fn [resolve reject]
|
||||
(->> (dwm/upload-media-url name file-id url)
|
||||
(rx/take 1)
|
||||
@@ -184,7 +183,7 @@
|
||||
(uploadMediaData
|
||||
[_ name data mime-type]
|
||||
(let [file-id (:current-file-id @st/state)]
|
||||
(p/create
|
||||
(js/Promise.
|
||||
(fn [resolve reject]
|
||||
(->> (dwm/process-blobs
|
||||
{:file-id file-id
|
||||
|
||||
@@ -19,13 +19,12 @@
|
||||
[app.plugins.shape :as shape]
|
||||
[app.plugins.user :as user]
|
||||
[app.plugins.utils :as u]
|
||||
[beicon.v2.core :as rx]
|
||||
[promesa.core :as p]))
|
||||
[beicon.v2.core :as rx]))
|
||||
|
||||
(deftype CommentProxy [$plugin $file $page $thread $id]
|
||||
Object
|
||||
(remove [_]
|
||||
(p/create
|
||||
(js/Promise.
|
||||
(fn [resolve reject]
|
||||
(cond
|
||||
(not (r/check-permission $plugin "comment:write"))
|
||||
@@ -79,7 +78,7 @@
|
||||
Object
|
||||
(findComments
|
||||
[_]
|
||||
(p/create
|
||||
(js/Promise.
|
||||
(fn [resolve reject]
|
||||
(cond
|
||||
(not (r/check-permission $plugin "comment:read"))
|
||||
@@ -106,7 +105,7 @@
|
||||
(u/display-not-valid :reply "Not valid")
|
||||
|
||||
:else
|
||||
(p/create
|
||||
(js/Promise.
|
||||
(fn [resolve reject]
|
||||
(->> (rp/cmd! :create-comment {:thread-id $id :content content})
|
||||
(rx/subs! #(resolve (comment-proxy $plugin $file $page $id $users %)) reject))))))
|
||||
@@ -121,9 +120,9 @@
|
||||
(u/display-not-valid :remove "Cannot change content from another user's comments")
|
||||
|
||||
:else
|
||||
(p/create
|
||||
(js/Promise.
|
||||
(fn [resolve]
|
||||
(p/create
|
||||
(js/Promise.
|
||||
(st/emit! (dc/delete-comment-thread-on-workspace {:id $id} #(resolve))))))))))
|
||||
|
||||
(defn comment-thread-proxy? [p]
|
||||
|
||||
@@ -20,8 +20,7 @@
|
||||
[app.plugins.utils :as u]
|
||||
[app.util.http :as http]
|
||||
[app.util.object :as obj]
|
||||
[beicon.v2.core :as rx]
|
||||
[promesa.core :as p]))
|
||||
[beicon.v2.core :as rx]))
|
||||
|
||||
(deftype FileProxy [$plugin $id]
|
||||
Object
|
||||
@@ -128,7 +127,7 @@
|
||||
file (u/proxy->file self)
|
||||
features (features/get-team-enabled-features @st/state)
|
||||
team-id (:current-team-id @st/state)]
|
||||
(p/create
|
||||
(js/Promise.
|
||||
(fn [resolve reject]
|
||||
(->> (uw/ask-many!
|
||||
{:cmd export-cmd
|
||||
|
||||
@@ -30,8 +30,7 @@
|
||||
[app.plugins.utils :as u]
|
||||
[app.util.object :as obj]
|
||||
[beicon.v2.core :as rx]
|
||||
[potok.v2.core :as ptk]
|
||||
[promesa.core :as p]))
|
||||
[potok.v2.core :as ptk]))
|
||||
|
||||
(declare lib-color-proxy)
|
||||
(declare lib-typography-proxy)
|
||||
@@ -915,7 +914,7 @@
|
||||
(availableLibraries
|
||||
[_]
|
||||
(let [team-id (:current-team-id @st/state)]
|
||||
(p/create
|
||||
(js/Promise.
|
||||
(fn [resolve reject]
|
||||
(let [current-libs (into #{} (map first) (get @st/state :workspace-libraries))]
|
||||
(->> (rp/cmd! :get-team-shared-files {:team-id team-id})
|
||||
@@ -939,7 +938,7 @@
|
||||
(u/display-not-valid :connectLibrary "Plugin doesn't have 'library:write' permission")
|
||||
|
||||
:else
|
||||
(p/create
|
||||
(js/Promise.
|
||||
(fn [resolve reject]
|
||||
(cond
|
||||
(not (string? library-id))
|
||||
|
||||
@@ -29,8 +29,7 @@
|
||||
[app.plugins.utils :as u]
|
||||
[app.util.object :as obj]
|
||||
[beicon.v2.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[promesa.core :as p]))
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(deftype FlowProxy [$plugin $file $page $id]
|
||||
Object
|
||||
@@ -288,7 +287,7 @@
|
||||
(some? board)
|
||||
(-> (update :x - (:x board))
|
||||
(update :y - (:y board))))]
|
||||
(p/create
|
||||
(js/Promise.
|
||||
(fn [resolve]
|
||||
(st/emit!
|
||||
(dc/create-thread-on-workspace
|
||||
@@ -315,10 +314,10 @@
|
||||
(u/display-not-valid :removeCommentThread "Plugin doesn't have 'content:write' permission")
|
||||
|
||||
:else
|
||||
(p/create
|
||||
(js/Promise.
|
||||
(fn [resolve]
|
||||
(let [thread-id (obj/get thread "$id")]
|
||||
(p/create
|
||||
(js/Promise.
|
||||
(st/emit! (dc/delete-comment-thread-on-workspace {:id thread-id} #(resolve)))))))))
|
||||
|
||||
(findCommentThreads
|
||||
@@ -326,7 +325,7 @@
|
||||
(let [only-yours (boolean (obj/get criteria "onlyYours" false))
|
||||
show-resolved (boolean (obj/get criteria "showResolved" true))
|
||||
user-id (-> @st/state :profile :id)]
|
||||
(p/create
|
||||
(js/Promise.
|
||||
(fn [resolve reject]
|
||||
(cond
|
||||
(not (r/check-permission $plugin "comment:read"))
|
||||
|
||||
@@ -52,8 +52,7 @@
|
||||
[app.util.object :as obj]
|
||||
[app.util.path.format :as upf]
|
||||
[beicon.v2.core :as rx]
|
||||
[cuerdas.core :as str]
|
||||
[promesa.core :as p]))
|
||||
[cuerdas.core :as str]))
|
||||
|
||||
(declare shape-proxy)
|
||||
(declare shape-proxy?)
|
||||
@@ -542,7 +541,7 @@
|
||||
:type (:type value :png)
|
||||
:suffix (:suffix value "")
|
||||
:scale (:scale value 1)}]}]
|
||||
(p/create
|
||||
(js/Promise.
|
||||
(fn [resolve reject]
|
||||
(->> (rp/cmd! :export payload)
|
||||
(rx/mapcat #(rp/cmd! :export {:cmd :get-resource :wait true :id (:id %) :blob? true}))
|
||||
|
||||
@@ -12,8 +12,7 @@
|
||||
[app.common.types.container :as ctn]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.main.store :as st]
|
||||
[app.util.object :as obj]
|
||||
[promesa.core :as p]))
|
||||
[app.util.object :as obj]))
|
||||
|
||||
(defn locate-file
|
||||
[id]
|
||||
@@ -175,7 +174,7 @@
|
||||
[]
|
||||
(let [ret-v (atom nil)
|
||||
ret-p
|
||||
(p/create
|
||||
(js/Promise.
|
||||
(fn [resolve _]
|
||||
(add-watch
|
||||
ret-v
|
||||
|
||||
Reference in New Issue
Block a user