Compare commits

..

21 Commits
2.2.4 ... 2.3.0

Author SHA1 Message Date
Jiaxin Peng
ded01ce678 Update version to 2.3.0 2024-07-04 20:57:35 +01:00
Jiaxin Peng
3535d9fc70 Merge pull request #23 from jxpeng98/edit-modal
edit modal update for customised database
2024-07-04 20:55:41 +01:00
Jiaxin Peng
9c93e38aff reformat code and update readme file 2024-07-04 20:51:07 +01:00
Jiaxin Peng
bfde5dfe1a finish the edit modal 2024-07-04 20:28:28 +01:00
Jiaxin Peng
d8eb3c8984 feat: cancel function works well 2024-07-04 18:12:31 +01:00
Jiaxin Peng
1cee2b67a6 update edit modal with better display setting. 2024-07-04 17:06:23 +01:00
Jiaxin Peng
82529ce56a back up for edit modal 2024-07-04 10:00:46 +01:00
Jiaxin Peng
70f30f0713 Add support for notion link display in the front matter. 2024-07-03 22:35:47 +01:00
Jiaxin Peng
24ebb0bf8a Back up edit modal 2024-07-03 22:01:46 +01:00
Jiaxin Peng
d7372c7c55 Improve preview function for customised database 2024-07-03 16:05:24 +01:00
Jiaxin Peng
f7bcf71020 create retrieve function to get all created properties for customised database 2024-07-03 14:26:02 +01:00
Jiaxin Peng
72146afe48 update settingModal.ts refactor the customise database and improve the creating logic 2024-07-03 13:39:56 +01:00
Jiaxin Peng
9bcdb42edb settingmodal save mapping for reference 2024-07-03 11:06:54 +01:00
Jiaxin Peng
16e0827991 update the basic function of edit modal 2024-07-03 08:47:33 +01:00
Jiaxin Peng
863a6fb0dc more clear logic customised database setting code 2024-07-02 23:56:35 +01:00
Jiaxin Peng
5799ffe79b Update custom function and adjust the custom interface ui 2024-07-02 23:48:37 +01:00
Jiaxin Peng
a8ebab7fcb change tags titleicon and summary to optional function in next database 2024-03-17 14:36:55 +00:00
Jiaxin Peng
e0ec27ad07 update readme 2024-03-12 22:04:34 +00:00
Jiaxin Peng
85220105b0 update README 2024-03-08 15:23:17 +00:00
Jiaxin Peng
9afdb24a82 typo 2024-02-26 11:57:28 +00:00
Jiaxin Peng
3c7ab13995 update readme 2024-02-26 11:53:02 +00:00
28 changed files with 792 additions and 905 deletions

View File

