Skip to content

Commit

Permalink
feat: improve global search
Browse files Browse the repository at this point in the history
  • Loading branch information
0xzio committed Apr 30, 2024
1 parent c35d46a commit d4bbf9f
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 25 deletions.
8 changes: 4 additions & 4 deletions apps/web/next.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,8 @@ const config = {
// export default withPWA(million.next(config))
const nextConfig = isDev ? config : withPWA(config)

// export default nextConfig
export default nextConfig

export default million.next(nextConfig, {
auto: true,
})
// export default million.next(nextConfig, {
// auto: true,
// })
72 changes: 56 additions & 16 deletions packages/app/src/Palette/SearchByTag.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { Dispatch, SetStateAction, useMemo } from 'react'
import { Box, styled } from '@fower/react'
import { Node as SlateNode } from 'slate'
import { modalController } from 'uikit'
import { Command } from '@penx/cmdk'
import { ModalNames } from '@penx/constants'
import { getText } from '@penx/editor-queries'
import { usePaletteDrawer } from '@penx/hooks'
import { db } from '@penx/local-db'
Expand All @@ -12,6 +14,13 @@ import { store } from '@penx/store'

const CommandItem = styled(Command.Item)

const filterBuiltin = (node: Node) => {
if (node.isTodoDatabase) return false
if (node.isFileDatabase) return false
if (node.tagName.startsWith('$template_')) return false
return true
}

interface Props {
q: string
setSearch: Dispatch<SetStateAction<string>>
Expand All @@ -23,34 +32,57 @@ export function SearchByTag({ q, setSearch, close }: Props) {
const search = q.replace(/^#(\s+)?/, '') || ''

const regex = /^(\S+)\s?(.*)?$/
const [_, tag, text] = search.match(regex) || []
const [_, tag, text = ''] = search.match(regex) || []

const paletteDrawer = usePaletteDrawer()

const filteredItems = useMemo(() => {
if (!search) return nodeList.tagNodes
if (!search) {
return nodeList.tagNodes.filter(filterBuiltin)
}

const tagNodes = nodeList.tagNodes.filter((node) => {
return node.tagName.includes(tag)
})

const canSearchALlNodesByTag = /^#(\S)+\s$/.test(q)
if (!text && !canSearchALlNodesByTag) return tagNodes
if (!text && !canSearchALlNodesByTag) {
return tagNodes.filter(filterBuiltin)
}

const database = store.node.getDatabaseByName(tag)!

const cells = store.node
.getCells(database.id)
.filter((cell) => {
// first try to match the ref
const node = store.node.getNode(cell.props.ref!)
if (!node) return false

if (!node) {
const { data = '' } = cell.props

// try to match others cell data
if (data) {
return String(data).toLowerCase().includes(text.toLowerCase())
}

return false
}

if (!text) return true
const str = SlateNode.string(node.element)
return str.toLowerCase().includes(text.toLowerCase())

const str = SlateNode.string(node.element[0])
const matched = str.toLowerCase().includes(text.toLowerCase())

return matched
})
.map((cell) => {
const raw = store.node.getNode(cell.props.ref!)!
const raw = store.node.getNode(cell.props.ref!) || cell
const node = new Node(raw)

// set name for render
node.raw.props.name = new Node(database).tagName

return node
})

Expand All @@ -72,6 +104,20 @@ export function SearchByTag({ q, setSearch, close }: Props) {
node,
store.node.getNodes().map((n) => new Node(n)),
)

const onSelect = () => {
console.log('node----:', node)
if (node.isDatabase) {
nodeService.selectNode()
} else {
modalController.open(ModalNames.ROW, node)
}

paletteDrawer?.close()
close()
setSearch('')
}

return (
<CommandItem
key={node.id}
Expand All @@ -83,21 +129,15 @@ export function SearchByTag({ q, setSearch, close }: Props) {
roundedLG
value={node.id}
onSelect={() => {
paletteDrawer?.close()
nodeService.selectNode()
close()
setSearch('')
onSelect()
}}
onClick={() => {
nodeService.selectNode()
paletteDrawer?.close()
close()
setSearch('')
onSelect()
}}
>
{node.isDatabase
? `#${node.tagName}`
: `#${node.tagName} ${node.title}`}
: `#${node.tagName} ${node.isCell ? String(node.props.data) : node.title}`}
</CommandItem>
)
})}
Expand Down
37 changes: 37 additions & 0 deletions packages/app/src/Workbench/RowModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { Box } from '@fower/react'
import {
Button,
Modal,
ModalClose,
ModalCloseButton,
ModalContent,
ModalHeader,
ModalOverlay,
useModalContext,
} from 'uikit'
import { ModalNames } from '@penx/constants'
import { RowForm } from '@penx/database-ui'
import { Node } from '@penx/model'

const Content = () => {
const { data: node } = useModalContext<Node>()
return (
<Box>
<ModalHeader mb2># {node.tagName}</ModalHeader>
<RowForm rowId={node.props.rowId} databaseId={node.parentId} />
</Box>
)
}

export const RowModal = () => {
return (
<Modal name={ModalNames.ROW}>
<ModalOverlay />
<ModalContent w={['100%', 500]} column gap4>
<ModalCloseButton />

<Content />
</ModalContent>
</Modal>
)
}
2 changes: 2 additions & 0 deletions packages/app/src/Workbench/Workbench.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { MobileNav } from './NodeNav/MobileNav'
import { PCNav } from './NodeNav/PCNav'
import { NodePanels } from './NodePanels'
import { PageTodo } from './PageTodo/PageTodo'
import { RowModal } from './RowModal'
import { GoogleBackup } from './Settings/Backup/GoogleBackup'
import { PageSettings } from './Settings/PageSettings/PageSettings'
import { SettingsModal } from './Settings/SettingsModal/SettingsModal'
Expand Down Expand Up @@ -56,6 +57,7 @@ export const Workbench = () => {
<LoginByTokenModal />
<SettingsModal />
<TagHubModal />
<RowModal />

<Box h-100vh toLeft black flex-1 relative>
{!isBackedUp && session && name === 'NODE' && <BackupMnemonicTips />}
Expand Down
2 changes: 2 additions & 0 deletions packages/constants/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ export enum SettingsType {
export enum ModalNames {
DELETE_NODE,

ROW,

DELETE_COLUMN,
CONFIG_COLUMN,
DELETE_DATABASE,
Expand Down
49 changes: 49 additions & 0 deletions packages/database-ui/src/RowForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { forwardRef } from 'react'
import { Box } from '@fower/react'
import { useDatabase } from '@penx/node-hooks'
import { mappedByKey } from '@penx/shared'
import { FieldIcon } from './shared/FieldIcon'
import { CellField } from './tag/fields'

interface Props {
databaseId: string
rowId: string
}

export const RowForm = forwardRef<HTMLDivElement, Props>(function TagForm(
{ databaseId, rowId },
ref,
) {
const { columns, views, cells } = useDatabase(databaseId)

const currentView = views[0]

const columnMap = mappedByKey(columns, 'id')
const { viewColumns = [] } = currentView.props
const sortedColumns = viewColumns.map(({ columnId }) => columnMap[columnId])

const rowCells = sortedColumns.map((column) => {
return cells.find(
(cell) => cell.props.rowId === rowId && cell.props.columnId === column.id,
)!
})

return (
<Box ref={ref} column gap4>
{rowCells.map((cell, index) => {
const column = columns.find((col) => col.id === cell.props.columnId)!

return (
<Box key={cell.id}>
<Box mb2 toCenterY gap1 gray600>
<FieldIcon fieldType={column.props.fieldType} />
<Box textXS>{column.props.displayName}</Box>
</Box>

<CellField index={index} cell={cell} columns={sortedColumns} />
</Box>
)
})}
</Box>
)
})
1 change: 1 addition & 0 deletions packages/database-ui/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ export * from './views/TableView/cells-common'
export * from './views/TableView/PublishedTableView'
export * from './ViewToolBar/FilterField/OperatorSelect'
export * from './ViewToolBar/ToolbarBtn'
export * from './RowForm'
12 changes: 8 additions & 4 deletions packages/model/src/Node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,12 @@ export type WithFlattenedProps<T> = T & {
export class Node {
parentId: string

props: Record<string, any> = {}

constructor(public raw: INode) {
this.parentId = this.raw?.parentId || ''

this.props = this.raw?.props || {}
}

get id(): string {
Expand All @@ -46,10 +50,6 @@ export class Node {
return !!this.children.length
}

get props() {
return this.raw.props || {}
}

get date() {
return this.raw.date || ''
}
Expand Down Expand Up @@ -283,4 +283,8 @@ export class Node {

return calculateSHA256FromString(JSON.stringify(json))
}

setProps(props: Record<string, any>) {
this.props = props
}
}
2 changes: 1 addition & 1 deletion packages/store/src/stores/NodeStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ export class NodeStore {
let cells = nodes.filter(
(node) => node.type === NodeType.CELL && node.parentId === databaseId,
)
return cells
return cells as ICellNode[]
}

getTodos() {
Expand Down

0 comments on commit d4bbf9f

Please sign in to comment.