feat: improve LiveQuery ui

This commit is contained in:
0xzion
2023-11-08 00:21:34 +08:00
parent b2e83d8d3b
commit b404ff7c82
14 changed files with 129 additions and 79 deletions

View File

@@ -89,6 +89,7 @@ export const BlockSelectorContent = ({ close, element }: Props) => {
const next = Path.next(Path.parent(at))
// create new empty list item node
Transforms.insertNodes(
editor,
ListsEditor.createListItemTextNode(editor, {

View File

@@ -1,4 +1,4 @@
export const ELEMENT_DATABASE = 'database'
export const ELEMENT_NODE_QUERY = 'node_query'
export const ELEMENT_LIVE_QUERY = 'live_query'
export const FIRST_COL_WIDTH = 50

View File

@@ -1,10 +1,10 @@
import { ELEMENT_DATABASE, ELEMENT_NODE_QUERY } from './constants'
import { DatabaseElement, NodeQueryElement } from './types'
import { ELEMENT_DATABASE, ELEMENT_LIVE_QUERY } from './constants'
import { DatabaseElement, LiveQueryElement } from './types'
export function isDatabase(node: any): node is DatabaseElement {
return node?.type === ELEMENT_DATABASE
}
export function isNodeQuery(node: any): node is NodeQueryElement {
return node?.type === ELEMENT_NODE_QUERY
export function isLiveQuery(node: any): node is LiveQueryElement {
return node?.type === ELEMENT_LIVE_QUERY
}

View File

@@ -1,9 +1,9 @@
import { TableIcon } from 'lucide-react'
import { ExtensionContext } from '@penx/extension-typings'
import { db } from '@penx/local-db'
import { ELEMENT_DATABASE, ELEMENT_NODE_QUERY } from './constants'
import { ELEMENT_DATABASE, ELEMENT_LIVE_QUERY } from './constants'
import { Database } from './ui/Database'
import { NodeQuery } from './ui/NodeQuery'
import { LiveQuery } from './ui/LiveQuery/LiveQuery'
import { withDatabase } from './withDatabase'
export * from './guard'
@@ -20,6 +20,7 @@ export function activate(ctx: ExtensionContext) {
name: 'Database',
icon: TableIcon,
async beforeInvokeCommand(editor) {
console.log('before.............')
return db.createDatabase()
},
},
@@ -27,10 +28,10 @@ export function activate(ctx: ExtensionContext) {
{
isVoid: true,
type: ELEMENT_NODE_QUERY,
component: NodeQuery,
type: ELEMENT_LIVE_QUERY,
component: LiveQuery,
slashCommand: {
name: 'Node Query',
name: 'Live Query',
icon: TableIcon,
},
},

View File

@@ -1,5 +1,5 @@
import { BaseElement } from 'slate'
import { ELEMENT_DATABASE } from './constants'
import { ELEMENT_DATABASE, ELEMENT_LIVE_QUERY } from './constants'
export interface BaseCustomElement extends BaseElement {
id?: string
@@ -11,10 +11,6 @@ export interface DatabaseElement extends BaseCustomElement {
name: string
}
export interface NodeQueryElement extends BaseCustomElement {
type: typeof ELEMENT_DATABASE
colWidths: number[] // table col widths
isHeaderRow: boolean
isHeaderColumn: boolean
databaseId: string
export interface LiveQueryElement extends BaseCustomElement {
type: typeof ELEMENT_LIVE_QUERY
}

View File

@@ -0,0 +1,24 @@
import { Box } from '@fower/react'
import { Input } from 'uikit'
import { ElementProps } from '@penx/extension-typings'
import { LiveQueryElement } from '../../types'
import { LiveQueryProvider } from './LiveQueryContext'
export const LiveQuery = ({
attributes,
element,
children,
}: ElementProps<LiveQueryElement>) => {
const sql = '#bookmark'
return (
<Box flex-1 mb8 mt8 contentEditable={false} {...attributes}>
<Box>
<Input placeholder="#bookmark" defaultValue="#bookmark" />
</Box>
<LiveQueryProvider sql={sql}>
<Box>Node Query...</Box>
</LiveQueryProvider>
{children}
</Box>
)
}

View File

@@ -0,0 +1,56 @@
import {
createContext,
PropsWithChildren,
useCallback,
useContext,
useEffect,
useState,
} from 'react'
import { db } from '@penx/local-db'
import { ICellNode, IColumnNode, INode, IRowNode, IViewNode } from '@penx/types'
export interface ILiveQueryContext {
database: INode
views: IViewNode[]
columns: IColumnNode[]
rows: IRowNode[]
cells: ICellNode[]
}
export const liveQueryContext = createContext<ILiveQueryContext>(
{} as ILiveQueryContext,
)
export function useLiveQueryContext() {
return useContext(liveQueryContext)
}
interface LiveQueryProviderProps {
sql: string
}
export const LiveQueryProvider = ({
children,
sql,
}: PropsWithChildren<LiveQueryProviderProps>) => {
const { Provider } = liveQueryContext
const [loading, setLoading] = useState(true)
const [ctx, setCtx] = useState({} as ILiveQueryContext)
console.log('gogoggo.......')
const loadLiveQuery = useCallback(async () => {
console.log('sql:', sql)
const database = await db.getDatabaseByName('bookmark')
// const data = await db.getLiveQuery(databaseId)
// setLoading(false)
// setCtx(data as any)
}, [sql])
useEffect(() => {
loadLiveQuery()
}, [loadLiveQuery])
if (loading) return null
return <Provider value={ctx}>{children}</Provider>
}

View File

@@ -1,19 +0,0 @@
import { Box } from '@fower/react'
import { ElementProps } from '@penx/extension-typings'
import { NodeQueryElement } from '../types'
import { DatabaseProvider } from './DatabaseContext'
export const NodeQuery = ({
attributes,
element,
children,
}: ElementProps<NodeQueryElement>) => {
const { databaseId } = element
return (
<Box flex-1 mb8 mt8 contentEditable={false} {...attributes}>
<Box>Node Query</Box>
{children}
</Box>
)
}

View File

@@ -35,10 +35,12 @@ function onEnterInTitle(editor: Editor) {
export const onKeyDown: OnKeyDown = (editor, e) => {
if (e.key === 'Enter') {
e.preventDefault()
const handled = onEnterInTitle(editor)
if (handled) return
if (handled) {
e.preventDefault()
return
}
const node = getCurrentNode(editor)!
// TODO: handle any

View File

@@ -19,9 +19,8 @@ interface Props {
export const TagSelectorContent = ({ close, element }: Props) => {
const editor = useEditorStatic()
const { nodeList } = useNodes()
const tagNames = nodeList.tagNodes
.map((node) => node.props.tag!)
.filter((i) => !!i)
const tagNames = nodeList.tagNodes.map((node) => node.props.name!)
// .filter((i) => !!i)
const filteredTypes = tagNames.filter((item) => {
const q = Node.string(element).replace(/^#/, '').toLowerCase()
@@ -30,6 +29,7 @@ export const TagSelectorContent = ({ close, element }: Props) => {
})
const text = Node.string(element)
const tagName = text.replace(/^#/, '')
const selectTag = useCallback(
(tagName: any) => {
@@ -56,13 +56,11 @@ export const TagSelectorContent = ({ close, element }: Props) => {
const listItemIdPrefix = 'type-list-item-'
const { cursor } = useKeyDownList({
onEnter: (cursor) => {
console.log('enter.......xx')
onEnter: async (cursor) => {
if (!filteredTypes.length) {
console.log('create tag......')
store.createTag(text)
selectTag(text)
console.log('create tag......:', tagName)
await store.createDatabase(tagName)
selectTag(tagName)
return
}
selectTag(filteredTypes[cursor])

View File

@@ -98,7 +98,7 @@ class DB {
await this.node.insert(
getNewNode({
spaceId,
type: NodeType.TAG_ROOT,
type: NodeType.DATABASE_ROOT,
}),
)
@@ -512,6 +512,20 @@ class DB {
}
}
getDatabaseByName = async (name: string) => {
const space = await this.getActiveSpace()
const nodes = await this.node.select({
where: {
type: NodeType.DATABASE,
spaceId: space.id,
},
})
console.log('nodes:', nodes)
const database = nodes.find((node) => node.props.name === name)
return database
}
addColumn = async (databaseId: string, fieldType: FieldType) => {
const space = await this.getActiveSpace()
const spaceId = space.id

View File

@@ -19,6 +19,8 @@ export function onKeyDown(
onKeyDown.onEnterEscapeFromEmptyList(editor, event) ||
onKeyDown.onEnterSplitNonEmptyList(editor, event)
)
} catch (e) {
console.log('onkeydown', e)
} finally {
// Slate does not always trigger normalization when one would expect it to.
// So we want to force it after we perform lists operations, as it fixes

View File

@@ -222,40 +222,15 @@ export const store = Object.assign(createStore(), {
this.reloadNode(node)
},
async createTag(text: string) {
const space = this.getActiveSpace()
async createDatabase(tagName: string) {
const nodes = store.getNodes()
let tagRootNode = nodes.find((node) => node.type === NodeType.TAG_ROOT)!
let tagNode = nodes.find(
(node) => node.type === NodeType.DATABASE && node.props.tag === text,
let databaseNode = nodes.find(
(node) => node.type === NodeType.DATABASE && node.props.name === tagName,
)
if (!tagNode) {
const newNode = await db.createNode({
spaceId: space.id,
parentId: tagRootNode.id,
type: NodeType.DATABASE,
props: {
tag: text,
// TODO:
columns: [
{
title: text,
type: 'TEXT',
},
],
},
})
newNode.parentId
await db.updateNode(tagRootNode.id, {
children: [...tagRootNode.children, newNode.id],
})
await db.createDatabase(text)
if (!databaseNode) {
await db.createDatabase(tagName)
}
},

View File

@@ -5,10 +5,10 @@ export enum NodeType {
TRASH = 'TRASH',
DAILY_NOTE = 'DAILY_NOTE',
TAG_ROOT = 'TAG_ROOT',
TAG = 'TAG',
// Database
DATABASE_ROOT = 'DATABASE_ROOT',
DATABASE = 'DATABASE',
CELL = 'CELL',
ROW = 'ROW',