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 May 1, 2024
1 parent c35d46a commit 60b87a0
Show file tree
Hide file tree
Showing 15 changed files with 213 additions and 166 deletions.
27 changes: 0 additions & 27 deletions apps/believer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,38 +10,23 @@
"with-env": "dotenv -e ../../.env --"
},
"dependencies": {
"@dnd-kit/core": "^6.1.0",
"@dnd-kit/sortable": "^7.0.2",
"@dnd-kit/utilities": "^3.2.2",
"@emoji-mart/data": "^1.1.2",
"@emoji-mart/react": "^1.1.1",
"@floating-ui/react": "^0.25.4",
"@fower/atomic-props": "^2.0.0",
"@fower/react": "^2.0.0",
"@glideapps/glide-data-grid": "^6.0.3",
"@hookform/resolvers": "^3.3.2",
"@next-auth/prisma-adapter": "^1.0.7",
"@octokit/auth-app": "^6.0.1",
"@octokit/oauth-app": "^6.0.0",
"@octokit/rest": "^20.0.2",
"@penx/abi": "workspace:*",
"@penx/api": "workspace:*",
"@penx/app": "workspace:*",
"@penx/constants": "workspace:*",
"@penx/database": "workspace:*",
"@penx/db": "workspace:*",
"@penx/encryption": "workspace:*",
"@penx/hooks": "workspace:*",
"@penx/icons": "workspace:*",
"@penx/local-db": "workspace:*",
"@penx/math": "workspace:*",
"@penx/model": "workspace:*",
"@penx/model-types": "workspace:*",
"@penx/serializer": "workspace:*",
"@penx/session": "workspace:*",
"@penx/shared": "workspace:*",
"@penx/slate-lists": "workspace:*",
"@penx/store": "workspace:*",
"@penx/trpc-client": "workspace:^",
"@penx/unique-id": "workspace:*",
"@penx/wagmi": "workspace:*",
Expand All @@ -67,9 +52,6 @@
"cookies-next": "^2.1.2",
"crypto-js": "^4.2.0",
"date-fns": "^2.30.0",
"dexie": "^3.2.4",
"dexie-react-hooks": "^1.1.7",
"emoji-mart": "^5.5.2",
"emoji-picker-react": "^4.5.16",
"ethers": "^6.10.0",
"framer-motion": "^10.16.14",
Expand All @@ -82,18 +64,14 @@
"ky": "^1.1.3",
"lodash": "^4.17.21",
"lucide-react": "^0.344.0",
"markdown-it": "^13.0.2",
"million": "^3.0.6",
"mime": "^3.0.0",
"mitt": "^3.0.1",
"next": "14.1.4",
"next-auth": "4.24.7",
"nextjs-cors": "^2.2.0",
"nextjs-google-analytics": "^2.3.3",
"octokit": "^3.1.2",
"prismjs": "^1.29.0",
"rc-table": "^7.36.0",
"re-resizable": "^6.9.11",
"react": "^18.2.0",
"react-datepicker": "^4.24.0",
"react-dom": "^18.2.0",
Expand All @@ -104,10 +82,7 @@
"react-use": "^17.5.0",
"simplebar-react": "^3.2.4",
"siwe": "^2.1.4",
"slate": "0.102.0",
"slate-history": "0.100.0",
"slate-hyperscript": "0.100.0",
"slate-react": "0.102.0",
"sonner": "^0.6.2",
"stook": "^1.17.0",
"superjson": "1.9.1",
Expand All @@ -126,7 +101,6 @@
"@types/is-hotkey": "^0.1.10",
"@types/jsonwebtoken": "^9.0.5",
"@types/lodash": "^4.14.202",
"@types/markdown-it": "^13.0.7",
"@types/mime": "^3.0.4",
"@types/node": "^20.10.3",
"@types/react": "^18.2.61",
Expand All @@ -138,7 +112,6 @@
"eslint-config-custom": "workspace:*",
"postcss": "^8.4.32",
"sass": "^1.69.5",
"smee-client": "^2.0.1",
"typescript": "^5.3.2"
}
}
3 changes: 0 additions & 3 deletions apps/bounty/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,6 @@
"cookies-next": "^2.1.2",
"crypto-js": "^4.2.0",
"date-fns": "^2.30.0",
"dexie": "^3.2.4",
"dexie-react-hooks": "^1.1.7",
"ethers": "^6.10.0",
"framer-motion": "^10.16.14",
"idb-keyval": "^6.2.1",
Expand All @@ -71,7 +69,6 @@
"nextjs-google-analytics": "^2.3.3",
"octokit": "^3.1.2",
"prismjs": "^1.29.0",
"re-resizable": "^6.9.11",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-fast-compare": "^3.2.2",
Expand Down
21 changes: 6 additions & 15 deletions apps/home/src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@ import { Fragment } from 'react'
import { Session } from 'next-auth'
import { NextSeo } from 'next-seo'
import type { AppProps } from 'next/app'
import { ToastContainer } from 'uikit'
import { isServer } from '@penx/constants'
import { TrpcProvider } from '@penx/trpc-client'
import { initFower } from '../common/initFower'
import '../styles/globals.css'

