0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-04-13 07:21:40 -05:00

Merge pull request #5115 from penpot/alotor-plugins

Plugins update
This commit is contained in:
Andrey Antukh 2024-10-01 12:53:03 +02:00 committed by GitHub
commit 3d7df5b005
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 1522 additions and 1208 deletions

File diff suppressed because it is too large Load diff

View file

@ -941,7 +941,7 @@
(update-in [:dashboard-projects project-id :count] inc)))))
(defn create-file
[{:keys [project-id] :as params}]
[{:keys [project-id name] :as params}]
(dm/assert! (uuid? project-id))
(ptk/reify ::create-file
ev/Event
@ -955,7 +955,7 @@
files (get state :dashboard-files)
unames (cfh/get-used-names files)
name (cfh/generate-unique-name unames (str (tr "dashboard.new-file-prefix") " 1"))
name (or name (cfh/generate-unique-name unames (str (tr "dashboard.new-file-prefix") " 1")))
features (-> (features/get-team-enabled-features state)
(set/difference cfeat/frontend-only-features))
params (-> params

View file

@ -0,0 +1,43 @@
;; 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.data.plugins
(:require
[app.plugins.register :as pr]
[app.util.globals :as ug]
[beicon.v2.core :as rx]
[potok.v2.core :as ptk]))
(defn open-plugin!
[{:keys [plugin-id name description host code icon permissions]}]
(try
(.ɵloadPlugin
^js ug/global
#js {:pluginId plugin-id
:name name
:description description
:host host
:code code
:icon icon
:permissions (apply array permissions)})
(catch :default e
(.error js/console "Error" e))))
(defn delay-open-plugin
[plugin]
(ptk/reify ::delay-open-plugin
ptk/UpdateEvent
(update [_ state]
(assoc state ::open-plugin (:plugin-id plugin)))))
(defn check-open-plugin
[]
(ptk/reify ::check-open-plugin
ptk/WatchEvent
(watch [_ state _]
(when-let [pid (::open-plugin state)]
(open-plugin! (pr/get-plugin pid))
(rx/of #(dissoc % ::open-plugin))))))

View file

@ -42,6 +42,7 @@
[app.main.data.modal :as modal]
[app.main.data.notifications :as ntf]
[app.main.data.persistence :as dps]
[app.main.data.plugins :as dp]
[app.main.data.users :as du]
[app.main.data.workspace.bool :as dwb]
[app.main.data.workspace.collapse :as dwco]
@ -131,6 +132,7 @@
(when (and (not (boolean (-> state :profile :props :v2-info-shown)))
(features/active-feature? state "components/v2"))
(modal/show :v2-info {}))
(dp/check-open-plugin)
(fdf/fix-deleted-fonts)
(fbs/fix-broken-shapes)))))

View file

@ -8,10 +8,15 @@
(:require-macros [app.main.style :as stl])
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.spec :as us]
[app.config :as cf]
[app.main.data.dashboard :as dd]
[app.main.data.dashboard.shortcuts :as sc]
[app.main.data.events :as ev]
[app.main.data.modal :as modal]
[app.main.data.notifications :as notif]
[app.main.data.plugins :as dp]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.context :as ctx]
@ -25,11 +30,17 @@
[app.main.ui.dashboard.team :refer [team-settings-page team-members-page team-invitations-page team-webhooks-page]]
[app.main.ui.dashboard.templates :refer [templates-section]]
[app.main.ui.hooks :as hooks]
[app.main.ui.workspace.plugins]
[app.plugins.register :as preg]
[app.util.dom :as dom]
[app.util.http :as http]
[app.util.keyboard :as kbd]
[app.util.object :as obj]
[app.util.router :as rt]
[beicon.v2.core :as rx]
[goog.events :as events]
[okulary.core :as l]
[potok.v2.core :as ptk]
[rumext.v2 :as mf]))
(defn ^boolean uuid-str?
@ -143,6 +154,70 @@
(def dashboard-initialized
(l/derived :current-team-id st/state))
(defn use-plugin-register
[plugin-url team-id project-id]
(let [navegate-file!
(fn [plugin {:keys [project-id id data]}]
(st/emit!
(dp/delay-open-plugin plugin)
(rt/nav :workspace
{:project-id project-id :file-id id}
{:page-id (dm/get-in data [:pages 0])})))
create-file!
(fn [plugin]
(st/emit!
(modal/hide)
(let [data
(with-meta
{:project-id project-id
:name (dm/str "Try plugin: " (:name plugin))}
{:on-success (partial navegate-file! plugin)})]
(-> (dd/create-file data)
(with-meta {::ev/origin "plugin-try-out"})))))
open-try-out-dialog
(fn [plugin]
(modal/show
:plugin-try-out
{:plugin plugin
:on-accept #(create-file! plugin)
:on-close #(modal/hide!)}))
open-permissions-dialog
(fn [plugin]
(modal/show!
:plugin-permissions
{:plugin plugin
:on-accept
#(do (preg/install-plugin! plugin)
(st/emit! (modal/hide)
(rt/nav :dashboard-projects {:team-id team-id})
(open-try-out-dialog plugin)))
:on-close
#(st/emit! (modal/hide)
(rt/nav :dashboard-projects {:team-id team-id}))}))]
(mf/with-layout-effect
[plugin-url team-id project-id]
(when plugin-url
(->> (http/send! {:method :get
:uri plugin-url
:omit-default-headers true
:response-type :json})
(rx/map :body)
(rx/subs!
(fn [body]
(if-let [plugin (preg/parse-manifest plugin-url body)]
(do
(st/emit! (ptk/event ::ev/event {::ev/name "install-plugin" :name (:name plugin) :url plugin-url}))
(open-permissions-dialog plugin))
(st/emit! (notif/error "Cannot parser the plugin manifest"))))
(fn [_]
(st/emit! (notif/error "The plugin URL is incorrect")))))))))
(mf/defc dashboard
{::mf/props :obj}
[{:keys [route profile]}]
@ -150,8 +225,12 @@
params (parse-params route)
project-id (:project-id params)
team-id (:team-id params)
search-term (:search-term params)
plugin-url (-> route :query-params :plugin)
invite-email (-> route :query-params :invite-email)
teams (mf/deref refs/teams)
@ -160,6 +239,8 @@
projects (mf/deref refs/dashboard-projects)
project (get projects project-id)
default-project (->> projects vals (d/seek :is-default))
initialized? (mf/deref dashboard-initialized)]
(hooks/use-shortcuts ::dashboard sc/shortcuts)
@ -178,6 +259,8 @@
(fn []
(events/unlistenByKey key))))
(use-plugin-register plugin-url team-id (:id default-project))
[:& (mf/provider ctx/current-team-id) {:value team-id}
[:& (mf/provider ctx/current-project-id) {:value project-id}
;; NOTE: dashboard events and other related functions assumes
@ -206,4 +289,3 @@
:search-term search-term
:team team
:invite-email invite-email}])])]]))

