mirror of
https://github.com/penpot/penpot.git
synced 2025-03-28 15:41:25 -05:00
✨ Components annotations
This commit is contained in:
parent
cd1825d97a
commit
68367b002e
19 changed files with 495 additions and 38 deletions
|
@ -78,7 +78,7 @@
|
|||
(update :data remove-not-allowed-pages (:pages perms))
|
||||
|
||||
:always
|
||||
(update :data select-keys [:id :options :pages :pages-index]))))))
|
||||
(update :data select-keys [:id :options :pages :pages-index :components]))))))
|
||||
|
||||
(s/def ::get-view-only-bundle
|
||||
(s/keys :req-un [::files/file-id]
|
||||
|
|
|
@ -639,11 +639,13 @@
|
|||
:id id
|
||||
:name (:name new-component)
|
||||
:path (:path new-component)
|
||||
:annotation (:annotation new-component)
|
||||
:objects (:objects new-component)}) ;; this won't exist in components-v2
|
||||
(update :undo-changes d/preconj {:type :mod-component
|
||||
:id id
|
||||
:name (:name prev-component)
|
||||
:path (:path prev-component)
|
||||
:annotation (:annotation prev-component)
|
||||
:objects (:objects prev-component)}))
|
||||
changes)))
|
||||
|
||||
|
|
|
@ -22,6 +22,8 @@
|
|||
(s/def ::page-id uuid?)
|
||||
(s/def ::component-id uuid?)
|
||||
(s/def ::name string?)
|
||||
(s/def ::path string?)
|
||||
(s/def ::annotation string?)
|
||||
|
||||
(defmulti operation-spec :type)
|
||||
|
||||
|
@ -158,7 +160,7 @@
|
|||
|
||||
(defmethod change-spec :mod-component [_]
|
||||
(s/keys :req-un [::id]
|
||||
:opt-un [::name :internal.changes.add-component/shapes]))
|
||||
:opt-un [::name ::path ::annotation :internal.changes.add-component/shapes]))
|
||||
|
||||
(s/def :internal.changes.del-component/skip-undelete? boolean?)
|
||||
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
:main-instance-page main-instance-page))))
|
||||
|
||||
(defn mod-component
|
||||
[file-data {:keys [id name path objects]}]
|
||||
[file-data {:keys [id name path objects annotation]}]
|
||||
(let [wrap-objects-fn feat/*wrap-with-objects-map-fn*]
|
||||
(update-in file-data [:components id]
|
||||
(fn [component]
|
||||
|
@ -58,7 +58,13 @@
|
|||
(assoc :path path)
|
||||
|
||||
(some? objects)
|
||||
(assoc :objects objects)))))))
|
||||
(assoc :objects objects)
|
||||
|
||||
(some? annotation)
|
||||
(assoc :annotation annotation)
|
||||
|
||||
(nil? annotation)
|
||||
(dissoc :annotation)))))))
|
||||
|
||||
(defn get-component
|
||||
([file-data component-id]
|
||||
|
|
|
@ -383,3 +383,15 @@
|
|||
.element-options > :first-child {
|
||||
border-top: none;
|
||||
}
|
||||
|
||||
.inspect-annotation {
|
||||
.content {
|
||||
background-color: $color-gray-60;
|
||||
color: $color-white;
|
||||
margin: 0 10px;
|
||||
padding: 10px;
|
||||
font-size: $fs14;
|
||||
overflow-wrap: anywhere;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2327,3 +2327,120 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.component-annotation {
|
||||
background-color: $color-gray-60;
|
||||
border: 1px solid $color-gray-60;
|
||||
&.editing {
|
||||
border: 1px solid $color-primary;
|
||||
}
|
||||
.title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
border-bottom: 1px solid $color-gray-50;
|
||||
font-size: $fs12;
|
||||
color: $color-gray-20;
|
||||
padding: 0 10px;
|
||||
|
||||
&.expandeable {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
line-height: 2.5;
|
||||
}
|
||||
|
||||
.expand {
|
||||
svg {
|
||||
fill: $color-gray-20;
|
||||
width: $size-2;
|
||||
height: $size-2;
|
||||
margin-right: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
.icon {
|
||||
display: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.icon {
|
||||
display: flex;
|
||||
svg {
|
||||
fill: $color-gray-20;
|
||||
width: $size-4;
|
||||
height: $size-4;
|
||||
margin-left: 15px;
|
||||
}
|
||||
|
||||
.icon-tick:hover,
|
||||
.icon-pencil:hover {
|
||||
fill: $color-primary;
|
||||
}
|
||||
|
||||
.icon-cross:hover,
|
||||
.icon-trash:hover {
|
||||
fill: $color-danger;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.counter {
|
||||
text-align: right;
|
||||
font-size: $fs11;
|
||||
color: $color-gray-30;
|
||||
margin: 0 10px 10px 0;
|
||||
}
|
||||
|
||||
// Auto growing text
|
||||
.grow-wrap {
|
||||
// easy way to plop the elements on top of each other and have them both sized based on the tallest one's height
|
||||
display: grid;
|
||||
|
||||
&:after {
|
||||
// The space is needed to preventy jumpy behavior
|
||||
content: attr(data-replicated-value) " ";
|
||||
white-space: pre-wrap;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
textarea {
|
||||
background-color: $color-gray-60;
|
||||
color: $color-white;
|
||||
min-height: 250px;
|
||||
padding: 10px;
|
||||
|
||||
border: none;
|
||||
overflow: hidden;
|
||||
outline: none;
|
||||
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
|
||||
resize: none; /*remove the resize handle on the bottom right*/
|
||||
}
|
||||
|
||||
textarea,
|
||||
&:after {
|
||||
/* Identical styling required!! */
|
||||
font: inherit;
|
||||
font-size: $fs14;
|
||||
overflow-wrap: anywhere;
|
||||
|
||||
padding: 10px;
|
||||
|
||||
/* Place on top of each other */
|
||||
grid-area: 1 / 1 / 2 / 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -141,6 +141,17 @@
|
|||
(rx/reduce conj {})
|
||||
(rx/map (fn [pages-index]
|
||||
(update-in bundle [:file :data] assoc :pages-index pages-index))))))
|
||||
(rx/mapcat
|
||||
(fn [bundle]
|
||||
(->> (rx/from (-> bundle :file :data seq))
|
||||
(rx/merge-map
|
||||
(fn [[_ object :as kp]]
|
||||
(if (t/pointer? object)
|
||||
(resolve kp)
|
||||
(rx/of kp))))
|
||||
(rx/reduce conj {})
|
||||
(rx/map (fn [data]
|
||||
(update bundle :file assoc :data data))))))
|
||||
(rx/mapcat
|
||||
(fn [{:keys [fonts] :as bundle}]
|
||||
(rx/of (df/fonts-fetched fonts)
|
||||
|
|
|
@ -2060,6 +2060,58 @@
|
|||
(update [_ state]
|
||||
(assoc-in state [:workspace-global :file-library-reverse-sort] reverse-sort?))))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Components annotations
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
(defn update-component-annotation
|
||||
"Update the component with the given annotation"
|
||||
[id annotation]
|
||||
(us/assert ::us/uuid id)
|
||||
(us/assert ::us/string annotation)
|
||||
(ptk/reify ::update-component-annotation
|
||||
ptk/WatchEvent
|
||||
(watch [it state _]
|
||||
|
||||
(let [data (get state :workspace-data)
|
||||
|
||||
update-fn
|
||||
(fn [component]
|
||||
;; NOTE: we need to ensure the component exists,
|
||||
;; because there are small possibilities of race
|
||||
;; conditions with component deletion.
|
||||
(when component
|
||||
(if (nil? annotation)
|
||||
(dissoc component :annotation)
|
||||
(assoc component :annotation annotation))))
|
||||
|
||||
changes (-> (pcb/empty-changes it)
|
||||
(pcb/with-library-data data)
|
||||
(pcb/update-component id update-fn))]
|
||||
|
||||
(rx/of (dch/commit-changes changes))))))
|
||||
|
||||
|
||||
|
||||
(defn set-annotations-expanded
|
||||
[expanded?]
|
||||
(ptk/reify ::set-annotations-expanded
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(assoc-in state [:workspace-annotations :expanded?] expanded?))))
|
||||
|
||||
(defn set-annotations-id-for-create
|
||||
[id]
|
||||
(ptk/reify ::set-annotations-id-for-create
|
||||
ptk/UpdateEvent
|
||||
(update [_ state]
|
||||
(if id
|
||||
(-> (assoc-in state [:workspace-annotations :id-for-create] id)
|
||||
(assoc-in [:workspace-annotations :expanded?] true))
|
||||
(d/dissoc-in state [:workspace-annotations :id-for-create])))))
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Exports
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
|
28
frontend/src/app/main/data/workspace/annotation_helpers.cljs
Normal file
28
frontend/src/app/main/data/workspace/annotation_helpers.cljs
Normal file
|
@ -0,0 +1,28 @@
|
|||
;; 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.workspace.annotation-helpers
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.logging :as log]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.main.refs :as refs]))
|
||||
|
||||
;; Change this to :info :debug or :trace to debug this module, or :warn to reset to default
|
||||
(log/set-level! :warn)
|
||||
|
||||
|
||||
(defn get-main-annotation
|
||||
[shape libraries]
|
||||
(let [library (dm/get-in libraries [(:component-file shape) :data])
|
||||
component (ctkl/get-component library (:component-id shape) true)]
|
||||
(:annotation component)))
|
||||
|
||||
(defn get-main-annotation-viewer
|
||||
[shape libraries]
|
||||
(let [objects (deref (refs/get-viewer-objects))
|
||||
parent (get objects (:parent-id shape))]
|
||||
(get-main-annotation parent libraries)))
|
|
@ -544,3 +544,9 @@
|
|||
[id]
|
||||
(l/derived #(get % id) workspace-grid-edition))
|
||||
|
||||
(def workspace-annotations
|
||||
(l/derived #(get % :workspace-annotations {}) st/state))
|
||||
|
||||
(def current-file-id
|
||||
(l/derived :current-file-id st/state))
|
||||
|
||||
|
|
19
frontend/src/app/main/ui/viewer/inspect/annotation.cljs
Normal file
19
frontend/src/app/main/ui/viewer/inspect/annotation.cljs
Normal file
|
@ -0,0 +1,19 @@
|
|||
;; 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.ui.viewer.inspect.annotation
|
||||
(:require
|
||||
[app.main.ui.components.copy-button :refer [copy-button]]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc annotation
|
||||
[{:keys [content] :as props}]
|
||||
[:div.attributes-block.inspect-annotation
|
||||
[:div.attributes-block-title
|
||||
[:div.attributes-block-title-text (tr "workspace.options.component.annotation")]
|
||||
[:& copy-button {:data content}]]
|
||||
[:div.content content]])
|
|
@ -7,7 +7,9 @@
|
|||
(ns app.main.ui.viewer.inspect.attributes
|
||||
(:require
|
||||
[app.common.geom.shapes :as gsh]
|
||||
[app.main.data.workspace.annotation-helpers :as dwah]
|
||||
[app.main.ui.hooks :as hooks]
|
||||
[app.main.ui.viewer.inspect.annotation :refer [annotation]]
|
||||
[app.main.ui.viewer.inspect.attributes.blur :refer [blur-panel]]
|
||||
[app.main.ui.viewer.inspect.attributes.fill :refer [fill-panel]]
|
||||
[app.main.ui.viewer.inspect.attributes.image :refer [image-panel]]
|
||||
|
@ -32,12 +34,17 @@
|
|||
:text [:layout :text :shadow :blur :stroke :layout-flex-item]})
|
||||
|
||||
(mf/defc attributes
|
||||
[{:keys [page-id file-id shapes frame from]}]
|
||||
[{:keys [page-id file-id shapes frame from libraries]}]
|
||||
(let [shapes (hooks/use-equal-memo shapes)
|
||||
shapes (mf/with-memo [shapes]
|
||||
(mapv #(gsh/translate-to-frame % frame) shapes))
|
||||
type (if (= (count shapes) 1) (-> shapes first :type) :multiple)
|
||||
options (type->options type)]
|
||||
options (type->options type)
|
||||
content (when (= (count shapes) 1)
|
||||
(if (= from :workspace)
|
||||
(dwah/get-main-annotation (first shapes) libraries)
|
||||
(dwah/get-main-annotation-viewer (first shapes) libraries)))]
|
||||
|
||||
[:div.element-options
|
||||
(for [[idx option] (map-indexed vector options)]
|
||||
[:> (case option
|
||||
|
@ -55,6 +62,8 @@
|
|||
:shapes shapes
|
||||
:frame frame
|
||||
:from from}])
|
||||
(when content
|
||||
[:& annotation {:content content}])
|
||||
[:& exports
|
||||
{:shapes shapes
|
||||
:type type
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
(ns app.main.ui.viewer.inspect.right-sidebar
|
||||
(:require
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.shape-icon :as si]
|
||||
[app.main.ui.components.tabs-container :refer [tabs-container tabs-element]]
|
||||
|
@ -18,6 +19,24 @@
|
|||
[app.util.i18n :refer [tr]]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(defn- get-libraries
|
||||
"Retrieve all libraries, including the local file, on workspace or viewer"
|
||||
[from]
|
||||
(if (= from :workspace)
|
||||
(let [workspace-data (deref refs/workspace-data)
|
||||
{:keys [id] :as local} workspace-data
|
||||
libraries (deref refs/workspace-libraries)]
|
||||
(-> libraries
|
||||
(assoc id {:id id
|
||||
:data local})))
|
||||
(let [viewer-data (deref refs/viewer-data)
|
||||
local (get-in viewer-data [:file :data])
|
||||
id (deref refs/current-file-id)
|
||||
libraries (:libraries viewer-data)]
|
||||
(-> libraries
|
||||
(assoc id {:id id
|
||||
:data local})))))
|
||||
|
||||
(mf/defc right-sidebar
|
||||
[{:keys [frame page file selected shapes page-id file-id from]
|
||||
:or {from :inspect}}]
|
||||
|
@ -28,7 +47,9 @@
|
|||
|
||||
first-shape (first shapes)
|
||||
page-id (or page-id (:id page))
|
||||
file-id (or file-id (:id file))]
|
||||
file-id (or file-id (:id file))
|
||||
|
||||
libraries (get-libraries from)]
|
||||
|
||||
[:aside.settings-bar.settings-bar-right {:class (when @expanded "expanded")}
|
||||
[:div.settings-bar-inside
|
||||
|
@ -67,7 +88,8 @@
|
|||
:file-id file-id
|
||||
:frame frame
|
||||
:shapes shapes
|
||||
:from from}]]
|
||||
:from from
|
||||
:libraries libraries}]]
|
||||
|
||||
[:& tabs-element {:id :code :title (tr "inspect.tabs.code")}
|
||||
[:& code {:frame frame
|
||||
|
|
|
@ -440,10 +440,9 @@
|
|||
is-component? (and single? (-> shapes first :component-id some?))
|
||||
is-non-root? (and single? (ctk/in-component-instance-not-root? (first shapes)))
|
||||
|
||||
shape-id (-> shapes first :id)
|
||||
component-id (-> shapes first :component-id)
|
||||
component-file (-> shapes first :component-file)
|
||||
main-component? (-> shapes first :main-instance?)
|
||||
first-shape (first shapes)
|
||||
{:keys [shape-id component-id component-file main-instance?]} first-shape
|
||||
lacks-annotation? (nil? (:annotation first-shape))
|
||||
component-shapes (filter #(contains? % :component-id) shapes)
|
||||
|
||||
components-v2 (features/use-feature :components-v2)
|
||||
|
@ -467,6 +466,9 @@
|
|||
do-show-in-assets #(st/emit! (if components-v2
|
||||
(dw/show-component-in-assets component-id)
|
||||
(dw/go-to-component component-id)))
|
||||
create-annotation #(when components-v2
|
||||
(st/emit! (dw/set-annotations-id-for-create (:id first-shape))))
|
||||
|
||||
do-navigate-component-file #(st/emit! (dwl/nav-to-component-file component-file))
|
||||
do-update-component #(st/emit! (dwl/update-component-sync shape-id component-file))
|
||||
do-update-component-in-bulk #(st/emit! (dwl/update-component-in-bulk component-shapes component-file))
|
||||
|
@ -518,9 +520,13 @@
|
|||
;; app/main/ui/workspace/sidebar/options/menus/component.cljs
|
||||
[:*
|
||||
[:& menu-separator]
|
||||
(if main-component?
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.show-in-assets")
|
||||
:on-click do-show-in-assets}]
|
||||
(if main-instance?
|
||||
[:*
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.show-in-assets")
|
||||
:on-click do-show-in-assets}]
|
||||
(when (and components-v2 lacks-annotation?)
|
||||
[:& menu-entry {:title (tr "workspace.shape.menu.create-annotation")
|
||||
:on-click create-annotation}])]
|
||||
(if local-component?
|
||||
(if is-dangling?
|
||||
[:*
|
||||
|
|
|
@ -20,29 +20,148 @@
|
|||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def component-attrs [:component-id :component-file :shape-ref :main-instance?])
|
||||
(def component-attrs [:component-id :component-file :shape-ref :main-instance? :annotation])
|
||||
|
||||
|
||||
(mf/defc component-annotation
|
||||
[{:keys [id values shape component] :as props}]
|
||||
(let [main-instance? (:main-instance? values)
|
||||
component-id (:component-id values)
|
||||
annotation (:annotation component)
|
||||
editing? (mf/use-state false)
|
||||
size (mf/use-state (count annotation))
|
||||
textarea-ref (mf/use-ref)
|
||||
|
||||
;; hack to create an autogrowing textarea
|
||||
;; based on https://css-tricks.com/the-cleanest-trick-for-autogrowing-textareas/
|
||||
autogrow #(let [textarea (mf/ref-val textarea-ref)
|
||||
text (when textarea (.-value textarea))]
|
||||
(when textarea
|
||||
(reset! size (count text))
|
||||
(aset (.-dataset (.-parentNode textarea)) "replicatedValue" text)))
|
||||
initialize #(let [textarea (mf/ref-val textarea-ref)]
|
||||
(when textarea
|
||||
(aset textarea "value" annotation)
|
||||
(autogrow)))
|
||||
|
||||
discard (fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(let [textarea (mf/ref-val textarea-ref)]
|
||||
(aset textarea "value" annotation)
|
||||
(reset! editing? false)
|
||||
(st/emit! (dw/set-annotations-id-for-create nil))))
|
||||
save (fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(let [textarea (mf/ref-val textarea-ref)
|
||||
text (.-value textarea)]
|
||||
(reset! editing? false)
|
||||
(st/emit!
|
||||
(dw/set-annotations-id-for-create nil)
|
||||
(dw/update-component-annotation component-id text))))
|
||||
workspace-annotations (mf/deref refs/workspace-annotations)
|
||||
annotations-expanded? (:expanded? workspace-annotations)
|
||||
creating? (= id (:id-for-create workspace-annotations))
|
||||
|
||||
expand #(when-not (or @editing? creating?)
|
||||
(st/emit! (dw/set-annotations-expanded %)))
|
||||
edit (fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(when main-instance?
|
||||
(let [textarea (mf/ref-val textarea-ref)]
|
||||
(reset! editing? true)
|
||||
(dom/focus! textarea))))
|
||||
|
||||
on-delete-annotation
|
||||
(mf/use-callback
|
||||
(mf/deps shape)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(st/emit! (modal/show
|
||||
{:type :confirm
|
||||
:title (tr "modals.delete-component-annotation.title")
|
||||
:message (tr "modals.delete-component-annotation.message")
|
||||
:accept-label (tr "ds.confirm-ok")
|
||||
:on-accept (fn []
|
||||
(st/emit!
|
||||
(dw/set-annotations-id-for-create nil)
|
||||
(dw/update-component-annotation component-id nil)))}))))]
|
||||
|
||||
(mf/use-effect
|
||||
(mf/deps shape)
|
||||
(fn []
|
||||
(initialize)
|
||||
(when (and (not creating?) (:id-for-create workspace-annotations)) ;; cleanup set-annotations-id-for-create if we aren't on the marked component
|
||||
(st/emit! (dw/set-annotations-id-for-create nil)))
|
||||
(fn [] (st/emit! (dw/set-annotations-id-for-create nil))))) ;; cleanup set-annotationsid-for-create on unload
|
||||
|
||||
(when (or creating? annotation)
|
||||
[:div.component-annotation {:class (dom/classnames :editing @editing?)}
|
||||
[:div.title {:class (dom/classnames :expandeable (not (or @editing? creating?)))
|
||||
:on-click #(expand (not annotations-expanded?))}
|
||||
[:div (if (or @editing? creating?)
|
||||
(if @editing?
|
||||
(tr "workspace.options.component.edit-annotation")
|
||||
(tr "workspace.options.component.create-annotation"))
|
||||
[:* (if annotations-expanded?
|
||||
[:div.expand i/arrow-down]
|
||||
[:div.expand i/arrow-slide])
|
||||
(tr "workspace.options.component.annotation")])]
|
||||
[:div
|
||||
(when (and main-instance? annotations-expanded?)
|
||||
(if (or @editing? creating?)
|
||||
[:*
|
||||
[:div.icon {:title (if creating? (tr "labels.create") (tr "labels.save"))
|
||||
:on-click save} i/tick]
|
||||
[:div.icon {:title (tr "labels.discard")
|
||||
:on-click discard} i/cross]]
|
||||
[:*
|
||||
[:div.icon {:title (tr "labels.edit")
|
||||
:on-click edit} i/pencil]
|
||||
[:div.icon {:title (tr "labels.delete")
|
||||
:on-click on-delete-annotation} i/trash]]))]]
|
||||
|
||||
[:div {:class (dom/classnames :hidden (not annotations-expanded?))}
|
||||
[:div.grow-wrap
|
||||
[:div.texarea-copy]
|
||||
[:textarea
|
||||
{:ref textarea-ref
|
||||
:id "annotation-textarea"
|
||||
:data-debug annotation
|
||||
:auto-focus true
|
||||
:maxLength 300
|
||||
:on-input autogrow
|
||||
:default-value annotation
|
||||
:read-only (not (or creating? @editing?))}]]
|
||||
(when (or @editing? creating?)
|
||||
[:div.counter (str @size "/300")])]])))
|
||||
|
||||
|
||||
|
||||
(mf/defc component-menu
|
||||
[{:keys [ids values shape-name] :as props}]
|
||||
(let [current-file-id (mf/use-ctx ctx/current-file-id)
|
||||
components-v2 (mf/use-ctx ctx/components-v2)
|
||||
[{:keys [ids values shape] :as props}]
|
||||
(let [current-file-id (mf/use-ctx ctx/current-file-id)
|
||||
components-v2 (mf/use-ctx ctx/components-v2)
|
||||
|
||||
id (first ids)
|
||||
local (mf/use-state {:menu-open false})
|
||||
id (first ids)
|
||||
local (mf/use-state {:menu-open false})
|
||||
|
||||
component-id (:component-id values)
|
||||
library-id (:component-file values)
|
||||
show? (some? component-id)
|
||||
main-instance? (if components-v2
|
||||
(:main-instance? values)
|
||||
true)
|
||||
main-component? (:main-instance? values)
|
||||
shape-name (:name shape)
|
||||
|
||||
component-id (:component-id values)
|
||||
library-id (:component-file values)
|
||||
show? (some? component-id)
|
||||
main-instance? (if components-v2
|
||||
(:main-instance? values)
|
||||
true)
|
||||
main-component? (:main-instance? values)
|
||||
lacks-annotation? (nil? (:annotation values))
|
||||
local-component? (= library-id current-file-id)
|
||||
workspace-data (deref refs/workspace-data)
|
||||
workspace-libraries (deref refs/workspace-libraries)
|
||||
is-dangling? (nil? (if local-component?
|
||||
(ctkl/get-component workspace-data component-id)
|
||||
(ctf/get-component workspace-libraries library-id component-id)))
|
||||
component (if local-component?
|
||||
(ctkl/get-component workspace-data component-id)
|
||||
(ctf/get-component workspace-libraries library-id component-id))
|
||||
is-dangling? (nil? component)
|
||||
|
||||
on-menu-click
|
||||
(mf/use-callback
|
||||
|
@ -82,6 +201,7 @@
|
|||
do-show-in-assets #(st/emit! (if components-v2
|
||||
(dw/show-component-in-assets component-id)
|
||||
(dw/go-to-component component-id)))
|
||||
do-create-annotation #(st/emit! (dw/set-annotations-id-for-create id))
|
||||
do-navigate-component-file #(st/emit! (dwl/nav-to-component-file library-id))]
|
||||
(when show?
|
||||
[:div.element-set
|
||||
|
@ -103,7 +223,9 @@
|
|||
:show (:menu-open @local)
|
||||
:options
|
||||
(if main-component?
|
||||
[[(tr "workspace.shape.menu.show-in-assets") do-show-in-assets]]
|
||||
[[(tr "workspace.shape.menu.show-in-assets") do-show-in-assets]
|
||||
(when (and components-v2 lacks-annotation?)
|
||||
[(tr "workspace.shape.menu.create-annotation") do-create-annotation])]
|
||||
(if local-component?
|
||||
(if is-dangling?
|
||||
[[(tr "workspace.shape.menu.detach-instance") do-detach-component]
|
||||
|
@ -124,4 +246,7 @@
|
|||
[[(tr "workspace.shape.menu.detach-instance") do-detach-component]
|
||||
[(tr "workspace.shape.menu.reset-overrides") do-reset-component]
|
||||
[(tr "workspace.shape.menu.update-main") do-update-remote-component]
|
||||
[(tr "workspace.shape.menu.go-main") do-navigate-component-file]])))}]]]]])))
|
||||
[(tr "workspace.shape.menu.go-main") do-navigate-component-file]])))}]]]
|
||||
|
||||
(when components-v2
|
||||
[:& component-annotation {:id id :values values :shape shape :component component}])]])))
|
||||
|
|
|
@ -47,7 +47,7 @@
|
|||
:shape shape}]
|
||||
[:& component-menu {:ids comp-ids
|
||||
:values comp-values
|
||||
:shape-name (:name shape)}]
|
||||
:shape shape}]
|
||||
(when (or (not is-flex-layout-child?) is-layout-child-absolute?)
|
||||
[:& constraints-menu {:ids ids
|
||||
:values constraint-values}])
|
||||
|
|
|
@ -55,7 +55,7 @@
|
|||
|
||||
[:div.options
|
||||
[:& measures-menu {:type type :ids measure-ids :values measure-values :shape shape}]
|
||||
[:& component-menu {:ids comp-ids :values comp-values :shape-name (:name shape)}]
|
||||
[:& component-menu {:ids comp-ids :values comp-values :shape shape}] ;;remove this in components-v2
|
||||
[:& layout-container-menu {:type type :ids [(:id shape)] :values layout-container-values :multiple false}]
|
||||
|
||||
(when is-flex-layout-child?
|
||||
|
|
|
@ -314,7 +314,7 @@ msgstr "Create token"
|
|||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "modals.delete-acces-token.title"
|
||||
msgstr "Delete token"
|
||||
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "modals.delete-acces-token.message"
|
||||
msgstr "Are you sure you want to delete this token?"
|
||||
|
@ -1337,6 +1337,9 @@ msgstr "Copy link"
|
|||
msgid "labels.create"
|
||||
msgstr "Create"
|
||||
|
||||
msgid "labels.discard"
|
||||
msgstr "Discard"
|
||||
|
||||
#: src/app/main/ui/dashboard/team_form.cljs, src/app/main/ui/dashboard/team_form.cljs
|
||||
msgid "labels.create-team"
|
||||
msgstr "Create new team"
|
||||
|
@ -2124,6 +2127,12 @@ msgstr ""
|
|||
msgid "modals.update-remote-component.message"
|
||||
msgstr "Update a component in a shared library"
|
||||
|
||||
msgid "modals.delete-component-annotation.message"
|
||||
msgstr "Are you sure you want to delete this annotation?"
|
||||
|
||||
msgid "modals.delete-component-annotation.title"
|
||||
msgstr "Delete annotation"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs
|
||||
msgid "notifications.invitation-email-sent"
|
||||
msgstr "Invitation sent successfully"
|
||||
|
@ -3368,6 +3377,15 @@ msgstr "Clip content"
|
|||
msgid "workspace.options.component"
|
||||
msgstr "Component"
|
||||
|
||||
msgid "workspace.options.component.annotation"
|
||||
msgstr "Annotation"
|
||||
|
||||
msgid "workspace.options.component.create-annotation"
|
||||
msgstr "Create an annotation"
|
||||
|
||||
msgid "workspace.options.component.edit-annotation"
|
||||
msgstr "Edit an annotation"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/measures.cljs
|
||||
msgid "workspace.options.constraints"
|
||||
msgstr "Constraints"
|
||||
|
@ -4451,6 +4469,9 @@ msgstr "Show in assets panel"
|
|||
msgid "workspace.shape.menu.show-main"
|
||||
msgstr "Show main component"
|
||||
|
||||
msgid "workspace.shape.menu.create-annotation"
|
||||
msgstr "Create annotation"
|
||||
|
||||
msgid "workspace.shape.menu.thumbnail-remove"
|
||||
msgstr "Remove thumbnail"
|
||||
|
||||
|
@ -4713,4 +4734,5 @@ msgid "workspace.updates.update"
|
|||
msgstr "Update"
|
||||
|
||||
msgid "workspace.viewport.click-to-close-path"
|
||||
msgstr "Click to close the path"
|
||||
msgstr "Click to close the path"
|
||||
|
||||
|
|
|
@ -321,7 +321,7 @@ msgstr "Crear token"
|
|||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "modals.delete-acces-token.title"
|
||||
msgstr "Borrar token"
|
||||
|
||||
|
||||
#: src/app/main/ui/settings/access-tokens.cljs
|
||||
msgid "modals.delete-acces-token.message"
|
||||
msgstr "¿Seguro que deseas borrar este token?"
|
||||
|
@ -2192,6 +2192,12 @@ msgstr ""
|
|||
msgid "modals.update-remote-component.message"
|
||||
msgstr "Actualizar un componente en biblioteca"
|
||||
|
||||
msgid "modals.delete-component-annotation.message"
|
||||
msgstr "¿Seguro que quieres borrar esta nota?"
|
||||
|
||||
msgid "modals.delete-component-annotation.title"
|
||||
msgstr "Borrar nota"
|
||||
|
||||
#: src/app/main/ui/dashboard/team.cljs
|
||||
msgid "notifications.invitation-email-sent"
|
||||
msgstr "Invitación enviada con éxito"
|
||||
|
@ -3463,6 +3469,15 @@ msgstr "Truncar contenido"
|
|||
msgid "workspace.options.component"
|
||||
msgstr "Componente"
|
||||
|
||||
msgid "workspace.options.component.annotation"
|
||||
msgstr "Nota"
|
||||
|
||||
msgid "workspace.options.component.create-annotation"
|
||||
msgstr "Crear una nota"
|
||||
|
||||
msgid "workspace.options.component.edit-annotation"
|
||||
msgstr "Editar una nota"
|
||||
|
||||
#: src/app/main/ui/workspace/sidebar/options/menus/measures.cljs
|
||||
msgid "workspace.options.constraints"
|
||||
msgstr "Restricciones"
|
||||
|
@ -4570,6 +4585,9 @@ msgstr "Ver en el panel de recursos"
|
|||
msgid "workspace.shape.menu.show-main"
|
||||
msgstr "Ver componente principal"
|
||||
|
||||
msgid "workspace.shape.menu.create-annotation"
|
||||
msgstr "Crear una nota"
|
||||
|
||||
msgid "workspace.shape.menu.thumbnail-remove"
|
||||
msgstr "Quitar miniatura"
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue