diff --git a/README-zh.md b/README-zh.md index 4f4092a..c39a29d 100644 --- a/README-zh.md +++ b/README-zh.md @@ -8,6 +8,7 @@ QueryDash的目标是开发一款类似Notion Database的Obsidian插件,但不 **现有功能** 1. **多视图支持**:提供表格和列表两种视图,满足不同场景需求。 + - **时间轴视图**: 使用时间轴来展示数据 2. **Dataview SQL支持**:兼容Dataview的SQL语法。 3. **增强功能**: - **搜索**:快速定位所需内容。 @@ -27,6 +28,24 @@ file.mtime as "mtime" ,file.tags as "tags" from #clippings ![demo.gif](docs/demo.gif) +**timeline** + +**simple mode** +~~~markdown +```querydash +timeline from #start +``` +~~~ +![timeline.png](docs/timeline.png) +**full mode** + +If you want to append the time later, alias a specific field as "time". +~~~markdown +```querydash +timeline file.ctime as "time" from #start where file.ctime<=date(today) sort file.mtime desc +``` +~~~ + **远景规划** 1. **首页**:将常用功能整合到首页,提供一站式便捷操作。 diff --git a/README.md b/README.md index 50255e0..515797a 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ In the future, it will gradually expand with more practical features to help use **Current Features** 1. **Multi-view Support**: Provides table and list views to meet different scenario needs. + - **timeline**: use timeline view to display data. 2. **Dataview SQL Support**: Compatible with Dataview's SQL syntax . 3. **Enhanced Features**: - **Search**: Quickly locate the content you need. @@ -18,6 +19,7 @@ In the future, it will gradually expand with more practical features to help use **Tutorial** +**table** ~~~markdown ```querydash table file.name , file.outlinks as "links" ,file.ctime as "ctime", @@ -27,6 +29,24 @@ file.mtime as "mtime" ,file.tags as "tags" from #clippings ![demo.gif](docs/demo.gif) +**timeline** + +**simple mode** +~~~markdown +```querydash +timeline from #start +``` +~~~ +![timeline.png](docs/timeline.png) +**full mode** + +If you want to append the time later, alias a specific field as "time". +~~~markdown +```querydash +timeline file.ctime as "time" from #start where file.ctime<=date(today) sort file.mtime desc +``` +~~~ + **Future Vision** 1. **Homepage**: Integrate frequently used functions into the homepage for one-stop convenience. 2. **Multi-view Support**: Supports timeline, gallery, table, and other views to meet diverse scenario needs. diff --git a/docs/timeline.png b/docs/timeline.png new file mode 100644 index 0000000..d97b7e0 Binary files /dev/null and b/docs/timeline.png differ diff --git a/src/pages/QueryDashView.tsx b/src/pages/QueryDashView.tsx index d153921..1bab3a3 100644 --- a/src/pages/QueryDashView.tsx +++ b/src/pages/QueryDashView.tsx @@ -2,8 +2,9 @@ import React, {useEffect} from 'react'; import {App} from "obsidian"; import TableView from "./tableview/TableView"; import ListView from "./listview/ListView"; -import {ConfigProvider, ConfigProviderProps} from "antd"; +import {ConfigProvider, ConfigProviderProps, Timeline} from "antd"; import enUS from 'antd/locale/en_US'; +import TimeLineView from "./timelineview/TimeLineView"; interface QueryDashViewDashs { @@ -18,15 +19,18 @@ const QueryDashView: React.FC = ({app, source}) => { const [sourceType, setSourceType] = React.useState("table"); useEffect(() => { - const sourceType = source.toLowerCase().startsWith("list") ? "list" : "table"; + // 获取第一个单词 + const sourceType = source.split(" ")[0].toLowerCase(); setSourceType(sourceType); }, []); const getView = (app: App, source: string) => { if (sourceType === "table") { return ; - } else { + } else if (sourceType === "list") { return ; + } else if (sourceType === "timeline") { + return ; } } diff --git a/src/pages/timelineview/TimeLineView.tsx b/src/pages/timelineview/TimeLineView.tsx new file mode 100644 index 0000000..f825de2 --- /dev/null +++ b/src/pages/timelineview/TimeLineView.tsx @@ -0,0 +1,122 @@ +import {ProList} from '@ant-design/pro-components'; +import React, {useEffect, useState} from "react"; +import {formatValue} from "../GenerateColumns"; +import {getAPI} from 'obsidian-dataview'; +import {ViewProps} from "../../models/ViewProps"; +import {Radio, RadioChangeEvent, Timeline} from "antd"; +import {TFile} from "obsidian"; + + +const TimeLineView: React.FC = ({app, source}) => { + + const [data, setData] = React.useState([]); + + const dv = getAPI(app); + const [mode, setMode] = useState<'left' | 'alternate' | 'right'>('alternate'); + + const onChange = (e: RadioChangeEvent) => { + setMode(e.target.value); + }; + + + const renderItem = (itemFile: any, itemCtime: any) => { + const date = itemCtime?.display.split(" ")[0] || ""; + + return ( + + { + const file = app.vault.getAbstractFileByPath(itemFile.path); + if (file && file instanceof TFile) { + const leaf = app.workspace.getLeaf(); + leaf.openFile(file); + } + }}> + {itemFile.display} + + {date ? " " + date : ""} + + ) + } + + useEffect(() => { + + let resData: any[] = []; + + const response = executeTableQuery(dv, source, {}); + + response.then((res) => { + const {tableData} = res; + tableData.forEach((item: any) => { + const file = item["File"]; + const ctime = item["time"]; + const finalDisplay = renderItem(file, ctime); + resData.push({"children": finalDisplay}); + }); + setData(resData); + }).catch((error) => { + console.error("Error executing query:", error); + }); + // console.log(response, response); + + }, [app, source]); + + function parseTableResult(value: any, params: any): Array> { + const headers: string[] = value.headers; + const rows: Array> = []; + value.values.forEach((row: any) => { + const values: Record = {}; + headers.forEach((header, index) => { + const value = row[index]; + // console.log("list value", value); + const resValue = formatValue(value); + // console.log("list resValue", resValue); + values[header] = resValue; + }); + rows.push(values); + }); // console.log("list rows", rows); + + return rows; + } + + function replaceFirstWord(source: string): string { + const words = source.split(' '); + if (words[0] === 'timeline') { + words[0] = 'table'; + } + return words.join(' '); + } + + const executeTableQuery = async (dvApi: any, source: any, params: any) => { + const sql = replaceFirstWord(source); + const queryResult = await dvApi.query(sql); + + console.log("queryResult", queryResult); + const tableData: any = parseTableResult(queryResult.value, params); + return {tableData: tableData}; + + } + + + return ( + <> +

Timeline

+
+ + Left + Right + Alternate + + + ) +} + +export default TimeLineView;