View file

@ -8,6 +8,7 @@
(:require
[app.common.data.macros :as dm]
[app.common.spec :as us]
[app.common.uri :as u]
[app.common.uuid :as uuid]
[app.config :as cf]
[app.main.data.users :as du]
@ -16,6 +17,7 @@
[app.util.router :as rt]
[beicon.v2.core :as rx]
[cljs.spec.alpha :as s]
[cuerdas.core :as str]
[potok.v2.core :as ptk]))
(s/def ::page-id ::us/uuid)
@ -94,10 +96,11 @@
(defn on-navigate
[router path]
(let [location (.-location js/document)
[base-path qs] (str/split path "?")
location-path (dm/str (.-origin location) (.-pathname location))
valid-location? (= location-path (dm/str cf/public-uri))
match (match-path router path)
empty-path? (or (= path "") (= path "/"))]
empty-path? (or (= base-path "") (= base-path "/"))]
(cond
(not valid-location?)
(st/emit! (rt/assign-exception {:type :not-found}))
@ -116,7 +119,7 @@
(st/emit! (rt/nav :auth-login))
empty-path?
(st/emit! (rt/nav :dashboard-projects {:team-id (du/get-current-team-id profile)}))
(st/emit! (rt/nav :dashboard-projects {:team-id (du/get-current-team-id profile)} (u/query-string->map qs)))
:else
(st/emit! (rt/assign-exception {:type :not-found})))))))))

View file

