diff --git a/src/cljs/athens/self_hosted/presence/views.cljs b/src/cljs/athens/self_hosted/presence/views.cljs index 47b1f75328..498ee74d1b 100644 --- a/src/cljs/athens/self_hosted/presence/views.cljs +++ b/src/cljs/athens/self_hosted/presence/views.cljs @@ -1,13 +1,14 @@ (ns athens.self-hosted.presence.views (:require ["/components/PresenceDetails/PresenceDetails" :refer [PresenceDetails]] - ["@chakra-ui/react" :refer [Avatar AvatarGroup]] + ["@chakra-ui/react" :refer [Avatar AvatarGroup Tooltip]] [athens.electron.utils :as electron.utils] [athens.router :as router] [athens.self-hosted.presence.events] [athens.self-hosted.presence.fx] [athens.self-hosted.presence.subs] [athens.util :as util] + [clojure.string :as str] [re-frame.core :as rf] [reagent.core :as r])) @@ -35,8 +36,9 @@ (let [selected-db @(rf/subscribe [:db-picker/selected-db]) url (router/create-url-with-graph-param (:id selected-db))] (.. js/navigator -clipboard (writeText url)) - (rf/dispatch [:show-snack-msg {:msg "Permalink copied to clipboard" - :type :success}]))) + (util/toast (clj->js {:status "info" + :position "top-right" + :title "Copied permalink to clipboard"})))) (defn go-to-user-block @@ -101,17 +103,20 @@ (let [users (rf/subscribe [:presence/has-presence (util/embed-uid->original-uid uid)])] (when (seq @users) (into - [:> AvatarGroup {:max 3 - :zIndex 2 - :size "xs" - :position "absolute" - :right "-1.5rem" - :top "0.25rem"} - (->> @users - (map user->person) - (remove nil?) - (map (fn [{:keys [personId] :as person}] - [:> Avatar {:key personId - :bg (:color person) - :name (:username person)}])))])))) + [:> Tooltip {:label (->> @users (map user->person) + (remove nil?) + (map (fn [person] (:username person))) + (str/join ", "))} + [:> AvatarGroup {:max 1 + :zIndex 2 + :size "xs" + :cursor "default" + :gridArea "presence"} + (->> @users + (map user->person) + (remove nil?) + (map (fn [{:keys [personId] :as person}] + [:> Avatar {:key personId + :bg (:color person) + :name (:username person)}])))]])))) diff --git a/src/cljs/athens/views/blocks/core.cljs b/src/cljs/athens/views/blocks/core.cljs index 664395a4d7..91f6d21c29 100644 --- a/src/cljs/athens/views/blocks/core.cljs +++ b/src/cljs/athens/views/blocks/core.cljs @@ -72,12 +72,19 @@ parents (conj parents block))] [:> BreadcrumbItem {:key (str "breadcrumb-" uid)} - [:> BreadcrumbLink {:onClick #(let [new-B (db/get-block [:block/uid uid]) - new-P (concat - (take-while (fn [b] (not= (:block/uid b) uid)) parents) - [breadcrumb-block])] - (.. % stopPropagation) - (swap! state assoc :block new-B :parents new-P :focus? false))} + [:> BreadcrumbLink {:onClick (fn [e] + (let [shift? (.-shiftKey e)] + (rf/dispatch [:reporting/navigation {:source :block-bullet + :target :block + :pane (if shift? + :right-pane + :main-pane)}]) + (let [new-B (db/get-block [:block/uid uid]) + new-P (concat + (take-while (fn [b] (not= (:block/uid b) uid)) parents) + [breadcrumb-block])] + (.. e stopPropagation) + (swap! state assoc :block new-B :parents new-P :focus? false))))} [parse-renderer/parse-and-render (or title string) uid]]]))]] (when (:open? @state) @@ -110,8 +117,9 @@ :spacing 3 :key "Inline Linked References" :zIndex 2 - :ml 4 - :px 4 + :ml 8 + :pl 4 + :p2 2 :borderRadius "md" :background "background.basement"} (doall diff --git a/src/cljs/athens/views/blocks/textarea_keydown.cljs b/src/cljs/athens/views/blocks/textarea_keydown.cljs index 7d283bdbe0..5a81b5d7b7 100644 --- a/src/cljs/athens/views/blocks/textarea_keydown.cljs +++ b/src/cljs/athens/views/blocks/textarea_keydown.cljs @@ -93,15 +93,15 @@ (defn slash-options [] (cond-> - [["Add Todo" CheckboxIcon "{{[[TODO]]}} " "cmd-enter" nil] - ["Current Time" TimeNowIcon (fn [] (.. (js/Date.) (toLocaleTimeString [] (clj->js {"timeStyle" "short"})))) nil nil] - ["Today" CalendarNowIcon (fn [] (str "[[" (:title (dates/get-day 0)) "]] ")) nil nil] - ["Tomorrow" CalendarTomorrowIcon (fn [] (str "[[" (:title (dates/get-day -1)) "]]")) nil nil] - ["Yesterday" CalendarYesterdayIcon (fn [] (str "[[" (:title (dates/get-day 1)) "]]")) nil nil] - ["YouTube Embed" YoutubeIcon "{{[[youtube]]: }}" nil 2] - ["iframe Embed" HTMLEmbedIcon "{{iframe: }}" nil 2] - ["Block Embed" BlockEmbedIcon "{{[[embed]]: (())}}" nil 4] - ["Template" TemplateIcon ";;" nil nil]] + [["Add Todo" CheckboxIcon "{{[[TODO]]}} " "cmd-enter" nil] + ["Current Time" TimeNowIcon (fn [] (.. (js/Date.) (toLocaleTimeString [] (clj->js {"timeStyle" "short"})))) nil nil] + ["Today" CalendarNowIcon (fn [] (str "[[" (:title (dates/get-day 0)) "]] ")) nil nil] + ["Tomorrow" CalendarTomorrowIcon (fn [] (str "[[" (:title (dates/get-day -1)) "]]")) nil nil] + ["Yesterday" CalendarYesterdayIcon (fn [] (str "[[" (:title (dates/get-day 1)) "]]")) nil nil] + ["YouTube Embed" YoutubeIcon "{{[[youtube]]: }}" nil 2] + ["iframe Embed" HTMLEmbedIcon "{{iframe: }}" nil 2] + ["Block Embed" BlockEmbedIcon "{{[[embed]]: (())}}" nil 4] + ["Template" TemplateIcon ";;" nil nil]] @(subscribe [:db-picker/remote-db?]) (conj (let [username (:username @(rf/subscribe [:presence/current-user]))] [(str "Me (" username ")") PersonIcon (fn [] (str "[[" username "]] ")) nil nil])))) diff --git a/src/cljs/athens/views/pages/block_page.cljs b/src/cljs/athens/views/pages/block_page.cljs index 6eb81d2b45..3b402a3911 100644 --- a/src/cljs/athens/views/pages/block_page.cljs +++ b/src/cljs/athens/views/pages/block_page.cljs @@ -1,13 +1,13 @@ (ns athens.views.pages.block-page (:require + ["/components/Layout/Layout" :refer [PageReferences ReferenceBlock ReferenceGroup]] ["/components/Page/Page" :refer [PageHeader PageBody PageFooter TitleContainer]] - ["@chakra-ui/react" :refer [Breadcrumb BreadcrumbItem BreadcrumbLink VStack AccordionIcon Accordion AccordionItem AccordionButton AccordionPanel]] + ["@chakra-ui/react" :refer [Breadcrumb BreadcrumbItem BreadcrumbLink]] [athens.parse-renderer :as parse-renderer] [athens.reactive :as reactive] [athens.router :as router] [athens.views.blocks.core :as blocks] [athens.views.pages.node-page :as node-page] - [athens.views.references :refer [reference-group reference-block]] [komponentit.autosize :as autosize] [re-frame.core :as rf :refer [dispatch subscribe]] [reagent.core :as r])) @@ -52,32 +52,25 @@ [id] (let [linked-refs (reactive/get-reactive-linked-references id)] (when (seq linked-refs) - [:> Accordion - [:> AccordionItem - [:h2 - [:> AccordionButton - [:> AccordionIcon "LinkedReferences"]]] - [:> AccordionPanel {:px 0} - [:> VStack {:spacing 6 - :pl 6 - :align "stretch"} - (doall - (for [[group-title group] linked-refs] - [reference-group {:key (str "group-" group-title) - :title group-title - :on-click-title (fn [e] - (let [shift? (.-shiftKey e) - parsed-title (parse-renderer/parse-title group-title)] - (rf/dispatch [:reporting/navigation {:source :block-page-linked-refs - :target :page - :pane (if shift? - :right-pane - :main-pane)}]) - (router/navigate-page parsed-title)))} - (doall - (for [block group] - [reference-block {:key (str "ref-" (:block/uid block))} - [node-page/ref-comp block]]))]))]]]]))) + [:> PageReferences {:title "Linked References" + :count (count linked-refs)} + (doall + (for [[group-title group] linked-refs] + [:> ReferenceGroup {:key (str "group-" group-title) + :title group-title + :onClickTitle (fn [e] + (let [shift? (.-shiftKey e) + parsed-title (parse-renderer/parse-title group-title)] + (rf/dispatch [:reporting/navigation {:source :block-page-linked-refs + :target :page + :pane (if shift? + :right-pane + :main-pane)}]) + (router/navigate-page parsed-title)))} + (doall + (for [block group] + [:> ReferenceBlock {:key (str "ref-" (:block/uid block))} + [node-page/ref-comp block]]))]))]))) (defn parents-el diff --git a/src/cljs/athens/views/pages/node_page.cljs b/src/cljs/athens/views/pages/node_page.cljs index c3ffb627b0..dcf72ed1fe 100644 --- a/src/cljs/athens/views/pages/node_page.cljs +++ b/src/cljs/athens/views/pages/node_page.cljs @@ -5,7 +5,7 @@ ["/components/Icons/Icons" :refer [EllipsisHorizontalIcon GraphIcon BookmarkIcon BookmarkFillIcon TrashIcon ArrowRightOnBoxIcon]] ["/components/Layout/Layout" :refer [PageReferences ReferenceBlock ReferenceGroup]] ["/components/Page/Page" :refer [PageHeader PageBody PageFooter TitleContainer]] - ["@chakra-ui/react" :refer [Box Button Portal IconButton MenuDivider MenuButton Menu MenuList MenuItem Breadcrumb BreadcrumbItem BreadcrumbLink VStack]] + ["@chakra-ui/react" :refer [Box HStack Button Portal IconButton MenuDivider MenuButton Menu MenuList MenuItem Breadcrumb BreadcrumbItem BreadcrumbLink VStack]] [athens.common-db :as common-db] [athens.common.sentry :refer-macros [wrap-span-no-new-tx]] [athens.common.utils :as utils] @@ -415,9 +415,6 @@ :onClickOpenInSidebar (when-not (contains? @(subscribe [:right-sidebar/items]) uid) #(dispatch [:right-sidebar/open-item uid]))} - ;; Dropdown - [menu-dropdown node daily-note?] - [:> TitleContainer {:isEditing @(subscribe [:editing/is-editing uid])} ;; Prevent editable textarea if a node/title is a date ;; Don't allow title editing from daily notes, right sidebar, or node-page itself. @@ -434,11 +431,16 @@ (handle-blur node state)) :on-key-down (fn [e] (handle-key-down e uid state children)) :on-change (fn [e] (handle-change e state))}]) - ;; empty word break to keep span on full height else it will collapse to 0 height (weird ui) - (if (str/blank? (:title/local @state)) - [:wbr] - [perf-mon/hoc-perfmon {:span-name "parse-and-render"} - [parse-renderer/parse-and-render (:title/local @state) uid]])]] + + [:> HStack {:width "fit-content" :gridArea "main"} + ;; empty word break to keep span on full height else it will collapse to 0 height (weird ui) + (if (str/blank? (:title/local @state)) + [:wbr] + [perf-mon/hoc-perfmon {:span-name "parse-and-render"} + [parse-renderer/parse-and-render (:title/local @state) uid]]) + + ;; Dropdown + [menu-dropdown node daily-note?]]]] [:> PageBody @@ -453,11 +455,12 @@ ;; References [:> PageFooter - [perf-mon/hoc-perfmon-no-new-tx {:span-name "linked-ref-el"} - [linked-ref-el state title]] - (when-not on-daily-notes? - [perf-mon/hoc-perfmon-no-new-tx {:span-name "unlinked-ref-el"} - [unlinked-ref-el state unlinked-refs title]])]])))) + [:> VStack {:spacing 2 :py 4 :align "stretch"} + [perf-mon/hoc-perfmon-no-new-tx {:span-name "linked-ref-el"} + [linked-ref-el state title]] + (when-not on-daily-notes? + [perf-mon/hoc-perfmon-no-new-tx {:span-name "unlinked-ref-el"} + [unlinked-ref-el state unlinked-refs title]])]]])))) (defn page diff --git a/src/cljs/athens/views/pages/page.cljs b/src/cljs/athens/views/pages/page.cljs index 7146879b95..72e2b484a1 100644 --- a/src/cljs/athens/views/pages/page.cljs +++ b/src/cljs/athens/views/pages/page.cljs @@ -1,9 +1,10 @@ (ns athens.views.pages.page (:require - ["/components/Page/Page" :refer [PageContainer]] + ["/components/Page/Page" :refer [PageContainer PageNotFound]] [athens.common-db :as common-db] [athens.db :as db] [athens.reactive :as reactive] + [athens.router :as router] [athens.views.pages.block-page :as block-page] [athens.views.pages.node-page :as node-page] [re-frame.core :as rf])) @@ -16,7 +17,8 @@ (if (int? page-eid) [:> PageContainer {:uid page-eid :type "node"} [node-page/page page-eid]] - [:h3 (str "404: Page with title '" @title "' doesn't exist")]))) + [:> PageNotFound {:title @title + :onClickHome #(router/navigate :pages)}]))) (defn page @@ -28,4 +30,4 @@ (cond title [node-page/page id] string [block-page/page id] - :else [:h3 "404: This page doesn't exist"])])) + :else [:> PageNotFound {:onClickHome #(router/navigate :pages)}])])) diff --git a/src/cljs/athens/views/references.cljs b/src/cljs/athens/views/references.cljs deleted file mode 100644 index 5a773a9f18..0000000000 --- a/src/cljs/athens/views/references.cljs +++ /dev/null @@ -1,44 +0,0 @@ -(ns athens.views.references - (:require - ["@chakra-ui/react" :refer [Box Button Heading VStack]])) - - -(defn reference-header - ([props] - (let [{:keys [on-click title]} props] - [:> Heading {:as "h4" - :color "foreground.secondary" - :textTransform "uppercase" - :pt 4 - :borderTop "1px solid" - :borderTopColor "separator.divider" - :fontWeight "bold" - :fontSize "0.75rem" - :size "md"} - [:> Button {:onClick on-click - :color "inherit" - :textTransform "inherit" - :_hover {:textDecoration "none" - :opacity 0.5} - :fontWeight "inherit" - :fontSize "inherit" - :variant "link"} - title]]))) - - -(defn reference-group - ([props children] - (let [{:keys [on-click-title title]} props] - [:> VStack {:spacing 0 :align "stretch"} - (when title [reference-header {:on-click on-click-title - :title title}]) - children]))) - - -(defn reference-block - ([props children] - (let [{:keys [actions]} props] - [:> Box - children - actions]))) - diff --git a/src/js/components/Block/components/Container.tsx b/src/js/components/Block/components/Container.tsx index 74862d1c86..6854e3b52e 100644 --- a/src/js/components/Block/components/Container.tsx +++ b/src/js/components/Block/components/Container.tsx @@ -50,7 +50,6 @@ const _Container = ({ children, isDragging, isSelected, isOpen, hasChildren, has background: "link", }, "&.is-selected:after": { opacity: 0.2 }, - "&.is-presence .block-content": { paddingRight: "1rem" }, ".user-avatar": { position: "absolute", left: "4px", @@ -60,7 +59,8 @@ const _Container = ({ children, isDragging, isSelected, isOpen, hasChildren, has display: "grid", gridTemplateColumns: "1em 1em 1fr auto", gridTemplateRows: "0 1fr 0", - gridTemplateAreas: "'above above above above' 'toggle bullet content refs' 'below below below below'", + gridTemplateAreas: + "'above above above above above' 'toggle bullet content refs presence' 'below below below below below'", borderRadius: "0.5rem", minHeight: '2em', position: "relative", diff --git a/src/js/components/Layout/Layout.tsx b/src/js/components/Layout/Layout.tsx index d50c250d15..8b56e12330 100644 --- a/src/js/components/Layout/Layout.tsx +++ b/src/js/components/Layout/Layout.tsx @@ -219,7 +219,6 @@ export const PageReferences = withErrorBoundary(({ children, count, title, defau align="stretch" position="relative" spacing={0} - p={2} > + : } + {children && (<> children)} + +} + export const PageContainer = ({ children, uid, type }) => {children} @@ -112,7 +124,7 @@ export const PageFooter = ({ children }) => {children} export const DailyNotesPage = ({ isReal, children }) => {children} @@ -141,23 +153,23 @@ export const TitleContainer = ({ children, isEditing, props }) => span": { - position: "relative", - zIndex: 2, - } }, "abbr": { gridArea: "main", diff --git a/src/js/components/PresenceDetails/PresenceDetails.tsx b/src/js/components/PresenceDetails/PresenceDetails.tsx index d5c598db6b..0b5a61a0d8 100644 --- a/src/js/components/PresenceDetails/PresenceDetails.tsx +++ b/src/js/components/PresenceDetails/PresenceDetails.tsx @@ -84,39 +84,25 @@ export const PresenceDetails = withErrorBoundary((props: PresenceDetailsProps) = <> {hostAddress && ( <> - handleCopyHostAddress(hostAddress)} - display="flex" - flexDirection="column" - textAlign="left" - justifyContent="flex-start" - alignItems="stretch" - > - Copy address - - {hostAddress} - - - handleCopyPermalink()}> - Copy permalink + handleCopyHostAddress(hostAddress)}> + Copy link to database + {handleCopyPermalink && handleCopyPermalink()}> + Copy link to page + } )} {currentUser && ( - setShouldShowProfileSettings(true)} icon={}>Edit appearance + <> + + setShouldShowProfileSettings(true)} icon={}>Edit appearance + )} {currentPageMembers.length > 0 && ( diff --git a/src/js/theme/theme.js b/src/js/theme/theme.js index 03550d17a5..d3beb272bb 100644 --- a/src/js/theme/theme.js +++ b/src/js/theme/theme.js @@ -459,6 +459,9 @@ const components = { }, icon: { marginInlineEnd: "0.25rem", + }, + groupTitle: { + margin: '0.35rem 0.5rem', } } }