diff --git a/README-zh.md b/README-zh.md index 4f4092a..57b9113 100644 --- a/README-zh.md +++ b/README-zh.md @@ -6,8 +6,11 @@ QueryDash的目标是开发一款类似Notion Database的Obsidian插件,但不 **由于使用了dataview的api,必须启用dataview插件。** 未来将逐步扩展更多实用特性,帮助用户更高效地管理知识、任务和生活。 +**如果你对项目感兴趣,请star一下,非常感谢,这对我很重要** + **现有功能** 1. **多视图支持**:提供表格和列表两种视图,满足不同场景需求。 + - **时间轴视图**: 使用时间轴来展示数据 2. **Dataview SQL支持**:兼容Dataview的SQL语法。 3. **增强功能**: - **搜索**:快速定位所需内容。 @@ -27,6 +30,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..1c8e6af 100644 --- a/README.md +++ b/README.md @@ -3,12 +3,15 @@ The goal of QueryDash is to develop an Obsidian plugin similar to Notion Databas **Since the API of Dataview is used, the Dataview plugin must be enabled.** In the future, it will gradually expand with more practical features to help users manage knowledge, tasks, and life more efficiently. +**If you are interested in this project, please consider starring it. Thank you very much, it means a lot to me.** + **language** - [English](README.md) - [简体中文](README-zh.md) **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 +21,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 +31,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/manifest.json b/manifest.json index f153ddb..6f44ae7 100644 --- a/manifest.json +++ b/manifest.json @@ -1,7 +1,7 @@ { "id": "querydash", "name": "QueryDash", - "version": "1.0.2", + "version": "1.0.3", "minAppVersion": "1.8.0", "description": "Refer to Dataview and add search, sorting, and pagination functions, just like Notion.", "author": "lwx", diff --git a/package.json b/package.json index 94f1c88..78aad68 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,5 @@ { "name": "obsidian-querydash", - "version": "1.0.2", "description": "Refer to Dataview and add search, sorting, and pagination functions, just like Notion.", "main": "main.js", "scripts": { diff --git a/src/pages/GenerateColumns.tsx b/src/pages/GenerateColumns.tsx index 1fdeac6..46d1db6 100644 --- a/src/pages/GenerateColumns.tsx +++ b/src/pages/GenerateColumns.tsx @@ -21,7 +21,7 @@ export function formatValue( function formatObject(value: any) { const type =value.type; if(type==='file') { - const fileName = value.path.replace(/\.md$/, ''); + const fileName = value.path.split('/').pop().replace(/\.md$/, '') return {type: "link", path: value.path, display: fileName}; } 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;