@ -16,6 +16,7 @@
[app.main.data.events :as ev]
[app.main.data.exports :as de]
[app.main.data.modal :as modal]
[app.main.data.plugins :as dp]
[app.main.data.shortcuts :as scd]
[app.main.data.users :as du]
[app.main.data.workspace :as dw]
@ -29,7 +30,6 @@
[app.main.ui.context :as ctx]
[app.main.ui.hooks.resize :as r]
[app.main.ui.icons :as i]
[app.main.ui.workspace.plugins :as uwp]
[app.plugins.register :as preg]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
@ -637,7 +637,7 @@
::ev/origin "workspace:menu"
:name name
:host host}))
(uwp/open-plugin! manifest))
(dp/open-plugin! manifest))
:class (stl/css :submenu-item)
:on-key-down (fn [event]
(when (kbd/enter? event)
@ -646,7 +646,7 @@
::ev/origin "workspace:menu"
:name name
:host host}))
(uwp/open-plugin! manifest))))}
(dp/open-plugin! manifest))))}
[:span {:class (stl/css :item-name)} name]])])))
(mf/defc menu

View file

@ -12,6 +12,7 @@
[app.config :as cf]
[app.main.data.events :as ev]
[app.main.data.modal :as modal]
[app.main.data.plugins :as dp]
[app.main.store :as st]
[app.main.ui.components.search-bar :refer [search-bar]]
[app.main.ui.components.title-bar :refer [title-bar]]
@ -59,22 +60,6 @@
[:button {:class (stl/css :trash-button)
:on-click handle-delete-click} i/delete]]))
(defn open-plugin!
[{:keys [plugin-id name description host code icon permissions]}]
(try
(.ɵloadPlugin
js/window
#js {:pluginId plugin-id
:name name
:description description
:host host
:code code
:icon icon
:permissions (apply array permissions)})
(catch :default e
(.error js/console "Error" e))))
(mf/defc plugin-management-dialog
{::mf/register modal/components
::mf/register-as :plugin-management}
@ -144,7 +129,7 @@
::ev/origin "workspace:plugins"
:name (:name manifest)
:host (:host manifest)}))
(open-plugin! manifest)
(dp/open-plugin! manifest)
(modal/hide!)))
handle-remove-plugin
@ -215,7 +200,7 @@
(mf/defc plugins-permissions-dialog
{::mf/register modal/components
::mf/register-as :plugin-permissions}
[{:keys [plugin on-accept]}]
[{:keys [plugin on-accept on-close]}]
(let [{:keys [host permissions]} plugin
permissions (set permissions)
@ -224,25 +209,26 @@
(mf/use-callback
(fn [event]
(dom/prevent-default event)
(st/emit! (modal/hide))
(ptk/event ::ev/event {::ev/name "allow-plugin-permissions"
:host host
:permissions (->> permissions (str/join ", "))})
(on-accept)))
(st/emit! (ptk/event ::ev/event {::ev/name "allow-plugin-permissions"
:host host
:permissions (->> permissions (str/join ", "))})
(modal/hide))
(when on-accept (on-accept))))
handle-close-dialog
(mf/use-callback
(fn [event]
(dom/prevent-default event)
(ptk/event ::ev/event {::ev/name "reject-plugin-permissions"
:host host
:permissions (->> permissions (str/join ", "))})
(st/emit! (modal/hide))))]
(st/emit! (ptk/event ::ev/event {::ev/name "reject-plugin-permissions"
:host host
:permissions (->> permissions (str/join ", "))})
(modal/hide))
(when on-close (on-close))))]
[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-dialog :plugin-permissions)}
[:button {:class (stl/css :close-btn) :on-click handle-close-dialog} close-icon]
[:div {:class (stl/css :modal-title)} (tr "workspace.plugins.permissions.title")]
[:div {:class (stl/css :modal-title)} (tr "workspace.plugins.permissions.title" (str/upper (:name plugin)))]
[:div {:class (stl/css :modal-content)}
[:div {:class (stl/css :permissions-list)}
@ -277,7 +263,27 @@
[:div {:class (stl/css :permissions-list-entry)}
i/oauth-3
[:p {:class (stl/css :permissions-list-text)}
(tr "workspace.plugins.permissions.library-read")]])]
(tr "workspace.plugins.permissions.library-read")]])
(cond
(contains? permissions "comment:write")
[:div {:class (stl/css :permissions-list-entry)}
i/oauth-1
[:p {:class (stl/css :permissions-list-text)}
(tr "workspace.plugins.permissions.comment-write")]]
(contains? permissions "comment:read")
[:div {:class (stl/css :permissions-list-entry)}
i/oauth-1
[:p {:class (stl/css :permissions-list-text)}
(tr "workspace.plugins.permissions.comment-read")]])
(cond
(contains? permissions "allow:downloads")
[:div {:class (stl/css :permissions-list-entry)}
i/oauth-1
[:p {:class (stl/css :permissions-list-text)}
(tr "workspace.plugins.permissions.allow-download")]])]
[:div {:class (stl/css :permissions-disclaimer)}
(tr "workspace.plugins.permissions.disclaimer")]]
@ -295,3 +301,55 @@
:type "button"
:value (tr "ds.confirm-allow")
:on-click handle-accept-dialog}]]]]]))
(mf/defc plugins-try-out-dialog
{::mf/register modal/components
::mf/register-as :plugin-try-out}
[{:keys [plugin on-accept on-close]}]
(let [{:keys [icon host name]} plugin
handle-accept-dialog
(mf/use-callback
(fn [event]
(dom/prevent-default event)
(st/emit! (ptk/event ::ev/event {::ev/name "try-out-accept"})
(modal/hide))
(when on-accept (on-accept))))
handle-close-dialog
(mf/use-callback
(fn [event]
(dom/prevent-default event)
(st/emit! (ptk/event ::ev/event {::ev/name "try-out-cancel"})
(modal/hide))
(when on-close (on-close))))]
[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-dialog :plugin-try-out)}
[:button {:class (stl/css :close-btn) :on-click handle-close-dialog} close-icon]
[:div {:class (stl/css :modal-title)}
[:div {:class (stl/css :plugin-icon)}
[:img {:src (if (some? icon)
(dm/str host icon)
(avatars/generate {:name name}))}]]
(tr "workspace.plugins.try-out.title" (str/upper (:name plugin)))]
[:div {:class (stl/css :modal-content)}
[:div {:class (stl/css :modal-message)}
(tr "workspace.plugins.try-out.message")]]
[:div {:class (stl/css :modal-footer)}
[:div {:class (stl/css :action-buttons)}
[:input
{:class (stl/css :cancel-button :button-expand)
:type "button"
:value (tr "workspace.plugins.try-out.cancel")
:on-click handle-close-dialog}]
[:input
{:class (stl/css :primary-button :button-expand)
:type "button"
:value (tr "workspace.plugins.try-out.try")
:on-click handle-accept-dialog}]]]]]))

