mirror of
https://github.com/penpot/penpot.git
synced 2025-04-13 07:21:40 -05:00
commit
3d7df5b005
16 changed files with 1522 additions and 1208 deletions
File diff suppressed because it is too large
Load diff
|
@ -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
|
||||
|
|
43
frontend/src/app/main/data/plugins.cljs
Normal file
43
frontend/src/app/main/data/plugins.cljs
Normal 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))))))
|
|
@ -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)))))
|
||||
|
||||
|
|
|
@ -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}])])]]))
|
||||
|
||||
|
|
|
@ -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})))))))))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}]]]]]))
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 %)
|
||||
|
|
|
@ -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)))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Add table
Reference in a new issue