@@ -1,5 +1,25 @@
# Changelog v2.2.3 ## Fix
- fixed the issue that you cannot have empty values in the front matter of the customised database.
- 修复了自定义数据库的前置数据中不能有空值的问题。
For example, you have the property `tag` in your customised database, and you do not want to sync `tag` to Notion. You can remove the `tag` from the front matter.
- 例如,自定义数据库中有属性`tag`,但是你不想将`tag`同步到Notion。现在你可以直接在frontmatter中删除`tag`
## Bug Fixes
- Fix a bug that 'text' property cannot be synchronized. 修复了一个无法同步'text'属性的bug。 ## Improvement
**⚠️⚠️⚠️: The exist customised database should be recreated if you want to update to version 2.3.0. The new version has a new database structure, and the old database structure is not compatible with the new version to build the index properly.**
### 自定义数据库用户
**⚠️⚠️⚠️: 如果你想要更新到2.3.0版本,你需要重新创建自定义数据库。新版本有一个新的数据库结构,旧的数据库结构无法构建索引。**
- redesigned the way to create new customised database. The modal has been removed with a more straightforward layout.
- 重新设计了自定义数据库的创建方式。已删除模态框,采用更直观的布局。
![](https://minioapi.pjx.ac.cn/img1/2024/07/7a1550aefd71175c981077ce46d03c87.png)
- improved the edit modal for customised database. The layout has been simplified and the form has been reorganized.
- 改进了自定义数据库的编辑模态框。简化了布局,重新组织了表单。
![](https://minioapi.pjx.ac.cn/img1/2024/07/471ea519b7cb3fba8f0b57956bb1f973.png)
- improved the preview modal for customised database.
- 改进了自定义数据库的预览模态框。
![](https://minioapi.pjx.ac.cn/img1/2024/07/9599d77116afad065d2e31129942acc7.png)

253
README.md
View File

@@ -3,12 +3,12 @@
[![Test](https://github.com/jxpeng98/obsidian-to-NotionNext/actions/workflows/test.yml/badge.svg)](https://github.com/jxpeng98/obsidian-to-NotionNext/actions/workflows/test.yml) [![Test](https://github.com/jxpeng98/obsidian-to-NotionNext/actions/workflows/test.yml/badge.svg)](https://github.com/jxpeng98/obsidian-to-NotionNext/actions/workflows/test.yml)
[![Release](https://github.com/jxpeng98/obsidian-to-NotionNext/actions/workflows/release.yml/badge.svg)](https://github.com/jxpeng98/obsidian-to-NotionNext/actions/workflows/release.yml) [![Release](https://github.com/jxpeng98/obsidian-to-NotionNext/actions/workflows/release.yml/badge.svg)](https://github.com/jxpeng98/obsidian-to-NotionNext/actions/workflows/release.yml)
[![Obsidian Downloads](https://img.shields.io/badge/dynamic/json?logo=obsidian&color=%23483699&label=downloads&query=%24%5B%22share-to-notionnext%22%5D.downloads&url=https%3A%2F%2Fraw.githubusercontent.com%2Fobsidianmd%2Fobsidian-releases%2Fmaster%2Fcommunity-plugin-stats.json)](https://GitHub.com/jxpeng98/obsidian-to-NotionNext/releases/) [![Obsidian Downloads](https://img.shields.io/badge/dynamic/json?logo=obsidian&color=%23483699&label=downloads&query=%24%5B%22share-to-notionnext%22%5D.downloads&url=https%3A%2F%2Fraw.githubusercontent.com%2Fobsidianmd%2Fobsidian-releases%2Fmaster%2Fcommunity-plugin-stats.json)](https://GitHub.com/jxpeng98/obsidian-to-NotionNext/releases/)
[![GitHub release (with filter)](https://img.shields.io/github/v/release/jxpeng98/obsidian-to-NotionNext)](https://github.com/jxpeng98/obsidian-to-NotionNext/releases/) [![GitHub release (with filter)](https://img.shields.io/github/package-json/v/jxpeng98/obsidian-to-NotionNext)](https://github.com/jxpeng98/obsidian-to-NotionNext/releases/)
[//]: # ([![Github all releases](https://img.shields.io/github/downloads/jxpeng98/obsidian-to-NotionNext/total.svg)](https://GitHub.com/jxpeng98/obsidian-to-NotionNext/releases/)) [//]: # ([![Github all releases](https://img.shields.io/github/downloads/jxpeng98/obsidian-to-NotionNext/total.svg)](https://GitHub.com/jxpeng98/obsidian-to-NotionNext/releases/))
[中文文档](README-zh.md) [//]: # ([中文文档](README-zh.md))
**Now, support both NotionNext and General databases with customised properties.** **Now, support both NotionNext and General databases with customised properties.**
@@ -16,48 +16,79 @@
## TODO List ## TODO List
- [ ] Modify the Edit function for the custom properties. 改进自定义属性的编辑功能 - [x] ~~Modify the Edit function for the custom properties. 改进自定义属性的编辑功能~~
- [ ] Support group upload with one click 支持一键多数据库上传 - [ ] Support group upload with one click 支持一键多数据库上传
- [x] Support custom properties for Notion General database. 支持自定义属性 - [x] ~~Support custom properties for Notion General database. 支持自定义属性~~
- [x] Support preview for database details in plugin settings. 支持预览数据库详情 - [x] ~~Support preview for database details in plugin settings. 支持预览数据库详情~~
- [x] Support edit for database details in plugin settings. 支持编辑数据库详情 - [x] ~~Support edit for database details in plugin settings. 支持编辑数据库详情~~
## Update ## Precautions
### For customised database users
**⚠️⚠️⚠️: The exist customised database should be recreated if you want to update to version 2.3.0. The new version has a new database structure, and the old database structure is not compatible with the new version to build the index properly.**
### 2.2.3 ### 自定义数据库用户
**⚠️⚠️⚠️: 如果你想要更新到2.3.0版本,你需要重新创建自定义数据库。新版本有一个新的数据库结构,旧的数据库结构无法构建索引。**
- Fix a bug that 'text' property cannot be synchronized. 修复了一个无法同步'text'属性的bug。 ## How to use
You need seven steps to use this plugin in your Obsidian.
1. Create a database in your Notion workspace.
Open Notion, clink the `+` button on the left side, and 'Add a page' -> select 'Table' -> 'New database'.
2. On the right-top corner, click the 'Share' -> 'Publish' -> 'Publish' -> copy the database id from the URL.
3. go to [Notion API](https://www.notion.com/my-integrations) to create a new integration, and copy the token.
4. Go back to your created Notion database, click the right-top '...' -> connections -> connect to -> find the integration you created and connect it.
5. Go to obsidian settings -> community plugins -> search 'NotionNext' -> install it.
6. Create a database in the plugin settings, and fill in the database details and all properties you want to sync (**Note: the name of the properties is case-sensitive.**).
- There are three type of database that you can use:
- NotionNext: the database for the NotionNext template.(**All the properties are in lowercase**)
- General: the database for the general Notion database (**Only have `title` and `tags` columns**)
- Custom: the database for the custom properties (You can customise the properties you want to sync)
7. Create a new note in Obsidian, and fill in the frontmatter with the properties you want to sync.
### 2.2.2 ## 使用方法
如果你想使用这个插件,你需要完成下边的七个步骤。
1. 首先在你的Notion中创建一个数据库。
2. 点击右上角的'分享' -> '发布' -> '发布' -> 然后复制URL中的数据库ID。(版本不同可能id的形式也不同。只需要复制在之前的纯数字部分应该就可以了)
3. 去[Notion API](https://www.notion.com/my-integrations)创建一个新的API然后复制token。
4. 回到你创建的Notion数据库点击右上角的'...' -> 连接 -> 连接到 -> 把你刚才创建的API绑定到你的数据库
5. 回到Obsidian的设置 -> 社区插件 -> 搜索'NotionNext' -> 安装
6. 在插件设置中创建一个数据库,然后填写数据库的详情和你想要同步的属性 (**注意Notion会识别表头的大小写一定要和notion中的表头保持大小写一致**)。
- 你可以使用三种类型的数据库:
- NotionNext: 用于NotionNext模板的数据库。(**默认全部小写**)
- General: 用于普通的Notion数据库**只有`title``tags`两个属性**
- Custom: 用于自定义属性的数据库(你可以自定义你想要同步的属性)
7. 在Obsidian中创建一个新的笔记然后在frontmatter中写入你想要的属性。
- Fix the setting description of database. 修复数据库设置的描述错误。 ## Example
```plain
---
# default value has been set.
# for any unwanted value, you can delete it or set it to empty.
# for example, if you donot want to set password, you can delete password: "1234" or set it to password: ""
# 我已经在插件中设置了默认值,如果有不需要的选项,可以直接删除。
# 例如你不需要密码选项你可以将password: "1234"删除,或者将它设置为空。
# !!!!!!!!!!!!
# 现在阶段一定不要修改表头的名字, please do not change the name of the header in YAML front matter
# !!!!!!!!!!!!
titleicon: 📎 # emoji icon, default is 📜, 默认是📜
date: 2023-07-23 # default is today 默认是今天。 Format is YYYY-MM-DD 格式是YYYY-MM-DD
coverurl: https://img.jxpeng.dev/2023/08/843e27a210847f05a0f7cfb121fec100.jpg # default is empty 默认是空
type: Post # Post or Page, default is Post 默认是Post
slug: test # slug for url, default is empty 默认是空
status: Draft # Draft, Invisible, Published, default is Draft 默认是Draft
category: test # default is 'Obsidian' 默认是'Obsidian'
summary: this is a summary for test post # default is empty 默认是空
icon: fa-solid fa-camera # you can ignore this, default is empty 默认是空,可直接删除
password: "1234" # if you donot want to set password, you can delete this line, default is empty 默认是空,可直接删除
# 现在必须开启tags选项否则会报错
tags:
- test # tags for post
- web # add more tags if you want
---
```
### 2.2.1 ![](https://minioapi.pjx.ac.cn/img1/2024/07/7a1550aefd71175c981077ce46d03c87.png)
- improve the localisation for the custom properties setting. 改进自定义属性设置的本地化。
**Warning: the edit function for the custom properties is not perfect for now. You need to re-enter all the properties if you want to edit the properties.**
**注意:自定义属性的编辑功能现在还不完善。如果你想编辑属性,你需要重新输入所有的属性。**
### 2.2.0 (Big Update)
- add the support for custom properties in the Notion General database. 支持自定义属性
- [x] `title`, which is the first column of the database
- [x] 'Text'
- [x] 'Number'
- [x] 'Date'
- [x] 'Checkbox'
- [x] 'Select'
- [x] 'Multi-select'
- [x] 'URL'
- [x] 'Email'
- [x] 'Phone'
- [x] 'File' (**Only support external embedded files**)
![](https://minioapi.pjx.ac.cn/img1/2024/01/0cd99007409feede77bf5a3291e88af3.png)
- Once you create the properties, you can preview the database details in the plugin settings. - Once you create the properties, you can preview the database details in the plugin settings.
![](https://minioapi.pjx.ac.cn/img1/2024/01/665139962cc4cee2a0cb576b508b29f2.png) ![](https://minioapi.pjx.ac.cn/img1/2024/07/9599d77116afad065d2e31129942acc7.png)
--- ---
@@ -69,144 +100,7 @@ Thus, based on the [original author's work](https://github.com/EasyChris/obsidia
--- ---
## Archive Update <details> <summary> Previous How to Use </summary>
### 2.1.0
- add confirmation interface for deleting a database 增加删除数据库的确认界面
- fix the typo in the edit database modal 修复编辑数据库界面的标题错误
- improve the logic for the database editing 改进数据库编辑界面的逻辑
### 2.0.1
- Add the preview and edit function for database details in the plugin settings. 增加插件设置中数据库详情的预览和编辑功能。
![](https://minioapi.pjx.ac.cn/img1/2024/01/952f1e579daeac35b257ff7d744b0a3d.png)
- Preview:
![](https://minioapi.pjx.ac.cn/img1/2024/01/952f1e579daeac35b257ff7d744b0a3d.png)
- Edit:
![](https://minioapi.pjx.ac.cn/img1/2024/01/ded3d62660f5488c76488304a3fb269e.png)
### 2.0.0 (Big Update)
- redesign the plugin settings UI. From this version, the settings UI will be separated into two parts:
- one for general settings: bannerUrl and your notion username (ID)
- one for database list: You can add new database or delete the database.
- 重新设计了插件设置界面。从这个版本开始,设置界面将被分成两部分:
- 一部分是通用设置bannerUrl和你的notion用户名ID
- 一部分是数据库列表:你可以添加新的数据库或者删除数据库。
![](https://minioapi.pjx.ac.cn/img1/2023/12/f7e89241f45cfee6b902ec4b69dd6f63.png)
- You can add more databases in the plugin settings.
- 你可以在插件设置中添加更多的数据库。
![](https://minioapi.pjx.ac.cn/img1/2023/12/023bf46ebbc92c3991d2c443c575bc80.gif)
- You can sync one note to multiple databases.
- 你可以将一个笔记同步到多个数据库中。
![](https://minioapi.pjx.ac.cn/img1/2023/12/75f793bad756162e46bf41e54166eb32.png)
**Note: You need to add your previous database in the new template.**
**注意:你需要将之前的数据库添加到新的模板中。**
### 1.1.2
- Fix the typo that you cannot sync the markdown file `status` in the frontmatter to NotionNext. You can use `stats` or `status` to sync the status of the post to NotionNext. This update will not affect the function of syncing to General database.
- 修复了一个拼写错误,导致无法同步`status`到NotionNext。现在你可以使用`stats`或者`status`来同步文章的状态到NotionNext。这个更新不会影响到同步到General数据库的功能。
- **Both `stats` and `status` will work, but you can only use one of them.**
- **`stats``status`都可以使用,但是你只能使用其中一个。**
For example,
```yaml
stats: Draft # Draft, Invisible, Published, default is Draft 默认是Draft
# or
status: Draft # Draft, Invisible, Published, default is Draft 默认是Draft
# both of them will work, but you can only use one of them.
```
### 1.1.1
- Fix the setting display bug in Japanese.
- Add Japanese translation.
### 1.1.0
- Fix the custom name setting tab display bug.
- Add a toggle to control whether to sync `tags` since the empty tags may cause the syncing error.
If you switch off the `tags` function in the plugin settings, it will ignore the `tags` in your frontmatter.
If you prefer to sync tags to Notion database, you can switch on the `tags` function in the plugin settings. **You can only use the following format for tags:**
```yaml
tags: #empty tags, option 1
tags: [test,test1,test2] # use the square brackets, option 2
tags:
- test
- test1
- test2 # use the dash option 3
```
### 1.0.1
- Fix the custom name element display bug in the settings.
### 1.0.0 (Big Update)
- From this version, you can **modify the first column name (title column, default: 'title')** as you want. (**Note: You need to have the 'tags' column in your Notion General database, and add `tags:` in your markdown frontmatter. If not, you will receive `network error 400`. But you can leave the `tags:` blank.**)
![](https://minioapi.pjx.ac.cn/img1/2023/11/4a298b9be3990e9d2201bf2f50ca5a0a.png)
Like this:
![](https://minioapi.pjx.ac.cn/img1/2023/11/4cd8d79cd9dd9dde299e39c666cb3473.gif)
- Add a switch button to control whether display the setting tabs in the plugin settings for both NotionNext and Notion General databases.
![](https://minioapi.pjx.ac.cn/img1/2023/11/becb60fc44783842da4b3cf4c322f363.gif)
### 0.2.6
- Add a switch button to control whether to show the upload command in the command palette.
<!-- ![](https://minioapi.pjx.ac.cn/img1/2023/11/147c6a4eaa34da41a6f102558ed77106.png)
If you turn off the button for the General database, you won't see the option for the General database in the upload command list.
If you turn off the button for the NotionNext database, you won't see the option for the NotionNext database in the upload command list.
![](https://minioapi.pjx.ac.cn/img1/2023/11/70b8e4fc2148688ccbd6cfc53ce339a2.png) -->
### 0.2.3
- Fix the bug, now you can update normally.
### 0.2.2
- Support both NotionNext and General Notion database.
- You can have one NotionNext and one General Notion database.
- General Notion database can only have `title` and `tags` columns, and `tags` columns should be the multi-selected property. **the name of the columns is case sensitive. You should use small letter.**
![](https://minioapi.pjx.ac.cn/img1/2023/11/712a12081d855aa60f82a7b46913ab7e.gif)
![](https://minioapi.pjx.ac.cn/img1/2023/11/9de76cecceef74c78884ddfc1c221659.gif)
### 0.2.1
- Restructure the code
### 0.2.0
- From this version, the interactive logic has been rewritten. When you click the ribbon icon, it will display the sync command for all presetting NotionNext databases. You can choose the database you want to sync to. **However, only NotionNext database is supported for now.**
### 0.1.10
- Fix the Chinese support in the settings.
### 0.1.8
- Rebuild the uploadCommand function, and add one button to select the different databases. **However, only NotionNext database is supported for now.**
### 0.1.7
- [x] Removed the `convert tag` option. Now, you can directly add tags in the YAML front matter. If you don't want to add tags, you can delete the tags in the YAML front matter or leave the tags blank.
## How to Use
### Precautions ### Precautions
@@ -298,9 +192,11 @@ Usage of the template is as follows:
**Plugin preview is shown below** **Plugin preview is shown below**
![](https://minioapi.pjx.ac.cn/img1/2023/09/d6199619b68fab218fca8ae0cebece78.gif) ![](https://minioapi.pjx.ac.cn/img1/2023/09/d6199619b68fab218fca8ae0cebece78.gif)
</details>
--- ---
**Original README.md** <details> <summary> Original README.md </summary>
Many Thanks for the original author's work. I've only made some changes to the original author's work. If you find this plugin useful, please give the [original author](https://github.com/EasyChris/obsidian-to-notion) a star. Many Thanks for the original author's work. I've only made some changes to the original author's work. If you find this plugin useful, please give the [original author](https://github.com/EasyChris/obsidian-to-notion) a star.
@@ -474,10 +370,6 @@ node update-version.js
./release.sh ./release.sh
``` ```
```
# Thanks # Thanks
[Development Process | Obsidian Plugin Development Documentation](https://luhaifeng666.github.io/obsidian-plugin-docs-zh/zh/getting-started/development-workflow.html) [Development Process | Obsidian Plugin Development Documentation](https://luhaifeng666.github.io/obsidian-plugin-docs-zh/zh/getting-started/development-workflow.html)
@@ -494,3 +386,6 @@ node update-version.js
# License # License
GNU GPLv3 GNU GPLv3
</details>

View File

@@ -1,7 +1,7 @@
{ {
"id": "share-to-notionnext", "id": "share-to-notionnext",
"name": "Share to NotionNext", "name": "Share to NotionNext",
"version": "2.2.4", "version": "2.3.0",
"minAppVersion": "0.0.1", "minAppVersion": "0.0.1",
"description": "Shares obsidian md file to notion with notion api for NotionNext web deploy, originally created by EasyChris/obsidian-to-notion.", "description": "Shares obsidian md file to notion with notion api for NotionNext web deploy, originally created by EasyChris/obsidian-to-notion.",
"author": "EasyChris, jxpeng98", "author": "EasyChris, jxpeng98",

View File

@@ -12,7 +12,7 @@ date: 2023-07-23 # default is today 默认是今天。 Format is YYYY-MM-DD
coverurl: https://img.jxpeng.dev/2023/08/843e27a210847f05a0f7cfb121fec100.jpg # default is empty 默认是空 coverurl: https://img.jxpeng.dev/2023/08/843e27a210847f05a0f7cfb121fec100.jpg # default is empty 默认是空
type: Post # Post or Page, default is Post 默认是Post type: Post # Post or Page, default is Post 默认是Post
slug: test # slug for url, default is empty 默认是空 slug: test # slug for url, default is empty 默认是空
stats: Draft # Draft, Invisible, Published, default is Draft 默认是Draft status: Draft # Draft, Invisible, Published, default is Draft 默认是Draft
category: test # default is 'Obsidian' 默认是'Obsidian' category: test # default is 'Obsidian' 默认是'Obsidian'
summary: this is a summary for test post # default is empty 默认是空 summary: this is a summary for test post # default is empty 默认是空
icon: fa-solid fa-camera # you can ignore this, default is empty 默认是空,可直接删除 icon: fa-solid fa-camera # you can ignore this, default is empty 默认是空,可直接删除

View File

@@ -1,6 +1,6 @@
{ {
"name": "share-to-notionnext", "name": "share-to-notionnext",
"version": "2.2.4", "version": "2.3.0",
"type": "module", "type": "module",
"description": "Shares obsidian md file to notion with notion api for NotionNext web deploy, originally created by EasyChris/obsidian-to-notion.", "description": "Shares obsidian md file to notion with notion api for NotionNext web deploy, originally created by EasyChris/obsidian-to-notion.",
"main": "main.js", "main": "main.js",

View File

@@ -11,7 +11,7 @@ export interface DatabaseList {
} }
export class FuzzySuggester extends FuzzySuggestModal<DatabaseList>{ export class FuzzySuggester extends FuzzySuggestModal<DatabaseList> {
private plugin: MyPlugin; private plugin: MyPlugin;
private data: DatabaseList[]; private data: DatabaseList[];
private callback: any; private callback: any;

View File

@@ -1,9 +1,9 @@
import { i18nConfig } from "src/lang/I18n"; import { i18nConfig } from "src/lang/I18n";
import {Editor, MarkdownView, setTooltip} from "obsidian"; import { Editor, MarkdownView, setTooltip } from "obsidian";
import { FuzzySuggester, DatabaseList } from "./FuzzySuggester"; import { FuzzySuggester, DatabaseList } from "./FuzzySuggester";
import {uploadCommandCustom, uploadCommandGeneral, uploadCommandNext} from "../upload/uploadCommand"; import { uploadCommandCustom, uploadCommandGeneral, uploadCommandNext } from "../upload/uploadCommand";
import ObsidianSyncNotionPlugin from "src/main"; import ObsidianSyncNotionPlugin from "src/main";
import {DatabaseDetails} from "../ui/settingTabs"; import { DatabaseDetails } from "../ui/settingTabs";
interface Command { interface Command {

View File

@@ -33,6 +33,8 @@ export const en = {
NotionUserDesc: NotionUserDesc:
"Collect from share link likes:https://username.notion.site. Your notion id is [username]", "Collect from share link likes:https://username.notion.site. Your notion id is [username]",
NotionUserText: "Enter your notion ID", NotionUserText: "Enter your notion ID",
NotionLinkDisplay: "Notion Link Display",
NotionLinkDisplayDesc: "Default is ON, if you want to hide the link in the front matter, please turn it off",
NotionGeneralSettingHeader: "General Notion Database Settings", NotionGeneralSettingHeader: "General Notion Database Settings",
NotionGeneralButton: "Notion General Sync", NotionGeneralButton: "Notion General Sync",
NotionGeneralButtonDesc: "Open this option, Sync to Notion General Database command will be displayed in the command palette (default: ON)", NotionGeneralButtonDesc: "Open this option, Sync to Notion General Database command will be displayed in the command palette (default: ON)",

View File

@@ -31,6 +31,8 @@ export const ja = {
NotionUser: "Notion IDユーザー名、任意", NotionUser: "Notion IDユーザー名、任意",
NotionUserDesc: "共有リンクから取得https://username.notion.site。Notion IDは[username]です", NotionUserDesc: "共有リンクから取得https://username.notion.site。Notion IDは[username]です",
NotionUserText: "Notion IDを入力", NotionUserText: "Notion IDを入力",
NotionLinkDisplay: "Notionリンク表示",
NotionLinkDisplayDesc: "デフォルトはONです。front matterにリンクを非表示にしたい場合は、オフにしてください",
NotionGeneralSettingHeader: "一般的なNotionデータベース設定", NotionGeneralSettingHeader: "一般的なNotionデータベース設定",
NotionGeneralButton: "一般的なNotion同期", NotionGeneralButton: "一般的なNotion同期",
NotionGeneralButtonDesc: "このオプションを開くと、一般的なNotionデータベース同期コマンドがコマンドパレットに表示されますデフォルトON", NotionGeneralButtonDesc: "このオプションを開くと、一般的なNotionデータベース同期コマンドがコマンドパレットに表示されますデフォルトON",

View File

@@ -33,6 +33,8 @@ export const zh = {
NotionUserDesc: NotionUserDesc:
"数据库分享链接类似https://username.notion.site/。你的 Notion ID 是 [username]", "数据库分享链接类似https://username.notion.site/。你的 Notion ID 是 [username]",
NotionUserText: "输入你的 Notion ID", NotionUserText: "输入你的 Notion ID",
NotionLinkDisplay: "Notion 链接显示",
NotionLinkDisplayDesc: "默认开启如果你不想在front matter中显示链接请关闭",
NotionGeneralSettingHeader: "普通 Notion 数据库设置", NotionGeneralSettingHeader: "普通 Notion 数据库设置",
NotionGeneralButton: "普通数据库同步", NotionGeneralButton: "普通数据库同步",
NotionGeneralButtonDesc: "打开此选项,同步到普通数据库命令将显示在命令面板中(默认:开)", NotionGeneralButtonDesc: "打开此选项,同步到普通数据库命令将显示在命令面板中(默认:开)",

View File

@@ -1,162 +0,0 @@
import {App, Modal, Setting} from "obsidian";
import ObsidianSyncNotionPlugin from "../main";
import {ObsidianSettingTab} from "./settingTabs";
import {i18nConfig} from "../lang/I18n";
export class CustomModal extends Modal {
propertyLines: Setting[] = []; // Store all property line settings
properties: { customName: string, customType: string }[] = []; // Array to store property values and types
plugin: ObsidianSyncNotionPlugin;
settingTab: ObsidianSettingTab;
constructor(app: App) {
super(app);
}
createPropertyLine(containerEl: HTMLElement): void {
const propertyIndex = this.properties.length;
this.properties.push({customName: "", customType: ""}); // Initialize with empty values
const propertyLine = new Setting(containerEl)
if (propertyIndex === 0) {
propertyLine
.setName(i18nConfig.CustomPropertyFirstColumn)
.setDesc(i18nConfig.CustomPropertyFirstColumnDesc)
propertyLine.addText((text) => {
text
.setPlaceholder("Property name")
.setValue("")
.onChange(async (value) => {
this.properties[propertyIndex].customName = value; // Update the customValue of the specific property
});
}
)
propertyLine.addDropdown((dropdown) => {
dropdown
.addOption("title", "Title")
.setValue("")
.onChange(async (value) => {
this.properties[propertyIndex].customType = value; // Update the customType of the specific property
});
}
)
} else {
propertyLine
.setName(i18nConfig.CustomProperty + (propertyIndex))
propertyLine.addText((text) => {
text
.setPlaceholder(i18nConfig.CustomPropertyName)
.setValue("")
.onChange(async (value) => {
this.properties[propertyIndex].customName = value; // Update the customValue of the specific property
});
}
)
propertyLine.addDropdown((dropdown) => {
dropdown
// .addOption("none", '')
.addOption("text", "Text")
.addOption("number", "Number")
.addOption("select", "Select")
.addOption("multi_select", "Multi-Select")
.addOption("date", "Date")
// .addOption("person", "Person")
.addOption("files", "Files & Media")
.addOption("checkbox", "Checkbox")
.addOption("url", "URL")
.addOption("email", "Email")
.addOption("phone_number", "Phone Number")
// .addOption("formula", "Formula")
// .addOption("relation", "Relation")
// .addOption("rollup", "Rollup")
// .addOption("created_time", "Created time")
// .addOption("created_by", "Created by")
// .addOption("last_edited_time", "Last Edited Time")
// .addOption("last_edited_by", "Last Edited By")
.setValue("")
.onChange(async (value) => {
this.properties[propertyIndex].customType = value; // Update the customType of the specific property
});
}
)
propertyLine.addButton((button) => {
return button
.setTooltip("Delete")
.setIcon("trash")
.onClick(async () => {
// Handle the deletion of this property line
this.propertyLines = this.propertyLines.filter(line => line !== propertyLine);
this.properties.splice(propertyIndex, 1); // Remove the property from the array
propertyLine.settingEl.remove();
});
}
);
}
this.propertyLines.push(propertyLine);
}
display(): void {
this.containerEl.addClass("custom-modal");
this.titleEl.setText(i18nConfig.AddCustomProperty);
let {contentEl} = this;
contentEl.empty();
const customDiv = contentEl.createDiv("custom-div");
new Setting(customDiv)
.setName(i18nConfig.AddNewProperty)
.setDesc(i18nConfig.AddNewPropertyDesc)
.addButton((button) => {
return button
.setTooltip("Add")
.setIcon("plus")
.onClick(async () => {
const customTabs = customDiv.createDiv("custom-tabs");
this.createPropertyLine(customTabs);
});
});
let footerEl = this.contentEl.createDiv("save-custom-value");
let saveButton = new Setting(footerEl)
saveButton.addButton((button) => {
return button
.setTooltip("Save")
.setIcon("checkmark")
.onClick(async () => {
this.close();
});
}
);
saveButton.addExtraButton((button) => {
return button
.setTooltip("Cancel")
.setIcon("cross")
.onClick(async () => {
this.close();
});
}
);
}
onOpen(): void {
this.display();
}
onClose(): void {
const {contentEl} = this;
contentEl.empty();
}
}

View File

@@ -1,5 +1,5 @@
import {App, ButtonComponent, Modal, Setting} from "obsidian"; import { App, ButtonComponent, Modal, Setting } from "obsidian";
import {DatabaseDetails, ObsidianSettingTab} from "./settingTabs"; import { DatabaseDetails, ObsidianSettingTab } from "./settingTabs";
import ObsidianSyncNotionPlugin from "../main"; import ObsidianSyncNotionPlugin from "../main";
export class DeleteModal extends Modal { export class DeleteModal extends Modal {
@@ -21,12 +21,12 @@ export class DeleteModal extends Modal {
this.containerEl.addClass("delete-modal"); this.containerEl.addClass("delete-modal");
this.titleEl.setText('Delete Database'); this.titleEl.setText('Delete Database');
let {contentEl} = this; let { contentEl } = this;
contentEl.empty(); contentEl.empty();
const deleteDiv = contentEl.createDiv('delete-div'); const deleteDiv = contentEl.createDiv('delete-div');
deleteDiv.createEl('h4', {text: 'Are you sure you want to delete the following database?'}); deleteDiv.createEl('h4', { text: 'Are you sure you want to delete the following database?' });
deleteDiv.createEl('h2', {text: this.dbDetails.fullName + ' (' + this.dbDetails.abName + ', ' + this.dbDetails.format +')'}); deleteDiv.createEl('h2', { text: this.dbDetails.fullName + ' (' + this.dbDetails.abName + ', ' + this.dbDetails.format + ')' });
// add delete button // add delete button

View File

@@ -1,11 +1,12 @@
import {App, ButtonComponent, Modal, Setting} from "obsidian"; import { App, ButtonComponent, Setting } from "obsidian";
import {SettingModal} from "./settingModal"; import { customProperty, SettingModal } from "./settingModal";
import ObsidianSyncNotionPlugin from "../main"; import ObsidianSyncNotionPlugin from "../main";
import {DatabaseDetails, ObsidianSettingTab} from "./settingTabs"; import { DatabaseDetails, ObsidianSettingTab } from "./settingTabs";
import {i18nConfig} from "../lang/I18n"; import { i18nConfig } from "../lang/I18n";
import {CustomModal} from "./CustomModal";
export class EditModal extends SettingModal { export class EditModal extends SettingModal {
propertyLines: Setting[] = []; // Store all property line settings
[key: string]: any; // Index signature
dataTemp: Record<string, any> = { dataTemp: Record<string, any> = {
databaseFormatTemp: '', databaseFormatTemp: '',
// databaseFormatTempInd: false, // databaseFormatTempInd: false,
@@ -70,7 +71,7 @@ export class EditModal extends SettingModal {
this.dataTemp.tagButtonTemp = dbDetails.tagButton; this.dataTemp.tagButtonTemp = dbDetails.tagButton;
this.dataTemp.customTitleButtonTemp = dbDetails.customTitleButton; this.dataTemp.customTitleButtonTemp = dbDetails.customTitleButton;
this.dataTemp.customTitleNameTemp = dbDetails.customTitleName; this.dataTemp.customTitleNameTemp = dbDetails.customTitleName;
this.dataTemp.customPropertiesTemp = dbDetails.customProperties; this.dataTemp.customPropertiesTemp = dbDetails.customProperties.map(prop => ({ ...prop })); // Ensure deep copy
// this.dataTemp.customValues = dbDetails.customValues; // this.dataTemp.customValues = dbDetails.customValues;
this.dataTemp.savedTemp = dbDetails.saved; this.dataTemp.savedTemp = dbDetails.saved;
@@ -83,7 +84,7 @@ export class EditModal extends SettingModal {
this.dataPrev.tagButtonPrev = dbDetails.tagButton; this.dataPrev.tagButtonPrev = dbDetails.tagButton;
this.dataPrev.customTitleButtonPrev = dbDetails.customTitleButton; this.dataPrev.customTitleButtonPrev = dbDetails.customTitleButton;
this.dataPrev.customTitleNamePrev = dbDetails.customTitleName; this.dataPrev.customTitleNamePrev = dbDetails.customTitleName;
this.dataPrev.customPropertiesPrev = dbDetails.customProperties; this.dataPrev.customPropertiesPrev = dbDetails.customProperties.map(prop => ({ ...prop })); // Ensure deep copy
// this.dataTemp.customValues = dbDetails.customValues; // this.dataTemp.customValues = dbDetails.customValues;
this.dataPrev.savedPrev = dbDetails.saved; this.dataPrev.savedPrev = dbDetails.saved;
} }
@@ -94,12 +95,13 @@ export class EditModal extends SettingModal {
this.containerEl.addClass("edit-modal"); this.containerEl.addClass("edit-modal");
this.titleEl.setText('Edit Database'); this.titleEl.setText('Edit Database');
let {contentEl} = this; let { contentEl } = this;
contentEl.empty(); contentEl.empty();
const editDiv = contentEl.createDiv('edit-div'); const editDiv = contentEl.createDiv('edit-div');
const nextTabs = contentEl.createDiv('next-tabs'); const nextTabs = contentEl.createDiv('next-tabs');
new Setting(editDiv) new Setting(editDiv)
.setName(i18nConfig.databaseFormat) .setName(i18nConfig.databaseFormat)
.setDesc(i18nConfig.databaseFormatDesc) .setDesc(i18nConfig.databaseFormatDesc)
@@ -131,6 +133,8 @@ export class EditModal extends SettingModal {
.onClick(async () => { .onClick(async () => {
this.dataTemp.savedTempInd = true; this.dataTemp.savedTempInd = true;
this.dataTemp.savedTemp = true; this.dataTemp.savedTemp = true;
// console.log(this.dataTemp);
// console.log(this.dataPrev);
this.close(); this.close();
}); });
} }
@@ -140,19 +144,18 @@ export class EditModal extends SettingModal {
.setTooltip('Cancel') .setTooltip('Cancel')
.setIcon('cross') .setIcon('cross')
.onClick(() => { .onClick(() => {
this.dataTemp.savedTempInd = false; // console.log(this.dataTemp);
// console.log(this.dataPrev);
this.close(); this.close();
}); });
} }
); );
} }
onOpen(): void { onOpen(): void {
this.display() this.display()
} }
updateContentBasedOnSelection(value: string, nextTabs: HTMLElement): void { updateContentBasedOnSelection(value: string, nextTabs: HTMLElement): void {
// Clear existing content // Clear existing content
nextTabs.empty(); nextTabs.empty();
@@ -162,13 +165,13 @@ export class EditModal extends SettingModal {
nextTabs.createEl('h3', { text: i18nConfig.NotionGeneralSettingHeader }); nextTabs.createEl('h3', { text: i18nConfig.NotionGeneralSettingHeader });
// add full name // add full name
this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.dataTemp.databaseFullNameTemp,'dataTemp', 'databaseFullNameTemp') this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.dataTemp.databaseFullNameTemp, 'dataTemp', 'databaseFullNameTemp')
// add abbreviate name // add abbreviate name
this.createSettingEl(nextTabs, i18nConfig.databaseAbbreviateName, i18nConfig.databaseAbbreviateNameDesc, 'text', i18nConfig.databaseAbbreviateNameText, this.dataTemp.databaseAbbreviateNameTemp, 'dataTemp','databaseAbbreviateNameTemp') this.createSettingEl(nextTabs, i18nConfig.databaseAbbreviateName, i18nConfig.databaseAbbreviateNameDesc, 'text', i18nConfig.databaseAbbreviateNameText, this.dataTemp.databaseAbbreviateNameTemp, 'dataTemp', 'databaseAbbreviateNameTemp')
// tag button // tag button
this.createSettingEl(nextTabs, i18nConfig.NotionTagButton, i18nConfig.NotionTagButtonDesc, 'toggle', i18nConfig.NotionCustomTitleText, this.dataTemp.tagButtonTemp, 'dataTemp','tagButtonTemp') this.createSettingEl(nextTabs, i18nConfig.NotionTagButton, i18nConfig.NotionTagButtonDesc, 'toggle', i18nConfig.NotionCustomTitleText, this.dataTemp.tagButtonTemp, 'dataTemp', 'tagButtonTemp')
// add custom title button // add custom title button
@@ -180,49 +183,28 @@ export class EditModal extends SettingModal {
.setValue(this.dataTemp.customTitleButtonTemp) .setValue(this.dataTemp.customTitleButtonTemp)
.onChange(async (value) => { .onChange(async (value) => {
this.dataTemp.customTitleButtonTemp = value; this.dataTemp.customTitleButtonTemp = value;
this.updateSettingEl(CustomNameEl, value) this.updateSettingEl(CustomNameEl, value)
// this.updateSettingEl(CustomValuesEl, value)
// await this.plugin.saveSettings();
// await this.plugin.commands.updateCommand();
}) })
); );
// add custom title name // add custom title name
const CustomNameEl = this.createStyleDiv('custom-name', (this.dataTemp.customTitleButtonTemp), nextTabs); const CustomNameEl = this.createStyleDiv('custom-name', (this.dataTemp.customTitleButtonTemp), nextTabs);
this.createSettingEl(CustomNameEl, i18nConfig.NotionCustomTitleName, i18nConfig.NotionCustomTitleNameDesc, 'text', i18nConfig.NotionCustomTitleText, this.dataTemp.customTitleNameTemp,'dataTemp', 'customTitleNameTemp') this.createSettingEl(CustomNameEl, i18nConfig.NotionCustomTitleName, i18nConfig.NotionCustomTitleNameDesc, 'text', i18nConfig.NotionCustomTitleText, this.dataTemp.customTitleNameTemp, 'dataTemp', 'customTitleNameTemp')
// add api key // add api key
this.createSettingEl(nextTabs, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.dataTemp.notionAPITemp, 'dataTemp','notionAPITemp') this.createSettingEl(nextTabs, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.dataTemp.notionAPITemp, 'dataTemp', 'notionAPITemp')
// add database id // add database id
this.createSettingEl(nextTabs, i18nConfig.DatabaseID, i18nConfig.DatabaseIDDesc, 'password', i18nConfig.DatabaseIDText, this.dataTemp.databaseIDTemp, 'dataTemp','databaseIDTemp') this.createSettingEl(nextTabs, i18nConfig.DatabaseID, i18nConfig.DatabaseIDDesc, 'password', i18nConfig.DatabaseIDText, this.dataTemp.databaseIDTemp, 'dataTemp', 'databaseIDTemp')
} else if (value === 'next') { } else if (value === 'next') {
nextTabs.createEl('h3', { text: i18nConfig.NotionNextSettingHeader }); nextTabs.createEl('h3', { text: i18nConfig.NotionNextSettingHeader });
// add full name
this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.dataTemp.databaseFullNameTemp, 'dataTemp','databaseFullNameTemp')
// add abbreviate name
this.createSettingEl(nextTabs, i18nConfig.databaseAbbreviateName, i18nConfig.databaseAbbreviateNameDesc, 'text', i18nConfig.databaseAbbreviateNameText, this.dataTemp.databaseAbbreviateNameTemp, 'dataTemp','databaseAbbreviateNameTemp')
// add api key
this.createSettingEl(nextTabs, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.dataTemp.notionAPITemp, 'dataTemp','notionAPITemp')
// add database id
this.createSettingEl(nextTabs, i18nConfig.DatabaseID, i18nConfig.DatabaseIDDesc, 'password', i18nConfig.DatabaseIDText, this.dataTemp.databaseIDTemp, 'dataTemp','databaseIDTemp')
} else if (value === 'custom') {
nextTabs.createEl('h3', {text: i18nConfig.NotionCustomSettingHeader});
// add full name // add full name
this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.dataTemp.databaseFullNameTemp, 'dataTemp', 'databaseFullNameTemp') this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.dataTemp.databaseFullNameTemp, 'dataTemp', 'databaseFullNameTemp')
@@ -235,31 +217,123 @@ export class EditModal extends SettingModal {
// add database id // add database id
this.createSettingEl(nextTabs, i18nConfig.DatabaseID, i18nConfig.DatabaseIDDesc, 'password', i18nConfig.DatabaseIDText, this.dataTemp.databaseIDTemp, 'dataTemp', 'databaseIDTemp') this.createSettingEl(nextTabs, i18nConfig.DatabaseID, i18nConfig.DatabaseIDDesc, 'password', i18nConfig.DatabaseIDText, this.dataTemp.databaseIDTemp, 'dataTemp', 'databaseIDTemp')
// add new property button } else if (value === 'custom') {
new Setting(nextTabs)
.setName(i18nConfig.NotionCustomValues)
.setDesc(i18nConfig.NotionCustomValuesDesc)
.addButton((button: ButtonComponent) => {
return button
.setTooltip('Add new property')
.setIcon('plus')
.onClick(async () => {
let customModal = new CustomModal(this.app);
customModal.onClose = () => { nextTabs.createEl('h3', { text: i18nConfig.NotionCustomSettingHeader });
this.renderCustomPreview(customModal.properties, nextTabs) // add full name
this.dataTemp.customPropertiesTemp = customModal.properties; this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.dataTemp.databaseFullNameTemp, 'dataTemp', 'databaseFullNameTemp')
// add abbreviate name
this.createSettingEl(nextTabs, i18nConfig.databaseAbbreviateName, i18nConfig.databaseAbbreviateNameDesc, 'text', i18nConfig.databaseAbbreviateNameText, this.dataTemp.databaseAbbreviateNameTemp, 'dataTemp', 'databaseAbbreviateNameTemp')
// add api key
this.createSettingEl(nextTabs, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.dataTemp.notionAPITemp, 'dataTemp', 'notionAPITemp')
// add database id
this.createSettingEl(nextTabs, i18nConfig.DatabaseID, i18nConfig.DatabaseIDDesc, 'password', i18nConfig.DatabaseIDText, this.dataTemp.databaseIDTemp, 'dataTemp', 'databaseIDTemp')
// add custom properties
this.initializePropertyLines(nextTabs, this.dataTemp.customPropertiesTemp);
}
} }
customModal.open(); initializePropertyLines(containerEl: HTMLElement, properties: customProperty[]): void {
if (!containerEl) {
console.error('Failed to initialize property lines: containerEl is null');
return;
}
new Setting(containerEl)
.setName("Add New Property")
.setDesc("Click to add a new property")
.addButton(button => {
return button
.setButtonText('Add')
.setTooltip('Add one more property')
.onClick(() => {
this.createPropertyLine(containerEl, properties);
});
});
properties.forEach(property => {
this.updatePropertyLine(containerEl, property, properties);
}); });
} }
);
updatePropertyLine(containerEl: HTMLElement, property: customProperty, properties: customProperty[]) {
let isExistingProperty = property !== null;
const propertyIndex = isExistingProperty ? property.index : properties.length;
const propertyLine = new Setting(containerEl)
.setName(propertyIndex === 0 ? i18nConfig.CustomPropertyFirstColumn : `${i18nConfig.CustomProperty} ${propertyIndex}`)
.setDesc(propertyIndex === 0 ? i18nConfig.CustomPropertyFirstColumnDesc : "");
propertyLine.addText(text => {
text.setPlaceholder(i18nConfig.CustomPropertyName)
.setValue(isExistingProperty ? property.customName : "")
.onChange(value => {
const actualIndex = properties.findIndex(p => p.index === propertyIndex);
if (actualIndex !== -1) {
properties[actualIndex].customName = value;
} else {
properties.push({ customName: value, customType: '', index: propertyIndex });
isExistingProperty = true;
}
});
});
propertyLine.addDropdown((dropdown) => {
const options: Record<string, string> = {
'text': 'Text',
'number': 'Number',
'select': 'Select',
'multi_select': 'Multi-Select',
'date': 'Date',
'files': 'Files & Media',
'checkbox': 'Checkbox',
'url': 'URL',
'email': 'Email',
'phone_number': 'Phone Number'
};
if (propertyIndex === 0) {
dropdown.addOption('title', 'Title');
} else {
Object.keys(options).forEach(key => {
dropdown.addOption(key, options[key]);
});
} }
dropdown.setValue(isExistingProperty ? property.customType : "")
.onChange(value => {
const actualIndex = properties.findIndex(p => p.index === propertyIndex);
if (actualIndex !== -1) {
properties[actualIndex].customType = value;
} else if (!isExistingProperty) {
properties.push({ customName: '', customType: value, index: propertyIndex });
isExistingProperty = true; // Update the flag to prevent re-adding
}
});
});
if (propertyIndex > 0) {
propertyLine.addButton(button => {
return button
.setTooltip("Delete")
.setIcon("trash")
.onClick(() => {
console.log('Deleting property', properties[propertyIndex]);
this.deleteProperty(propertyIndex, properties);
});
});
} }
this.propertyLines.push(propertyLine);
this.updatePropertyLines();
}
createStyleDiv(className: string, commandValue: boolean = false, parentEl: HTMLElement): HTMLDivElement { createStyleDiv(className: string, commandValue: boolean = false, parentEl: HTMLElement): HTMLDivElement {
return super.createStyleDiv(className, commandValue, parentEl); return super.createStyleDiv(className, commandValue, parentEl);

View File

@@ -1,13 +1,15 @@
import {App, ExtraButtonComponent, Modal, Notice, Setting} from "obsidian"; import { App, ExtraButtonComponent, Modal, Notice, Setting } from "obsidian";
import ObsidianSyncNotionPlugin from "../main"; import ObsidianSyncNotionPlugin from "../main";
import {DatabaseDetails, ObsidianSettingTab} from "./settingTabs"; import { DatabaseDetails, ObsidianSettingTab } from "./settingTabs";
import { customProperty } from "./settingModal";
import { i18nConfig } from "../lang/I18n";
export class PreviewModal extends Modal { export class PreviewModal extends Modal {
plugin: ObsidianSyncNotionPlugin; plugin: ObsidianSyncNotionPlugin;
settingTab: ObsidianSettingTab; settingTab: ObsidianSettingTab;
dbDetails: DatabaseDetails; dbDetails: DatabaseDetails;
constructor(app:App, plugin: ObsidianSyncNotionPlugin, settingTab: ObsidianSettingTab, dbDetails: DatabaseDetails) { constructor(app: App, plugin: ObsidianSyncNotionPlugin, settingTab: ObsidianSettingTab, dbDetails: DatabaseDetails) {
super(app); super(app);
this.plugin = plugin; this.plugin = plugin;
this.settingTab = settingTab; this.settingTab = settingTab;
@@ -120,12 +122,9 @@ export class PreviewModal extends Modal {
if (this.dbDetails.format === 'custom') { if (this.dbDetails.format === 'custom') {
const customPropertiesEl = new Setting(previewEl) const customPrv = previewEl.createDiv("custom-tabs");
customPropertiesEl
.setName('Custom Properties') this.previewPropertyLine(previewEl, this.dbDetails.customProperties);
.addTextArea(text => text
.setValue(JSON.stringify(this.dbDetails.customProperties, null, 2))
.setDisabled(true));
} }
} }
@@ -136,4 +135,44 @@ export class PreviewModal extends Modal {
} }
previewPropertyLine(containerEl: HTMLElement, properties: customProperty[]): void {
properties.forEach((property, index) => {
const propertyLine = new Setting(containerEl)
.setName(index === 0 ? i18nConfig.CustomPropertyFirstColumn : `${i18nConfig.CustomProperty} ${index}`)
.setDesc(index === 0 ? i18nConfig.CustomPropertyFirstColumnDesc : "");
propertyLine.addText(text => {
text.setPlaceholder(i18nConfig.CustomPropertyName)
.setValue(property.customName)
.setDisabled(true);
});
propertyLine.addDropdown((dropdown) => {
const options: Record<string, string> = {
'title': 'Title',
'text': 'Text',
'number': 'Number',
'select': 'Select',
'multi_select': 'Multi-Select',
'date': 'Date',
'files': 'Files & Media',
'checkbox': 'Checkbox',
'url': 'URL',
'email': 'Email',
'phone_number': 'Phone Number',
// Additional options can be added here
};
// Populate dropdown with options
Object.keys(options).forEach(key => {
dropdown.addOption(key, options[key]);
});
dropdown.setValue(property.customType)
.setDisabled(true); // Disable dropdown to prevent changes
});
});
}
} }

View File

@@ -1,17 +1,22 @@
import { import {
Modal, Modal,
Setting, Setting,
PluginSettingTab,
ButtonComponent, App ButtonComponent, App
} from 'obsidian'; } from 'obsidian';
import {i18nConfig} from "../lang/I18n"; import { i18nConfig } from "../lang/I18n";
import ObsidianSyncNotionPlugin from "../main"; import ObsidianSyncNotionPlugin from "../main";
import {DatabaseDetails, ObsidianSettingTab} from "./settingTabs"; import { DatabaseDetails, ObsidianSettingTab } from "./settingTabs";
import {CustomModal} from "./CustomModal";
export interface customProperty {
customName: string;
customType: string;
index: number;
}
export class SettingModal extends Modal { export class SettingModal extends Modal {
propertyLines: Setting[] = []; // Store all property line settings
properties: customProperty[] = []; // Array to store property values and types
[key: string]: any; // Index signature [key: string]: any; // Index signature
data: Record<string, any> = { data: Record<string, any> = {
databaseFormat: 'none', databaseFormat: 'none',
@@ -47,7 +52,6 @@ export class SettingModal extends Modal {
// this.data.customValues = dbDetails.customValues; // this.data.customValues = dbDetails.customValues;
this.data.saved = dbDetails.saved; this.data.saved = dbDetails.saved;
} }
} }
display(): void { display(): void {
@@ -55,14 +59,13 @@ export class SettingModal extends Modal {
this.titleEl.setText('Add new database'); this.titleEl.setText('Add new database');
// create the dropdown button to select the database format // create the dropdown button to select the database format
let {contentEl} = this; let { contentEl } = this;
contentEl.empty(); contentEl.empty();
const settingDiv = contentEl.createDiv('setting-div'); const settingDiv = contentEl.createDiv('setting-div');
const nextTabs = contentEl.createDiv('next-tabs'); const nextTabs = contentEl.createDiv('next-tabs');
if (this.data.saved) {
new Setting(settingDiv) new Setting(settingDiv)
.setName(i18nConfig.databaseFormat) .setName(i18nConfig.databaseFormat)
.setDesc(i18nConfig.databaseFormatDesc) .setDesc(i18nConfig.databaseFormatDesc)
@@ -80,31 +83,10 @@ export class SettingModal extends Modal {
}); });
// Initialize content based on the current dropdown value // Initialize content based on the current dropdown value
this.updateContentBasedOnSelection(this.data.databaseFormat, nextTabs); (this.data.saved) ? this.updateContentBasedOnSelection(this.data.databaseFormat, nextTabs) : this.updateContentBasedOnSelection(this.plugin.settings.databaseFormat, nextTabs);
});
} else {
new Setting(settingDiv)
.setName(i18nConfig.databaseFormat)
.setDesc(i18nConfig.databaseFormatDesc)
.addDropdown((component) => {
component
.addOption('none', '')
.addOption('general', i18nConfig.databaseGeneral)
.addOption('next', i18nConfig.databaseNext)
.addOption('custom', i18nConfig.databaseCustom)
.setValue(this.data.databaseFormat)
.onChange(async (value) => {
this.data.databaseFormat = value;
nextTabs.empty();
this.updateContentBasedOnSelection(value, nextTabs);
}); });
// Initialize content based on the current dropdown value
this.updateContentBasedOnSelection(this.plugin.settings.databaseFormat, nextTabs);
});
}
// add save button // add save button
let footerEl = contentEl.createDiv('save-button'); let footerEl = contentEl.createDiv('save-button');
@@ -115,6 +97,7 @@ export class SettingModal extends Modal {
.setIcon('checkmark') .setIcon('checkmark')
.onClick(async () => { .onClick(async () => {
this.data.saved = true; this.data.saved = true;
this.data.customProperties = this.properties;
this.close(); this.close();
}); });
} }
@@ -125,6 +108,7 @@ export class SettingModal extends Modal {
.setIcon('cross') .setIcon('cross')
.onClick(() => { .onClick(() => {
this.data.saved = false; this.data.saved = false;
// this.data.customProperties = this.properties;
this.close(); this.close();
}); });
} }
@@ -137,7 +121,7 @@ export class SettingModal extends Modal {
// Generate content based on the selected value // Generate content based on the selected value
if (value === 'general') { if (value === 'general') {
nextTabs.createEl('h3', {text: i18nConfig.NotionGeneralSettingHeader}); nextTabs.createEl('h3', { text: i18nConfig.NotionGeneralSettingHeader });
// add full name // add full name
this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.data.databaseFullName, 'data', 'databaseFullName') this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.data.databaseFullName, 'data', 'databaseFullName')
@@ -158,13 +142,8 @@ export class SettingModal extends Modal {
.setValue(this.data.customTitleButton) .setValue(this.data.customTitleButton)
.onChange(async (value) => { .onChange(async (value) => {
this.data.customTitleButton = value; this.data.customTitleButton = value;
this.updateSettingEl(CustomNameEl, value) this.updateSettingEl(CustomNameEl, value)
// this.updateSettingEl(CustomValuesEl, value)
// await this.plugin.saveSettings();
// await this.plugin.commands.updateCommand();
}) })
); );
@@ -183,7 +162,7 @@ export class SettingModal extends Modal {
} else if (value === 'next') { } else if (value === 'next') {
nextTabs.createEl('h3', {text: i18nConfig.NotionNextSettingHeader}); nextTabs.createEl('h3', { text: i18nConfig.NotionNextSettingHeader });
// add full name // add full name
this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.data.databaseFullName, 'data', 'databaseFullName') this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.data.databaseFullName, 'data', 'databaseFullName')
@@ -200,7 +179,7 @@ export class SettingModal extends Modal {
} else if (value === 'custom') { } else if (value === 'custom') {
nextTabs.createEl('h3', {text: i18nConfig.NotionCustomSettingHeader}); nextTabs.createEl('h3', { text: i18nConfig.NotionCustomSettingHeader });
// add full name // add full name
this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.data.databaseFullName, 'data', 'databaseFullName') this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.data.databaseFullName, 'data', 'databaseFullName')
@@ -220,23 +199,15 @@ export class SettingModal extends Modal {
.setDesc(i18nConfig.NotionCustomValuesDesc) .setDesc(i18nConfig.NotionCustomValuesDesc)
.addButton((button: ButtonComponent) => { .addButton((button: ButtonComponent) => {
return button return button
.setTooltip('Add new property') .setTooltip('Add one more property')
.setIcon('plus') .setButtonText('Add New Property')
.onClick(async () => { .onClick(async () => {
let customModal = new CustomModal(this.app); const customTabs = nextTabs.createDiv("custom-tabs");
this.createPropertyLine(customTabs, this.properties);
customModal.onClose = () => {
this.renderCustomPreview(customModal.properties, nextTabs)
this.data.customProperties = customModal.properties;
}
customModal.open();
}); });
} }
); );
} }
} }
@@ -245,16 +216,108 @@ export class SettingModal extends Modal {
this.display() this.display()
} }
renderCustomPreview(properties: any[], nextTabs: HTMLElement) { createPropertyLine(containerEl: HTMLElement, properties: customProperty[]): void {
const previewContainer = nextTabs.createDiv('preview-container'); const propertyIndex = properties.length;
properties.forEach((property: { customName: any; customType: any; }) => { properties.push({ customName: "", customType: "", index: propertyIndex });
const propertyEl = previewContainer.createEl('div', {cls: 'property-preview'});
propertyEl.createEl('span', {text: `Property: ${property.customName}, Type: ${property.customType}`}); const propertyLine = new Setting(containerEl)
.setName(propertyIndex === 0 ? i18nConfig.CustomPropertyFirstColumn : `${i18nConfig.CustomProperty} ${propertyIndex}`)
.setDesc(propertyIndex === 0 ? i18nConfig.CustomPropertyFirstColumnDesc : "");
propertyLine.addText(text => {
text.setPlaceholder(i18nConfig.CustomPropertyName)
.setValue("")
.onChange(value => {
let actualIndex = properties.findIndex(p => p.index === propertyIndex);
if (actualIndex !== -1) {
properties[actualIndex].customName = value;
}
});
}); });
propertyLine.addDropdown((dropdown) => {
const options: Record<string, string> = {
'text': 'Text',
'number': 'Number',
'select': 'Select',
'multi_select': 'Multi-Select',
'date': 'Date',
'files': 'Files & Media',
'checkbox': 'Checkbox',
'url': 'URL',
'email': 'Email',
'phone_number': 'Phone Number',
// 'formula': 'Formula',
// 'relation': 'Relation',
// 'rollup': 'Rollup',
// 'created_time': 'Created time',
// 'created_by': 'Created by',
// 'last_edited_time': 'Last Edited Time',
// 'last_edited_by': 'Last Edited By',
};
const currentProperty = properties[propertyIndex];
if (propertyIndex === 0) {
dropdown.addOption("title", "Title");
} else {
Object.keys(options).forEach(key => {
dropdown.addOption(key, options[key]);
});
}
dropdown.setValue("")
.onChange(value => {
if (currentProperty) {
currentProperty.customType = value;
// Retrieve the index of currentProperty from the properties array
const updatedIndex = properties.findIndex(p => p === currentProperty);
console.log(`Updated value at index ${updatedIndex}: ${value}`);
} else {
console.log("Property not found, may have been deleted.");
}
});
});
if (propertyIndex > 0) {
propertyLine.addButton(button => {
return button
.setTooltip("Delete")
.setIcon("trash")
.onClick(() => {
this.deleteProperty(propertyIndex, properties);
});
});
} }
this.propertyLines.push(propertyLine);
this.updatePropertyLines(); // Ensure property lines are updated after creation
}
deleteProperty(propertyIndex: number, properties: customProperty[]): void {
let actualIndex = properties.findIndex(p => p.index === propertyIndex);
if (actualIndex !== -1) {
properties.splice(actualIndex, 1);
if (this.propertyLines[actualIndex]) {
this.propertyLines[actualIndex].settingEl.remove();
this.propertyLines.splice(actualIndex, 1);
}
// Update indices in the properties array
properties.forEach((prop, idx) => {
prop.index = idx;
});
this.updatePropertyLines();
}
}
updatePropertyLines() {
this.propertyLines.forEach((line, idx) => {
line.setName(idx === 0 ? i18nConfig.CustomPropertyFirstColumn : `${i18nConfig.CustomProperty} ${idx}`);
});
}
// create a function to create a div with a style for pop over elements // create a function to create a div with a style for pop over elements
public createStyleDiv(className: string, commandValue: boolean = false, parentEl: HTMLElement) { public createStyleDiv(className: string, commandValue: boolean = false, parentEl: HTMLElement) {

View File

@@ -1,11 +1,10 @@
import {App, ButtonComponent, Modal, PluginSettingTab, Setting} from "obsidian"; import { App, ButtonComponent, PluginSettingTab, Setting } from "obsidian";
import {i18nConfig} from "../lang/I18n"; import { i18nConfig } from "../lang/I18n";
import ObsidianSyncNotionPlugin from "../main"; import ObsidianSyncNotionPlugin from "../main";
import {SettingModal} from "./settingModal"; import { SettingModal } from "./settingModal";
import {set} from "yaml/dist/schema/yaml-1.1/set"; import { PreviewModal } from "./PreviewModal";
import {PreviewModal} from "./PreviewModal"; import { EditModal } from "./EditModal";
import {EditModal} from "./EditModal"; import { DeleteModal } from "./DeleteModal";
import {DeleteModal} from "./DeleteModal";
export interface PluginSettings { export interface PluginSettings {
NextButton: boolean; NextButton: boolean;
@@ -37,7 +36,7 @@ export interface DatabaseDetails {
tagButton: boolean; tagButton: boolean;
customTitleButton: boolean; customTitleButton: boolean;
customTitleName: string; customTitleName: string;
customProperties:{ customName: string, customType: string }[]; customProperties: { customName: string, customType: string, index: number }[];
// customValues: string; // customValues: string;
saved: boolean; saved: boolean;
} }
@@ -84,9 +83,7 @@ export class ObsidianSettingTab extends PluginSettingTab {
this.createSettingEl(containerEl, i18nConfig.NotionUser, i18nConfig.NotionUserDesc, 'text', i18nConfig.NotionUserText, this.plugin.settings.notionUser, 'notionUser') this.createSettingEl(containerEl, i18nConfig.NotionUser, i18nConfig.NotionUserDesc, 'text', i18nConfig.NotionUserText, this.plugin.settings.notionUser, 'notionUser')
// add new button // add new button
new Setting(containerEl) new Setting(containerEl)
.setName("Add New Database") .setName("Add New Database")
.setDesc("Add New Database") .setDesc("Add New Database")
@@ -126,52 +123,21 @@ export class ObsidianSettingTab extends PluginSettingTab {
}); });
// new section to display all created database // new section to display all created database
containerEl.createEl('h2', {text: "Database List"}); containerEl.createEl('h2', { text: "Database List" });
this.databaseEl = containerEl.createDiv('database-list'); this.databaseEl = containerEl.createDiv('database-list');
// list all created database // list all created database
this.showDatabase(); this.showDatabase();
// // notion next database settings
//
// const NextTabs = new SettingNextTabs(this.app, this.plugin, this);
//
// NextTabs.display();
//
//
// // General Database Settings
// const GeneralTabs = new SettingGeneralTabs(this.app, this.plugin, this);
//
// GeneralTabs.display();
// Custom Database Settings
// containerEl.createEl('h2', {text: i18nConfig.NotionCustomSettingHeader});
//
// new Setting(containerEl)
// .setName(i18nConfig.NotionCustomButton)
// .setDesc(i18nConfig.NotionCustomButtonDesc)
// .addToggle((toggle) =>
// toggle
// .setValue(this.plugin.settings.CustomButton)
// .onChange(async (value) => {
// this.plugin.settings.CustomButton = value;
// await this.plugin.saveSettings();
// })
// );
} }
// create a function to create a div with a style for pop over elements // create a function to create a div with a style for pop over elements
public createStyleDiv(className: string, commandValue: boolean = false) { // public createStyleDiv(className: string, commandValue: boolean = false) {
return this.containerEl.createDiv(className, (div) => { // return this.containerEl.createDiv(className, (div) => {
this.updateSettingEl(div, commandValue); // this.updateSettingEl(div, commandValue);
}); // });
} // }
// update the setting display style in the setting tab // update the setting display style in the setting tab
public updateSettingEl(element: HTMLElement, commandValue: boolean) { public updateSettingEl(element: HTMLElement, commandValue: boolean) {
element.style.borderTop = commandValue ? "1px solid var(--background-modifier-border)" : "none"; element.style.borderTop = commandValue ? "1px solid var(--background-modifier-border)" : "none";
@@ -317,6 +283,8 @@ export class ObsidianSettingTab extends PluginSettingTab {
if (modal.data.deleted) { if (modal.data.deleted) {
this.plugin.deleteDatabaseDetails(dbDetails); this.plugin.deleteDatabaseDetails(dbDetails);
console.log(dbDetails.fullName + " deleted");
this.plugin.commands.updateCommand(); this.plugin.commands.updateCommand();
this.display() this.display()

View File

@@ -1,6 +1,6 @@
import { App, Notice, TFile } from "obsidian"; import { App, Notice, TFile } from "obsidian";
import ObsidianSyncNotionPlugin from "../main"; import ObsidianSyncNotionPlugin from "../main";
import {DatabaseDetails} from "../ui/settingTabs"; import { DatabaseDetails } from "../ui/settingTabs";
export async function updateYamlInfo( export async function updateYamlInfo(
yamlContent: string, yamlContent: string,

View File

@@ -1,13 +1,13 @@
import {i18nConfig} from "../lang/I18n"; import { i18nConfig } from "../lang/I18n";
import {App, Notice} from "obsidian"; import { App, Notice } from "obsidian";
import {Upload2NotionNext} from "./upload_next/Upload2NotionNext"; import { Upload2NotionNext } from "./upload_next/Upload2NotionNext";
import {Upload2NotionGeneral} from "./upload_general/Upload2NotionGeneral"; import { Upload2NotionGeneral } from "./upload_general/Upload2NotionGeneral";
import {Upload2NotionCustom} from "./upoload_custom/Upload2NotionCustom"; import { Upload2NotionCustom } from "./upoload_custom/Upload2NotionCustom";
import {DatabaseDetails, PluginSettings} from "../ui/settingTabs"; import { DatabaseDetails, PluginSettings } from "../ui/settingTabs";
import ObsidianSyncNotionPlugin from "../main"; import ObsidianSyncNotionPlugin from "../main";
import {getNowFileMarkdownContentNext} from "./upload_next/getMarkdownNext"; import { getNowFileMarkdownContentNext } from "./upload_next/getMarkdownNext";
import {getNowFileMarkdownContentGeneral} from "./upload_general/getMarkdownGeneral"; import { getNowFileMarkdownContentGeneral } from "./upload_general/getMarkdownGeneral";
import {getNowFileMarkdownContentCustom} from "./upoload_custom/getMarkdownCustom"; import { getNowFileMarkdownContentCustom } from "./upoload_custom/getMarkdownCustom";
export async function uploadCommandNext( export async function uploadCommandNext(
plugin: ObsidianSyncNotionPlugin, plugin: ObsidianSyncNotionPlugin,
@@ -16,7 +16,7 @@ export async function uploadCommandNext(
app: App, app: App,
) { ) {
const {notionAPI, databaseID} = dbDetails; const { notionAPI, databaseID } = dbDetails;
// Check if NNon exists // Check if NNon exists
// if (NNon === undefined) { // if (NNon === undefined) {
@@ -49,7 +49,7 @@ export async function uploadCommandNext(
} = await getNowFileMarkdownContentNext(app, settings) } = await getNowFileMarkdownContentNext(app, settings)
if (markDownData) { if (markDownData) {
const {basename} = nowFile; const { basename } = nowFile;
const upload = new Upload2NotionNext(plugin, dbDetails); const upload = new Upload2NotionNext(plugin, dbDetails);
const res = await upload.syncMarkdownToNotionNext(basename, emoji, cover, tags, type, slug, stats, category, summary, paword, favicon, datetime, markDownData, nowFile, this.app); const res = await upload.syncMarkdownToNotionNext(basename, emoji, cover, tags, type, slug, stats, category, summary, paword, favicon, datetime, markDownData, nowFile, this.app);
@@ -70,7 +70,7 @@ export async function uploadCommandGeneral(
app: App, app: App,
) { ) {
const {notionAPI, databaseID} = dbDetails; const { notionAPI, databaseID } = dbDetails;
// Check if the user has set up the Notion API and database ID // Check if the user has set up the Notion API and database ID
if (notionAPI === "" || databaseID === "") { if (notionAPI === "" || databaseID === "") {
@@ -79,10 +79,10 @@ export async function uploadCommandGeneral(
return; return;
} }
const {markDownData, nowFile, cover, tags} = await getNowFileMarkdownContentGeneral(app, settings) const { markDownData, nowFile, cover, tags } = await getNowFileMarkdownContentGeneral(app, settings)
if (markDownData) { if (markDownData) {
const {basename} = nowFile; const { basename } = nowFile;
const upload = new Upload2NotionGeneral(plugin, dbDetails); const upload = new Upload2NotionGeneral(plugin, dbDetails);
const res = await upload.syncMarkdownToNotionGeneral(basename, cover, tags, markDownData, nowFile, this.app); const res = await upload.syncMarkdownToNotionGeneral(basename, cover, tags, markDownData, nowFile, this.app);
@@ -104,7 +104,7 @@ export async function uploadCommandCustom(
app: App, app: App,
) { ) {
const {notionAPI, databaseID} = settings; const { notionAPI, databaseID } = settings;
// Check if the user has set up the Notion API and database ID // Check if the user has set up the Notion API and database ID
if (notionAPI === "" || databaseID === "") { if (notionAPI === "" || databaseID === "") {
@@ -113,10 +113,10 @@ export async function uploadCommandCustom(
return; return;
} }
const {markDownData, nowFile, cover, customValues} = await getNowFileMarkdownContentCustom(app, dbDetails) const { markDownData, nowFile, cover, customValues } = await getNowFileMarkdownContentCustom(app, dbDetails)
if (markDownData) { if (markDownData) {
const { basename} = nowFile; const { basename } = nowFile;
const upload = new Upload2NotionCustom(plugin, dbDetails); const upload = new Upload2NotionCustom(plugin, dbDetails);
const res = await upload.syncMarkdownToNotionCustom(cover, customValues, markDownData, nowFile, this.app); const res = await upload.syncMarkdownToNotionCustom(cover, customValues, markDownData, nowFile, this.app);

View File

@@ -1,10 +1,10 @@
import {App, Notice, requestUrl, TFile} from "obsidian"; import { App, Notice, requestUrl, TFile } from "obsidian";
import {Client} from '@notionhq/client'; import { Client } from '@notionhq/client';
import {markdownToBlocks,} from "@tryfabric/martian"; import { markdownToBlocks, } from "@tryfabric/martian";
import * as yamlFrontMatter from "yaml-front-matter"; import * as yamlFrontMatter from "yaml-front-matter";
// import * as yaml from "yaml" // import * as yaml from "yaml"
import MyPlugin from "src/main"; import MyPlugin from "src/main";
import {DatabaseDetails} from "../../ui/settingTabs"; import { DatabaseDetails } from "../../ui/settingTabs";
export class UploadBaseGeneral { export class UploadBaseGeneral {
plugin: MyPlugin; plugin: MyPlugin;
@@ -19,7 +19,7 @@ export class UploadBaseGeneral {
async deletePage(notionID: string) { async deletePage(notionID: string) {
const {notionAPI} = this.dbDetails const { notionAPI } = this.dbDetails
return requestUrl({ return requestUrl({
url: `https://api.notion.com/v1/blocks/${notionID}`, url: `https://api.notion.com/v1/blocks/${notionID}`,
method: 'DELETE', method: 'DELETE',
@@ -33,7 +33,7 @@ export class UploadBaseGeneral {
} }
async getDataBase(databaseID: string) { async getDataBase(databaseID: string) {
const {notionAPI} = this.dbDetails const { notionAPI } = this.dbDetails
const response = await requestUrl({ const response = await requestUrl({
url: `https://api.notion.com/v1/databases/${databaseID}`, url: `https://api.notion.com/v1/databases/${databaseID}`,
method: 'GET', method: 'GET',

View File

@@ -4,7 +4,7 @@ import { markdownToBlocks } from "@tryfabric/martian";
import * as yamlFrontMatter from "yaml-front-matter"; import * as yamlFrontMatter from "yaml-front-matter";
// import * as yaml from "yaml" // import * as yaml from "yaml"
import MyPlugin from "src/main"; import MyPlugin from "src/main";
import {DatabaseDetails, PluginSettings} from "../../ui/settingTabs"; import { DatabaseDetails, PluginSettings } from "../../ui/settingTabs";
import { UploadBaseGeneral } from "./BaseUpload2NotionGeneral"; import { UploadBaseGeneral } from "./BaseUpload2NotionGeneral";
import { updateYamlInfo } from "../updateYaml"; import { updateYamlInfo } from "../updateYaml";
@@ -138,7 +138,7 @@ export class Upload2NotionGeneral extends UploadBaseGeneral {
const file2Block = markdownToBlocks(__content, options); const file2Block = markdownToBlocks(__content, options);
const frontmasster = const frontmasster =
app.metadataCache.getFileCache(nowFile)?.frontmatter; app.metadataCache.getFileCache(nowFile)?.frontmatter;
const {abName} = this.dbDetails const { abName } = this.dbDetails
const notionIDKey = `NotionID-${abName}`; const notionIDKey = `NotionID-${abName}`;
const notionID = frontmasster ? frontmasster[notionIDKey] : null; const notionID = frontmasster ? frontmasster[notionIDKey] : null;

View File

@@ -1,6 +1,6 @@
import {App, Notice} from "obsidian"; import { App, Notice } from "obsidian";
import {i18nConfig} from "../../lang/I18n"; import { i18nConfig } from "../../lang/I18n";
import {PluginSettings} from "../../ui/settingTabs"; import { PluginSettings } from "../../ui/settingTabs";
export async function getNowFileMarkdownContentGeneral( export async function getNowFileMarkdownContentGeneral(
app: App, app: App,

View File

@@ -4,7 +4,7 @@ import { markdownToBlocks, } from "@tryfabric/martian";
import * as yamlFrontMatter from "yaml-front-matter"; import * as yamlFrontMatter from "yaml-front-matter";
// import * as yaml from "yaml" // import * as yaml from "yaml"
import MyPlugin from "src/main"; import MyPlugin from "src/main";
import {DatabaseDetails} from "../../ui/settingTabs"; import { DatabaseDetails } from "../../ui/settingTabs";
export class UploadBaseNext { export class UploadBaseNext {
plugin: MyPlugin; plugin: MyPlugin;
@@ -18,7 +18,7 @@ export class UploadBaseNext {
} }
async deletePage(notionID: string) { async deletePage(notionID: string) {
const {notionAPI} = this.dbDetails const { notionAPI } = this.dbDetails
return requestUrl({ return requestUrl({
url: `https://api.notion.com/v1/blocks/${notionID}`, url: `https://api.notion.com/v1/blocks/${notionID}`,
method: 'DELETE', method: 'DELETE',
@@ -32,7 +32,7 @@ export class UploadBaseNext {
} }
async getDataBase(databaseID: string) { async getDataBase(databaseID: string) {
const {notionAPI} = this.dbDetails const { notionAPI } = this.dbDetails
const response = await requestUrl({ const response = await requestUrl({
url: `https://api.notion.com/v1/databases/${databaseID}`, url: `https://api.notion.com/v1/databases/${databaseID}`,

View File

@@ -5,9 +5,9 @@ import { markdownToBlocks, } from "@tryfabric/martian";
import * as yamlFrontMatter from "yaml-front-matter"; import * as yamlFrontMatter from "yaml-front-matter";
// import * as yaml from "yaml" // import * as yaml from "yaml"
import MyPlugin from "src/main"; import MyPlugin from "src/main";
import {DatabaseDetails, PluginSettings} from "../../ui/settingTabs"; import { DatabaseDetails, PluginSettings } from "../../ui/settingTabs";
import { updateYamlInfo } from "../updateYaml"; import { updateYamlInfo } from "../updateYaml";
import {LIMITS, paragraph} from "@tryfabric/martian/src/notion"; import { LIMITS, paragraph } from "@tryfabric/martian/src/notion";
export class Upload2NotionNext extends UploadBaseNext { export class Upload2NotionNext extends UploadBaseNext {
settings: PluginSettings; settings: PluginSettings;
@@ -38,7 +38,7 @@ export class Upload2NotionNext extends UploadBaseNext {
) { ) {
await this.deletePage(notionID) await this.deletePage(notionID)
const { databaseID} = this.dbDetails const { databaseID } = this.dbDetails
const databaseCover = await this.getDataBase(databaseID) const databaseCover = await this.getDataBase(databaseID)
@@ -88,9 +88,6 @@ export class Upload2NotionNext extends UploadBaseNext {
parent: { parent: {
database_id: databaseID, database_id: databaseID,
}, },
icon: {
emoji: emoji || '📜'
},
properties: { properties: {
title: { title: {
title: [ title: [
@@ -101,25 +98,11 @@ export class Upload2NotionNext extends UploadBaseNext {
}, },
], ],
}, },
tags: {
multi_select: tags && true ? tags.map(tag => {
return { "name": tag }
}) : [],
},
type: { type: {
select: { select: {
name: type || 'Post' name: type || 'Post'
} }
}, },
slug: {
rich_text: [
{
text: {
content: slug || ''
}
}
]
},
status: { status: {
select: { select: {
name: stats || 'Draft' name: stats || 'Draft'
@@ -130,15 +113,7 @@ export class Upload2NotionNext extends UploadBaseNext {
name: category || 'Obsidian' name: category || 'Obsidian'
} }
}, },
summary: {
rich_text: [
{
text: {
content: summary || ''
}
}
]
},
password: { password: {
rich_text: [ rich_text: [
{ {
@@ -165,6 +140,52 @@ export class Upload2NotionNext extends UploadBaseNext {
}, },
children: childArr, children: childArr,
} }
// add tags
if (tags) {
bodyString.properties.tags = {
multi_select: tags.map(tag => {
return { "name": tag }
})
}
}
// add title icon
if (emoji) {
bodyString.icon = {
emoji: emoji
}
}
// add slug
if (slug) {
bodyString.properties.slug = {
rich_text: [
{
text: {
content: slug
}
}
]
}
}
// check if summary is available
if (summary) {
bodyString.properties.summary = {
rich_text: [
{
text: {
content: summary
}
}
]
}
}
if (cover) { if (cover) {
bodyString.cover = { bodyString.cover = {
type: "external", type: "external",
@@ -227,21 +248,21 @@ export class Upload2NotionNext extends UploadBaseNext {
const __content = yamlContent.__content const __content = yamlContent.__content
const file2Block = markdownToBlocks(__content, options); const file2Block = markdownToBlocks(__content, options);
const frontmasster = app.metadataCache.getFileCache(nowFile)?.frontmatter const frontmasster = app.metadataCache.getFileCache(nowFile)?.frontmatter
const {abName} = this.dbDetails const { abName } = this.dbDetails
const notionIDKey = `NotionID-${abName}`; const notionIDKey = `NotionID-${abName}`;
const notionID = frontmasster ? frontmasster[notionIDKey] : null; const notionID = frontmasster ? frontmasster[notionIDKey] : null;
// increase the limits // increase the limits
// Motivated by https://github.com/tryfabric/martian/issues/51 // Motivated by https://github.com/tryfabric/martian/issues/51
file2Block.forEach((block,index) => { file2Block.forEach((block, index) => {
if ( if (
block.type === 'paragraph' && block.type === 'paragraph' &&
block.paragraph.rich_text.length > LIMITS.RICH_TEXT_ARRAYS block.paragraph.rich_text.length > LIMITS.RICH_TEXT_ARRAYS
) { ) {
const newParagraphBlocks: any[] = [] const newParagraphBlocks: any[] = []
const chunk:any = [] const chunk: any = []
const richTextChunks = chunk(block.paragraph.rich_text, 100) const richTextChunks = chunk(block.paragraph.rich_text, 100)
richTextChunks.forEach((chunk: any) => { richTextChunks.forEach((chunk: any) => {

View File

@@ -1,10 +1,10 @@
import {App, Notice, requestUrl, TFile} from "obsidian"; import { App, Notice, requestUrl, TFile } from "obsidian";
import {Client} from '@notionhq/client'; import { Client } from '@notionhq/client';
import {markdownToBlocks,} from "@tryfabric/martian"; import { markdownToBlocks, } from "@tryfabric/martian";
import * as yamlFrontMatter from "yaml-front-matter"; import * as yamlFrontMatter from "yaml-front-matter";
// import * as yaml from "yaml" // import * as yaml from "yaml"
import MyPlugin from "src/main"; import MyPlugin from "src/main";
import {DatabaseDetails} from "../../ui/settingTabs"; import { DatabaseDetails } from "../../ui/settingTabs";
export class UploadBaseCustom { export class UploadBaseCustom {
plugin: MyPlugin; plugin: MyPlugin;
@@ -18,7 +18,7 @@ export class UploadBaseCustom {
} }
async deletePage(notionID: string) { async deletePage(notionID: string) {
const {notionAPI} = this.dbDetails const { notionAPI } = this.dbDetails
return requestUrl({ return requestUrl({
url: `https://api.notion.com/v1/blocks/${notionID}`, url: `https://api.notion.com/v1/blocks/${notionID}`,
method: 'DELETE', method: 'DELETE',
@@ -32,7 +32,7 @@ export class UploadBaseCustom {
} }
async getDataBase(databaseID: string) { async getDataBase(databaseID: string) {
const {notionAPI} = this.dbDetails const { notionAPI } = this.dbDetails
const response = await requestUrl({ const response = await requestUrl({
url: `https://api.notion.com/v1/databases/${databaseID}`, url: `https://api.notion.com/v1/databases/${databaseID}`,
method: 'GET', method: 'GET',
@@ -50,46 +50,4 @@ export class UploadBaseCustom {
return null; // or some other default value, if you prefer return null; // or some other default value, if you prefer
} }
} }
// async updateYamlInfo(yamlContent: string, nowFile: TFile, res: any, app: App, settings: any) {
// let {url, id} = res.json
// // replace www to notionID
// const {notionUser} = this.plugin.settings;
//
// if (notionUser !== "") {
// // replace url str "www" to notionID
// url = url.replace("www.notion.so", `${notionUser}.notion.site`)
// }
//
// await app.fileManager.processFrontMatter(nowFile, yamlContent => {
// if (yamlContent['notionID']) {
// delete yamlContent['notionID']
// }
// if (yamlContent['link']) {
// delete yamlContent['link']
// }
// // add new notionID and link
// yamlContent.notionID = id;
// yamlContent.link = url;
// });
//
// try {
// await navigator.clipboard.writeText(url)
// } catch (error) {
// new Notice(`复制链接失败,请手动复制${error}`)
// }
// // const __content = yamlContent.__content;
// // delete yamlContent.__content
// // const yamlhead = yaml.stringify(yamlContent)
// // // if yamlhead hava last \n remove it
// // const yamlhead_remove_n = yamlhead.replace(/\n$/, '')
// // // if __content have start \n remove it
// // const __content_remove_n = __content.replace(/^\n/, '')
// // const content = '---\n' +yamlhead_remove_n +'\n---\n' + __content_remove_n;
// // try {
// // await nowFile.vault.modify(nowFile, content)
// // } catch (error) {
// // new Notice(`write file error ${error}`)
// // }
// }
} }

View File

@@ -1,11 +1,11 @@
import {App, Notice, requestUrl, TFile} from "obsidian"; import { App, Notice, requestUrl, TFile } from "obsidian";
import {markdownToBlocks} from "@tryfabric/martian"; import { markdownToBlocks } from "@tryfabric/martian";
import * as yamlFrontMatter from "yaml-front-matter"; import * as yamlFrontMatter from "yaml-front-matter";
// import * as yaml from "yaml" // import * as yaml from "yaml"
import MyPlugin from "src/main"; import MyPlugin from "src/main";
import {DatabaseDetails, PluginSettings} from "../../ui/settingTabs"; import { DatabaseDetails, PluginSettings } from "../../ui/settingTabs";
import {updateYamlInfo} from "../updateYaml"; import { updateYamlInfo } from "../updateYaml";
import {UploadBaseCustom} from "./BaseUpload2NotionCustom"; import { UploadBaseCustom } from "./BaseUpload2NotionCustom";
export class Upload2NotionCustom extends UploadBaseCustom { export class Upload2NotionCustom extends UploadBaseCustom {
settings: PluginSettings; settings: PluginSettings;
@@ -26,7 +26,7 @@ export class Upload2NotionCustom extends UploadBaseCustom {
) { ) {
await this.deletePage(notionID); await this.deletePage(notionID);
const {databaseID} = this.dbDetails; const { databaseID } = this.dbDetails;
const databaseCover = await this.getDataBase( const databaseCover = await this.getDataBase(
databaseID databaseID
@@ -71,6 +71,8 @@ export class Upload2NotionCustom extends UploadBaseCustom {
}; };
} }
console.log(bodyString)
try { try {
return await requestUrl({ return await requestUrl({
url: `https://api.notion.com/v1/pages`, url: `https://api.notion.com/v1/pages`,
@@ -107,7 +109,7 @@ export class Upload2NotionCustom extends UploadBaseCustom {
const file2Block = markdownToBlocks(__content, options); const file2Block = markdownToBlocks(__content, options);
const frontmasster = const frontmasster =
app.metadataCache.getFileCache(nowFile)?.frontmatter; app.metadataCache.getFileCache(nowFile)?.frontmatter;
const {abName} = this.dbDetails const { abName } = this.dbDetails
const notionIDKey = `NotionID-${abName}`; const notionIDKey = `NotionID-${abName}`;
const notionID = frontmasster ? frontmasster[notionIDKey] : null; const notionID = frontmasster ? frontmasster[notionIDKey] : null;
@@ -205,7 +207,7 @@ export class Upload2NotionCustom extends UploadBaseCustom {
}; };
case "multi_select": case "multi_select":
return { return {
multi_select: Array.isArray(value) ? value.map(item => ({name: item})) : [{name: value}], multi_select: Array.isArray(value) ? value.map(item => ({ name: item })) : [{ name: value }],
}; };
} }
} }
@@ -218,11 +220,15 @@ export class Upload2NotionCustom extends UploadBaseCustom {
const properties: { [key: string]: any } = {}; const properties: { [key: string]: any } = {};
customProperties.forEach(({customName, customType}) => { // Only include custom properties that have values
customProperties.forEach(({ customName, customType }) => {
if (customValues[customName] !== undefined) {
properties[customName] = this.buildPropertyObject(customName, customType, customValues); properties[customName] = this.buildPropertyObject(customName, customType, customValues);
} }
}
); );
console.log(properties)
return { return {
parent: { parent: {
@@ -233,5 +239,4 @@ export class Upload2NotionCustom extends UploadBaseCustom {
}; };
} }
} }

View File

@@ -1,6 +1,6 @@
import {App, Notice} from "obsidian"; import { App, Notice } from "obsidian";
import {i18nConfig} from "../../lang/I18n"; import { i18nConfig } from "../../lang/I18n";
import {DatabaseDetails} from "../../ui/settingTabs"; import { DatabaseDetails } from "../../ui/settingTabs";
export async function getNowFileMarkdownContentCustom( export async function getNowFileMarkdownContentCustom(
app: App, app: App,