Expand All @@ -17,10 +15,6 @@ interface Props<T> extends AppProps<T> {
}
}

if (!isServer) {
// TODO: move this code to a separate file
}

function MyApp({ Component, pageProps }: Props<any>) {
const Layout = Component.Layout ? Component.Layout : Fragment

Expand All @@ -47,16 +41,13 @@ function MyApp({ Component, pageProps }: Props<any>) {
}}
/>

<TrpcProvider>
{/* <SpeedInsights /> */}
<Layout>
<Component {...pageProps} />
<div id="portal" />
</Layout>
<ToastContainer position="bottom-right" />
{/* <SpeedInsights /> */}
<Layout>
<Component {...pageProps} />
<div id="portal" />
</Layout>

{/* <Analytics /> */}
</TrpcProvider>
{/* <Analytics /> */}
</>
)
}
Expand Down
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,
// })
4 changes: 2 additions & 2 deletions apps/web/src/pages/login.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ import { SiweModal } from '~/components/SiweModal'
import { WalletConnectButton } from '~/components/WalletConnectButton'
import { WalletConnectProvider } from '~/components/WalletConnectProvider'

const isHosted = process.env.NEXT_PUBLIC_DEPLOY_MODE === 'SELF_HOSTED'

export default function LoginPage() {
const { push } = useRouter()

useHideLogoLoader()

const isHosted = process.env.NEXT_PUBLIC_DEPLOY_MODE === 'SELF_HOSTED'

const loginEntry = useMemo(() => {
if (isHosted) {
return <LoginForm />
Expand Down
94 changes: 76 additions & 18 deletions packages/app/src/Palette/SearchByTag.tsx
Original file line number Diff line number Diff line change
@@ -1,56 +1,95 @@
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 { getText } from '@penx/editor-queries'
import { ModalNames } from '@penx/constants'
import { usePaletteDrawer } from '@penx/hooks'
import { db } from '@penx/local-db'
import { Node } from '@penx/model'
import { IDatabaseNode } from '@penx/model-types'
import { useNodes } from '@penx/node-hooks'
import { NodeService } from '@penx/service'
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>>
close: () => void
}

interface Item {
node: Node
database: IDatabaseNode
}

export function SearchByTag({ q, setSearch, close }: Props) {
const { nodeList } = useNodes()
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)!

if (!database) return nodeList.tagNodes.filter(filterBuiltin)

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
node.raw.props.rowId = cell.props.rowId

return node
})

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

const onSelect = () => {
if (node.isDatabase) {
if (search === node.tagName) {
nodeService.selectNode()
} else {
setSearch('#' + node.tagName)
return
}
} else {
const database = store.node.getDatabaseByName(node.tagName)!

// console.log('=======database:', database)

modalController.open(ModalNames.ROW, {
node,
databaseId: database.id,
})
}

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

return (
<CommandItem
key={node.id}
Expand All @@ -83,21 +147,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
48 changes: 48 additions & 0 deletions packages/app/src/Workbench/RowModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { Box } from '@fower/react'
import {
Button,
Modal,
ModalClose,
ModalCloseButton,
ModalContent,
ModalHeader,
ModalOverlay,
useModalContext,
} from 'uikit'
import { ModalNames } from '@penx/constants'
import { DatabaseProvider, RowForm } from '@penx/database-ui'
import { Node } from '@penx/model'

interface Data {
node: Node
databaseId: string
}

const Content = () => {
const {
data: { node, databaseId },
} = useModalContext<Data>()
// console.log('======node:', node)

return (
<Box>
<ModalHeader mb2># {node.tagName}</ModalHeader>
<DatabaseProvider databaseId={databaseId}>
<RowForm rowId={node.props.rowId} databaseId={databaseId} />
</DatabaseProvider>
</Box>
)
}

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

<Content />
</ModalContent>
</Modal>
)
}
Loading

0 comments on commit 60b87a0

Please sign in to comment.