0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-27 23:21:47 -05:00

🎉 Allow import a template from a link

This commit is contained in:
Pablo Alba 2025-01-13 19:43:47 +01:00 committed by Alonso Torres
parent 0d70ceb264
commit 2f5f31814a
6 changed files with 103 additions and 20 deletions

View file

@ -111,6 +111,7 @@
(def grid-help-uri (obj/get global "penpotGridHelpURI" "https://help.penpot.app/user-guide/flexible-layouts/"))
(def plugins-list-uri (obj/get global "penpotPluginsListUri" "https://penpot.app/penpothub/plugins"))
(def plugins-whitelist (into #{} (obj/get global "penpotPluginsWhitelist" [])))
(def templates-uri (obj/get global "penpotTemplatesUri" "https://penpot.github.io/penpot-files/"))
(defn- normalize-uri
[uri-str]

View file

@ -70,7 +70,7 @@
(mf/defc dashboard-legacy-redirect*
{::mf/props :obj
::mf/private true}
[{:keys [section team-id project-id search-term plugin-url]}]
[{:keys [section team-id project-id search-term plugin-url template-url]}]
(let [section (case section
:dashboard-legacy-search
:dashboard-search
@ -97,7 +97,8 @@
(let [params {:team-id team-id
:project-id project-id
:search-term search-term
:plugin plugin-url}]
:plugin plugin-url
:template-url template-url}]
(st/emit! (rt/nav section (d/without-nils params)))))
[:> loader*
@ -211,11 +212,12 @@
:dashboard-invitations
:dashboard-webhooks
:dashboard-settings)
(let [params (get params :query)
team-id (some-> params :team-id uuid)
project-id (some-> params :project-id uuid)
search-term (some-> params :search-term)
plugin-url (some-> params :plugin)]
(let [params (get params :query)
team-id (some-> params :team-id uuid)
project-id (some-> params :project-id uuid)
search-term (some-> params :search-term)
plugin-url (some-> params :plugin)
template-url (some-> params :template)]
[:?
#_[:& app.main.ui.releases/release-notes-modal {:version "2.4"}]
#_[:& app.main.ui.onboarding/onboarding-templates-modal]
@ -241,7 +243,8 @@
:team-id team-id
:search-term search-term
:plugin-url plugin-url
:project-id project-id}]]])
:project-id project-id
:template-url template-url}]]])
:workspace
(let [params (get params :query)
@ -322,13 +325,15 @@
(let [team-id (some-> params :path :team-id uuid)
project-id (some-> params :path :project-id uuid)
search-term (some-> params :query :search-term)
plugin-url (some-> params :query :plugin)]
plugin-url (some-> params :query :plugin)
template-url (some-> params :template)]
[:> dashboard-legacy-redirect*
{:team-id team-id
:section section
:project-id project-id
:search-term search-term
:plugin-url plugin-url}])
:plugin-url plugin-url
:template-url template-url}])
:viewer-legacy
(let [{:keys [query-params path-params]} route

View file

@ -15,6 +15,7 @@
[app.main.data.modal :as modal]
[app.main.data.notifications :as notif]
[app.main.data.plugins :as dp]
[app.main.data.project :as dpj]
[app.main.refs :as refs]
[app.main.router :as rt]
[app.main.store :as st]
@ -33,9 +34,14 @@
[app.main.ui.workspace.plugins]
[app.plugins.register :as preg]
[app.util.dom :as dom]
[app.util.http :as http]
[app.util.i18n :refer [tr]]
[app.util.keyboard :as kbd]
[app.util.object :as obj]
[app.util.storage :as storage]
[app.util.webapi :as wapi]
[beicon.v2.core :as rx]
[cuerdas.core :as str]
[goog.events :as events]
[okulary.core :as l]
[potok.v2.core :as ptk]
@ -205,9 +211,47 @@
(fn [_]
(st/emit! (notif/error "The plugin URL is incorrect")))))))))
(defn use-templates-import
[can-edit? template-url default-project-id]
(mf/with-layout-effect
[can-edit? template-url default-project-id]
(when (and (some? template-url) (some? default-project-id))
(if can-edit?
(let [valid-url? (and (str/ends-with? template-url ".penpot")
(str/starts-with? template-url cf/templates-uri))
template-name (when valid-url? (subs template-url (count cf/templates-uri)))
on-import #(st/emit! (dpj/fetch-files default-project-id)
(dd/fetch-recent-files)
(dd/fetch-projects)
(dd/clear-selected-files)
(ptk/event ::ev/event {::ev/name "install-template-from-link-finished"
:name template-name
:url template-url}))]
(if valid-url?
(do
(st/emit! (ptk/event ::ev/event {::ev/name "install-template-from-link" :name template-name :url template-url}))
(->> (http/send! {:method :get
:uri template-url
:response-type :blob
:omit-default-headers true})
(rx/subs!
(fn [result]
(if (or (< (:status result) 200) (>= (:status result) 300))
(st/emit! (notif/error (tr "dashboard.import.error")))
(st/emit! (modal/show
{:type :import
:project-id default-project-id
:entries [{:name template-name :uri (wapi/create-uri (:body result))}]
:on-finish-import on-import})))))))
(st/emit! (notif/error (tr "dashboard.import.bad-url")))))
(st/emit! (notif/error (tr "dashboard.import.no-perms"))))
(binding [storage/*sync* true]
(swap! storage/session dissoc :template-url)))))
(mf/defc dashboard*
{::mf/props :obj}
[{:keys [profile project-id team-id search-term plugin-url section]}]
[{:keys [profile project-id team-id search-term plugin-url template-url section]}]
(let [team (mf/deref refs/team)
projects (mf/deref refs/projects)
@ -216,6 +260,9 @@
(->> (vals projects)
(filterv #(= team-id (:team-id %)))))
can-edit? (dm/get-in team [:permissions :can-edit])
template-url (or template-url (:template-url storage/session))
default-project
(mf/with-memo [projects]
(->> projects
@ -239,6 +286,7 @@
(events/unlistenByKey key))))
(use-plugin-register plugin-url team-id (:id default-project))
(use-templates-import can-edit? template-url (:id default-project))
[:& (mf/provider ctx/current-project-id) {:value project-id}
[:> modal-container*]

View file

@ -14,6 +14,7 @@
[app.main.repo :as rp]
[app.main.router :as rt]
[app.main.store :as st]
[app.util.storage :as storage]
[beicon.v2.core :as rx]
[cuerdas.core :as str]
[potok.v2.core :as ptk]))
@ -75,14 +76,23 @@
["/workspace" :workspace]
["/workspace/:project-id/:file-id" :workspace-legacy]])
(defn- store-session-params
[{:keys [template]}]
(binding [storage/*sync* true]
(when (some? template)
(swap! storage/session assoc
:template-url template))))
(defn on-navigate
[router path]
(let [location (.-location js/document)
[base-path qs] (str/split path "?")
location-path (dm/str (.-origin location) (.-pathname location))
(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 (rt/match router path)
empty-path? (or (= base-path "") (= base-path "/"))]
match (rt/match router path)
empty-path? (or (= base-path "") (= base-path "/"))
query-params (u/query-string->map qs)]
(cond
(not valid-location?)
@ -99,14 +109,15 @@
(rx/subs! (fn [{:keys [id] :as profile}]
(cond
(= id uuid/zero)
(st/emit! (rt/nav :auth-login))
(do
(store-session-params query-params)
(st/emit! (rt/nav :auth-login)))
empty-path?
(let [team-id (or (dtm/get-last-team-id)
(:default-team-id profile))]
(st/emit! (rt/nav :dashboard-recent
(-> (u/query-string->map qs)
(assoc :team-id team-id)))))
(assoc query-params :team-id team-id))))
:else
(st/emit! (rt/assign-exception {:type :not-found})))))))))

View file

@ -6966,6 +6966,15 @@ msgstr "None"
msgid "dashboard.settings.notifications.submit"
msgstr "Update settings"
msgid "dashboard.import.error"
msgstr "Import failed. Please try again"
msgid "dashboard.import.bad-url"
msgstr "Import failed. The template URL is incorrect"
msgid "dashboard.import.no-perms"
msgstr "You dont have permission to import to this team"
msgid "labels.notifications"
msgstr "Notifications"

View file

@ -6687,7 +6687,7 @@ msgstr "Nombre"
#: src/app/main/ui/workspace/tokens/form.cljs
msgid "workspace.token.enter-token-name"
msgstr "Introduce un nombre para el token %s"
msgstr "Introduce un nombre para el token %s"
#: src/app/main/ui/workspace/tokens/form.cljs
msgid "workspace.token.token-value"
@ -6923,6 +6923,15 @@ msgstr "Ninguna"
msgid "dashboard.settings.notifications.submit"
msgstr "Actualizar configuración"
msgid "dashboard.import.error"
msgstr "La importación ha fallado. Intentalo de nuevo, por favor"
msgid "dashboard.import.bad-url"
msgstr "La importación ha fallado. La URL de la plantilla es incorrecta"
msgid "dashboard.import.no-perms"
msgstr "No tienes permisos para importar en este equipo"
msgid "labels.notifications"
msgstr "Notificaciones"