View file

@ -14,6 +14,7 @@
@extend .modal-container-base;
display: grid;
grid-template-rows: auto 1fr auto;
max-height: initial;
&.plugin-permissions {
width: $s-412;
@ -25,6 +26,11 @@
max-width: $s-472;
}
&.plugin-try-out {
width: $s-452;
max-width: $s-452;
}
hr {
border-color: var(--color-background-tertiary);
}
@ -47,6 +53,8 @@
@include headlineMediumTypography;
margin-block-end: $s-32;
color: var(--modal-title-foreground-color);
display: flex;
gap: $s-12;
}
.modal-content {
@ -63,6 +71,11 @@
}
}
.modal-message {
font-size: $fs-14;
color: var(--color-foreground-secondary);
}
.primary-button {
@extend .button-primary;
@include headlineSmallTypography;
@ -253,8 +266,8 @@ div.input-error {
.permissions-disclaimer {
@include bodySmallTypography;
padding: $s-16;
background: var(--color-background-tertiary);
color: var(--color-foreground-secondary);
background: var(--color-background-quaternary);
color: var(--color-foreground-quaternary);
border-radius: $br-4;
}

View file

@ -76,18 +76,15 @@
(getFile
[_]
(file/file-proxy $plugin (:current-file-id @st/state)))
(when (some? (:current-file-id @st/state))
(file/file-proxy $plugin (:current-file-id @st/state))))
(getPage
[_]
(let [file-id (:current-file-id @st/state)
page-id (:current-page-id @st/state)]
(page/page-proxy $plugin file-id page-id)))
(getSelected
[_]
(let [selection (get-in @st/state [:workspace-local :selected])]
(apply array (map str selection))))
(when (and (some? file-id) (some? page-id))
(page/page-proxy $plugin file-id page-id))))
(getSelectedShapes
[_]
@ -143,7 +140,9 @@
(getRoot
[_]
(shape/shape-proxy $plugin uuid/zero))
(when (and (some? (:current-file-id @st/state))
(some? (:current-page-id @st/state)))
(shape/shape-proxy $plugin uuid/zero)))
(getTheme
[_]
@ -444,6 +443,7 @@
{:name "root" :get #(.getRoot ^js %)}
{:name "currentFile" :get #(.getFile ^js %)}
{:name "currentPage" :get #(.getPage ^js %)}
{:name "theme" :get #(.getTheme ^js %)}
{:name "selection"
:get #(.getSelectedShapes ^js %)

View file

@ -27,9 +27,16 @@
(remove [_]
(p/create
(fn [resolve reject]
(->> (rp/cmd! :delete-comment {:id $id})
(rx/tap #(st/emit! (dc/retrieve-comment-threads $file)))
(rx/subs! #(resolve) reject))))))
(cond
(not (r/check-permission $plugin "comment:write"))
(do
(u/display-not-valid :remove "Plugin doesn't have 'comment:write' permission")
(reject "Plugin doesn't have 'comment:write' permission"))
:else
(->> (rp/cmd! :delete-comment {:id $id})
(rx/tap #(st/emit! (dc/retrieve-comment-threads $file)))
(rx/subs! #(resolve) reject)))))))
(defn comment-proxy? [p]
(instance? CommentProxy p))
@ -60,8 +67,8 @@
(not= (:id profile) (:owner-id data))
(u/display-not-valid :content "Cannot change content from another user's comments")
(not (r/check-permission plugin-id "content:write"))
(u/display-not-valid :content "Plugin doesn't have 'content:write' permission")
(not (r/check-permission plugin-id "comment:write"))
(u/display-not-valid :content "Plugin doesn't have 'comment:write' permission")
:else
(->> (rp/cmd! :update-comment {:id (:id data) :content content})
@ -74,22 +81,29 @@
[_]
(p/create
(fn [resolve reject]
(->> (rp/cmd! :get-comments {:thread-id $id})
(rx/subs!
(fn [comments]
(resolve
(format/format-array
#(comment-proxy $plugin $file $page $id $users %) comments)))
reject)))))
(cond
(not (r/check-permission $plugin "comment:read"))
(do
(u/display-not-valid :findComments "Plugin doesn't have 'comment:read' permission")
(reject "Plugin doesn't have 'comment:read' permission"))
:else
(->> (rp/cmd! :get-comments {:thread-id $id})
(rx/subs!
(fn [comments]
(resolve
(format/format-array
#(comment-proxy $plugin $file $page $id $users %) comments)))
reject))))))
(reply
[_ content]
(cond
(not (r/check-permission $plugin "content:write"))
(u/display-not-valid :content "Plugin doesn't have 'content:write' permission")
(not (r/check-permission $plugin "comment:write"))
(u/display-not-valid :reply "Plugin doesn't have 'comment:write' permission")
(or (not (string? content)) (empty? content))
(u/display-not-valid :content "Not valid")
(u/display-not-valid :reply "Not valid")
:else
(p/create
@ -100,11 +114,11 @@
(remove [_]
(let [profile (:profile @st/state)]
(cond
(not (r/check-permission $plugin "content:write"))
(u/display-not-valid :removeCommentThread "Plugin doesn't have 'content:write' permission")
(not (r/check-permission $plugin "comment:write"))
(u/display-not-valid :remove "Plugin doesn't have 'comment:write' permission")
(not= (:id profile) owner)
(u/display-not-valid :content "Cannot change content from another user's comments")
(u/display-not-valid :remove "Cannot change content from another user's comments")
:else
(p/create
@ -140,8 +154,8 @@
(or (not (us/safe-number? (:x position))) (not (us/safe-number? (:y position))))
(u/display-not-valid :position "Not valid point")
(not (r/check-permission plugin-id "content:write"))
(u/display-not-valid :content "Plugin doesn't have 'content:write' permission")
(not (r/check-permission plugin-id "comment:write"))
(u/display-not-valid :position "Plugin doesn't have 'comment:write' permission")
:else
(do (st/emit! (dwc/update-comment-thread-position @data* [(:x position) (:y position)]))
@ -155,8 +169,8 @@
(not (boolean? is-resolved))
(u/display-not-valid :resolved "Not a boolean type")
(not (r/check-permission plugin-id "content:write"))
(u/display-not-valid :resolved "Plugin doesn't have 'content:write' permission")
(not (r/check-permission plugin-id "comment:write"))
(u/display-not-valid :resolved "Plugin doesn't have 'comment:write' permission")
:else
(do (st/emit! (dc/update-comment-thread (assoc @data* :is-resolved is-resolved)))

View file

@ -258,7 +258,7 @@
(u/display-not-valid :removeRulerGuide "Guide not provided")
(not (r/check-permission $plugin "content:write"))
(u/display-not-valid :removeRulerGuide "Plugin doesn't have 'content:write' permission")
(u/display-not-valid :removeRulerGuide "Plugin doesn't have 'comment:write' permission")
:else
(let [guide (u/proxy->ruler-guide value)]
@ -279,8 +279,8 @@
(and (some? board) (or (not (shape/shape-proxy? board)) (not (cfh/frame-shape? shape))))
(u/display-not-valid :addCommentThread "Board not valid")
(not (r/check-permission $plugin "content:write"))
(u/display-not-valid :addCommentThread "Plugin doesn't have 'content:write' permission")
(not (r/check-permission $plugin "comment:write"))
(u/display-not-valid :addCommentThread "Plugin doesn't have 'comment:write' permission")
:else
(let [position
@ -311,7 +311,7 @@
(not (pc/comment-thread-proxy? thread))
(u/display-not-valid :removeCommentThread "Comment thread not valid")
(not (r/check-permission $plugin "content:write"))
(not (r/check-permission $plugin "comment:write"))
(u/display-not-valid :removeCommentThread "Plugin doesn't have 'content:write' permission")
:else
@ -328,23 +328,30 @@
user-id (-> @st/state :profile :id)]
(p/create
(fn [resolve reject]
(->> (rx/zip (rp/cmd! :get-team-users {:file-id $file})
(rp/cmd! :get-comment-threads {:file-id $file}))
(rx/take 1)
(rx/subs!
(fn [[users comments]]
(let [users (d/index-by :id users)
comments
(cond->> comments
(not show-resolved)
(filter (comp not :is-resolved))
(cond
(not (r/check-permission $plugin "comment:read"))
(do
(u/display-not-valid :findCommentThreads "Plugin doesn't have 'comment:read' permission")
(reject "Plugin doesn't have 'comment:read' permission"))
only-yours
(filter #(contains? (:participants %) user-id)))]
(resolve
(format/format-array
#(pc/comment-thread-proxy $plugin $file $id users %) comments))))
reject)))))))
:else
(->> (rx/zip (rp/cmd! :get-team-users {:file-id $file})
(rp/cmd! :get-comment-threads {:file-id $file}))
(rx/take 1)
(rx/subs!
(fn [[users comments]]
(let [users (d/index-by :id users)
comments
(cond->> comments
(not show-resolved)
(filter (comp not :is-resolved))
only-yours
(filter #(contains? (:participants %) user-id)))]
(resolve
(format/format-array
#(pc/comment-thread-proxy $plugin $file $id users %) comments))))
reject))))))))
(crc/define-properties!
PageProxy

View file

@ -5,7 +5,6 @@
;; Copyright (c) KALEIDOS INC
(ns app.plugins.register
"RPC for plugins runtime."
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
@ -26,6 +25,10 @@
(->> (:ids @registry)
(mapv #(dm/get-in @registry [:data %]))))
(defn get-plugin
[id]
(dm/get-in @registry [:data id]))
(defn parse-manifest
"Read the manifest.json defined by the plugins definition and transforms it into an
object that will be stored in the register."
@ -42,7 +45,10 @@
(conj "content:read")
(contains? permissions "library:write")
(conj "content:write"))
(conj "content:write")
(contains? permissions "comment:write")
(conj "comment:read"))
origin (obj/get (js/URL. plugin-url) "origin")

View file

@ -987,7 +987,7 @@
:get (fn [self]
(let [shape (u/proxy->shape self)
parent-id (:parent-id shape)]
(shape-proxy (obj/get self "$file") (obj/get self "$page") parent-id)))}
(shape-proxy plugin-id (obj/get self "$file") (obj/get self "$page") parent-id)))}
{:name "parentX"
:get (fn [self]
(let [shape (u/proxy->shape self)

View file

@ -5580,7 +5580,7 @@ msgstr "Read and modify the content of files that users have access to."
#: src/app/main/ui/workspace/plugins.cljs:274
msgid "workspace.plugins.permissions.disclaimer"
msgstr "Note that this plugin has been created by an external party."
msgstr "Please note that this plugin is created by an external party, so ensure you trust it before granting access. Your data privacy and security are important to us. If you have any concerns, please contact support."
#: src/app/main/ui/workspace/plugins.cljs:271
msgid "workspace.plugins.permissions.library-read"
@ -5590,14 +5590,35 @@ msgstr "Read your libraries and assets."
msgid "workspace.plugins.permissions.library-write"
msgstr "Read and modify your libraries and assets."
msgid "workspace.plugins.permissions.comment-read"
msgstr "Read your comments and replies."
msgid "workspace.plugins.permissions.comment-write"
msgstr "Read and modify your comments and reply in your name."
msgid "workspace.plugins.permissions.allow-download"
msgstr "Start file downloads."
#: src/app/main/ui/workspace/plugins.cljs:236
msgid "workspace.plugins.permissions.title"
msgstr "THIS PLUGIN WANTS ACCESS TO:"
msgstr "'%s' PLUGIN WANTS ACCESS TO:"
#: src/app/main/ui/workspace/plugins.cljs:258
msgid "workspace.plugins.permissions.user-read"
msgstr "Read the profile information of the current user."
msgid "workspace.plugins.try-out.title"
msgstr "'%s' PLUGIN IS INSTALLED FOR YOUR USER!"
msgid "workspace.plugins.try-out.message"
msgstr "Want to take a look? It will open in a new draft for your current team. (If not, you can always find it in the installed plugins of any file.)"
msgid "workspace.plugins.try-out.cancel"
msgstr "NOT NOW"
msgid "workspace.plugins.try-out.try"
msgstr "TRY PLUGIN"
#: src/app/main/ui/workspace/plugins.cljs:192
msgid "workspace.plugins.plugin-list-link"
msgstr "Plugins List"

View file

@ -5567,7 +5567,7 @@ msgstr "Leer y modificar el contenido de sus archivos."
#: src/app/main/ui/workspace/plugins.cljs:274
msgid "workspace.plugins.permissions.disclaimer"
msgstr "Tenga en cuenta que esta extensión ha sido desarrollada por terceros."
msgstr "Ten en cuenta que las extensiones están desarrolladas por terceros, aseguraté que confías antes de conceder el permiso. Tu privacidad y seguridad es importante para nosotros. Si tienes cualquier duda, contacta con soporte."
#: src/app/main/ui/workspace/plugins.cljs:271
msgid "workspace.plugins.permissions.library-read"
@ -5577,14 +5577,35 @@ msgstr "Leer la información de sus bibliotecas y recursos."
msgid "workspace.plugins.permissions.library-write"
msgstr "Leer y modificar la información de sus bibliotecas y recursos."
msgid "workspace.plugins.permissions.comment-read"
msgstr "Leer tus comentarios y respuestas."
msgid "workspace.plugins.permissions.comment-write"
msgstr "Leer y modificar tus comentarios y responder en tu nombre."
msgid "workspace.plugins.permissions.allow-download"
msgstr "Comenzar descargas de ficheros."
#: src/app/main/ui/workspace/plugins.cljs:236
msgid "workspace.plugins.permissions.title"
msgstr "LA EXTENSIÓN SOLICITA PERMISO PARA ACCEDER:"
msgstr "LA EXTENSIÓN '%s' SOLICITA PERMISO PARA ACCEDER:"
#: src/app/main/ui/workspace/plugins.cljs:258
msgid "workspace.plugins.permissions.user-read"
msgstr "Leer la información del usuario actual."
msgid "workspace.plugins.try-out.title"
msgstr "¡LA EXTENSIÓN '%s' HA SIDO INSTALADA PARA TU USUARIO!"
msgid "workspace.plugins.try-out.message"
msgstr "¿Quieres echar un vistazo?. Crearemos un nuevo borrador en tu equipo actual. (Si no, puedes encontrar los plugins instalados en cualquier fichero.)"
msgid "workspace.plugins.try-out.cancel"
msgstr "AHORA NO"
msgid "workspace.plugins.try-out.try"
msgstr "PROBAR PLUGIN"
#: src/app/main/ui/workspace/plugins.cljs:192
msgid "workspace.plugins.plugin-list-link"
msgstr "Lista de extensiones"