Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Snippets Scrolling, Recents in Extension #280

Merged
merged 7 commits into from
Nov 18, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/friendly-cobras-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'mexit': patch
'mexit-webapp': patch
---

Right Sidebar UX fixes
4 changes: 4 additions & 0 deletions apps/extension/src/Components/Editor/SnippetPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ export interface SnippetPreviewProps {
hover?: boolean
// editable?: boolean
label?: string
disableClick?: boolean
allowClosePreview?: boolean
icon?: string
iconTooltip?: string
Expand All @@ -46,6 +47,7 @@ const SnippetPreview = ({
hover,
label,
placement,
disableClick,
// editable = true,
setPreview,
icon,
Expand Down Expand Up @@ -83,8 +85,10 @@ const SnippetPreview = ({
return (
<NestedFloating
hover={hover}
disableClick={disableClick}
root={getElementById('ext-side-nav')}
label={label}
scrollLock={false}
placement={placement}
persist={!allowClosePreview}
open={preview}
Expand Down
6 changes: 5 additions & 1 deletion apps/extension/src/Components/EditorPreviewRenderer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,11 @@ const PreviewStyles = styled(EditorStyles)<{ noMouseEvents: boolean }>`
/* user-select: none; */
font-size: 0.9rem;

${TodoContainer}, button, input, textarea, select, option {
${TodoContainer}, button,
input,
textarea,
select,
option {
pointer-events: none;
}
`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,8 @@ const Screenshot = () => {
]
appendAndSave({ nodeid, content: appendContent, saveAndExit: true, notification: true })
resetSpotlitState()
} else {
mog('Base 64 string not found')
}
} catch (error) {
mog('SSCaptureError', { error })
Expand Down
10 changes: 6 additions & 4 deletions apps/extension/src/Components/Sidebar/ContextInfoBar.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useMemo } from 'react'

import { SnippetCards, CenteredFlex } from '@mexit/shared'
import { SnippetCards, CenteredFlex, List } from '@mexit/shared'

import { useHighlightStore } from '../../Stores/useHighlightStore'
import { GenericCard } from './GenericCard'
Expand Down Expand Up @@ -67,7 +67,7 @@ export function ContextInfoBar() {
// }, [search])

return (
<SnippetCards>
<SnippetCards fullHeight={false}>
<ShortenerComponent />
{/* <SidebarListFilterWrapper>
<SidebarListFilter>
Expand All @@ -82,14 +82,16 @@ export function ContextInfoBar() {
<Infobox root={getElementById('ext-side-nav')} text={HighlightSidebarHelp} />
</SidebarListFilterWrapper> */}
{pageHighlights ? (
<HighlightGroups highlights={pageHighlights} />
<List scrollable>
<HighlightGroups highlights={pageHighlights} />
</List>
) : (
<div>
<CenteredFlex>
<h2>Hi there</h2>
<p>Let's get you started</p>
</CenteredFlex>
<SnippetCards>
<SnippetCards fullHeight={false}>
{basicOnboarding.map((item) => (
<GenericCard icon={item.icon} title={item.title} description={item.description} />
))}
Expand Down
17 changes: 11 additions & 6 deletions apps/extension/src/Components/Sidebar/DraggableToggle.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ import styled, { css } from 'styled-components'

import { TitleWithShortcut } from '@workduck-io/mex-components'

import { mog } from '@mexit/core'
import { MexIcon, WDLogo } from '@mexit/shared'
import { WDLogo } from '@mexit/shared'

import { useSidebarTransition } from '../../Hooks/useSidebarTransition'
import { useLayoutStore } from '../../Stores/useLayoutStore'
Expand All @@ -22,16 +21,16 @@ const DragIcon = styled(Icon)<{ $show: boolean }>`
`}
`

const ToggleWrapper = styled.div<{ $expanded?: boolean; $top: number }>`
const ToggleWrapper = styled.div<{ $endColumnWidth?: string; $expanded?: boolean; $top: number }>`
position: fixed;
display: flex;
align-items: center;

${({ $expanded, $top, theme }) =>
${({ $expanded, $top, $endColumnWidth, theme }) =>
$expanded
? css`
top: ${$top}px;
right: 405px;
right: calc(${($endColumnWidth ?? '400px') + ' + ' + (theme.additional.hasBlocks ? 0 : -15)}px);
`
: css`
top: ${$top}px;
Expand Down Expand Up @@ -130,7 +129,13 @@ export const DraggableToggle = () => {
appendTo={() => getElementById('ext-side-nav')}
content={<TitleWithShortcut title={rhSidebar.expanded ? 'Collapse Sidebar' : 'Expand Sidebar'} />}
>
<ToggleWrapper ref={intentRef as any} $top={toggleTop} $expanded={rhSidebar.expanded} onClick={toggleRHSidebar}>
<ToggleWrapper
$endColumnWidth={endColumnWidth}
ref={intentRef as any}
$top={toggleTop}
$expanded={rhSidebar.expanded}
onClick={toggleRHSidebar}
>
<WDLogo />

<DragIcon ref={handleRef} $show={isHovering} icon="ic:outline-drag-indicator" />
Expand Down
31 changes: 21 additions & 10 deletions apps/extension/src/Components/Sidebar/NodeCard.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,24 @@
import React, { useMemo } from 'react'

import { Icon } from '@iconify/react'
import toast from 'react-hot-toast'
import styled from 'styled-components'

import { convertContentToRawText, MEXIT_FRONTEND_URL_BASE, mog, WORKSPACE_HEADER } from '@mexit/core'
import {
CenteredFlex,
CopyButton,
GenericFlex,
IconButton,
MexIcon,
SnippetCardFooter,
SnippetCardHeader,
SnippetCardWrapper,
SnippetContentPreview,
TagsLabel
SnippetContentPreview
} from '@mexit/shared'

import { useAuthStore } from '../../Hooks/useAuth'
import { getTitleFromPath } from '../../Hooks/useLinks'
import { useNodes } from '../../Hooks/useNodes'
import { useContentStore } from '../../Stores/useContentStore'
import useDataStore from '../../Stores/useDataStore'
import { useRecentsStore } from '../../Stores/useRecentsStore'

export const NodeCardHeader = styled.div<{ $noHover?: boolean }>`
display: flex;
Expand All @@ -36,6 +34,7 @@ export const NodeCard = ({ nodeId }: { nodeId: string }) => {
const { publicNodes, setNodePrivate, setNodePublic, checkNodePublic } = useDataStore()
const { getNode } = useNodes()
const getContent = useContentStore((store) => store.getContent)
const addInRecents = useRecentsStore((s) => s.addRecent)
const getWorkspaceId = useAuthStore((store) => store.getWorkspaceId)

const isNodePublic = useMemo(() => {
Expand Down Expand Up @@ -66,6 +65,7 @@ export const NodeCard = ({ nodeId }: { nodeId: string }) => {
if (error) {
mog('ErrorMakingNodePrivate', error)
} else {
addInRecents(nodeId)
setNodePrivate(nodeId)
}
})
Expand All @@ -84,29 +84,40 @@ export const NodeCard = ({ nodeId }: { nodeId: string }) => {
if (error) {
mog('ErrorMakingNodePublic', error)
} else {
addInRecents(nodeId)
setNodePublic(nodeId)
}
})
}
}

const onNotePublic = (event) => {
event.stopPropagation()
flipPublicAccess()
}

return (
<SnippetCardWrapper>
<NodeCardHeader $noHover>
<GenericFlex>
<Icon icon="gg:file-document" />
<MexIcon $noHover icon="gg:file-document" />
{getTitleFromPath(node?.path)}
</GenericFlex>
<GenericFlex>
{isNodePublic ? (
<Icon icon="bi:cloud" onClick={() => flipPublicAccess()} />
<IconButton
title="Make Note Public"
size="16px"
icon="material-symbols:public-off-rounded"
onClick={onNotePublic}
/>
) : (
<Icon icon="bi:cloud-slash" onClick={() => flipPublicAccess()} />
<IconButton title="Make Note Private" size="16px" icon="material-symbols:public" onClick={onNotePublic} />
)}
{isNodePublic && (
<CopyButton
text={`${MEXIT_FRONTEND_URL_BASE}/share/${nodeId}`}
size="20px"
size="16px"
beforeCopyTooltip="Copy link"
afterCopyTooltip="Link copied!"
/>
Expand Down
78 changes: 64 additions & 14 deletions apps/extension/src/Components/Sidebar/NotesInfoBar.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,37 @@
import React, { useEffect, useRef, useState } from 'react'

import searchLine from '@iconify/icons-ri/search-line'
import { Icon } from '@iconify/react'
import { debounce } from 'lodash'
import { useTheme } from 'styled-components'

import { mog } from '@mexit/core'
import { SidebarListFilterWrapper, SidebarListFilter, Input, SnippetCards } from '@mexit/shared'
import { Infobox } from '@workduck-io/mex-components'

import { BASE_TASKS_PATH, isParent, mog } from '@mexit/core'
import {
SidebarListFilterWrapper,
SidebarListFilter,
Input,
SnippetCards,
MexIcon,
NotesInfoBarHelp,
List,
CenteredColumn
} from '@mexit/shared'

import { useLinks } from '../../Hooks/useLinks'
import useRaju from '../../Hooks/useRaju'
import useDataStore from '../../Stores/useDataStore'
import { useRecentsStore } from '../../Stores/useRecentsStore'
import { getElementById } from '../../contentScript'
import { NodeCard } from './NodeCard'

export const NotesInfoBar = () => {
const publicNodes = useDataStore((state) => state.publicNodes)
const [search, setSearch] = useState('')
const [searchedNodes, setSearchedNodes] = useState<string[]>()
const { dispatch } = useRaju()
const recentNotes = useRecentsStore((s) => s.lastOpened)

const theme = useTheme()
const { getILinkFromNodeid } = useLinks()

const inputRef = useRef<HTMLInputElement>(null)

Expand All @@ -24,35 +40,69 @@ export const NotesInfoBar = () => {
}

const onSearch = async (newSearchTerm: string) => {
const res = await dispatch('SEARCH', ['node'], newSearchTerm)
try {
const res = await dispatch('SEARCH', ['node'], newSearchTerm)
const results = res?.map((item) => item.id) ?? []
setSearchedNodes(results)
} catch (err) {
mog('[NOTE SEARCH]: Unable to search', { err })
}
}

const getRecentList = (noteIds: Array<string>, limit = 5) => {
const recentList = []

noteIds?.forEach((noteId) => {
const noteLink = getILinkFromNodeid(noteId, true)

if (noteLink && !isParent(noteLink.path, BASE_TASKS_PATH)) {
recentList.push(noteId)
}
})

if (recentList.length > limit) {
return recentList.reverse().slice(0, limit)
}

setSearchedNodes(res?.map((item) => item.id))
return recentList?.reverse()
}

useEffect(() => {
if (search !== '') {
onSearch(search)
} else {
setSearchedNodes(publicNodes)
const defaultList = getRecentList(recentNotes)
setSearchedNodes(defaultList)
}
}, [search])
}, [search, recentNotes])

return (
<SnippetCards>
<SidebarListFilterWrapper>
<SidebarListFilter>
<Icon icon={searchLine} />
<SidebarListFilter noMargin>
<MexIcon $noHover height={20} width={20} icon={searchLine} margin="0.6rem 0" />
<Input
autoFocus
fontSize="1rem"
placeholder={'Search notes'}
onChange={debounce((e) => onSearchChange(e), 250)}
ref={inputRef}
/>
</SidebarListFilter>
<Infobox text={NotesInfoBarHelp} root={getElementById('ext-side-nav')} />
</SidebarListFilterWrapper>
{searchedNodes?.map((nodeId) => (
<NodeCard key={nodeId} nodeId={nodeId} />
))}
{!search && !searchedNodes?.length ? (
<CenteredColumn>
<MexIcon color={theme.colors.primary} $noHover width="32" height="32" icon="gg:file-document" />
<p>All your recents will shown here!</p>
</CenteredColumn>
) : (
<List scrollable>
{searchedNodes?.map((nodeId) => (
<NodeCard key={nodeId} nodeId={nodeId} />
))}
</List>
)}
</SnippetCards>
)
}
Loading