Compare commits

..

15 Commits
2.0.1 ... 2.2.2

Author SHA1 Message Date
Jiaxin Peng
9e15044f6a Update version to 2.2.2 2024-02-16 23:10:22 +00:00
Jiaxin Peng
9d891dae55 Update version to 2.2.1 2024-01-29 20:43:14 +00:00
Jiaxin Peng
bc665253ec Update version to 2.2.0 2024-01-29 19:03:09 +00:00
Jiaxin Peng
125c75f7c0 Merge pull request #13 from jxpeng98/custom
add the customisation function
2024-01-29 19:01:37 +00:00
Jiaxin Peng
8248640b5f fix the extra argument in the uploadcommand 2024-01-29 11:55:52 +00:00
Jiaxin Peng
0198898086 update the readme and changelog 2024-01-29 11:53:18 +00:00
Jiaxin Peng
8c6aea8250 Complete the basic function of customisation 2024-01-29 11:12:07 +00:00
Jiaxin Peng
a179d3da52 almost finish the structure 2024-01-29 00:55:06 +00:00
Jiaxin Peng
569d8eb699 fix the error of the display of title custom button 2024-01-28 00:26:58 +00:00
Jiaxin Peng
2a58dd3258 complete the custom ui design 2024-01-28 00:11:11 +00:00
Jiaxin Peng
8c65e471eb Update version to 2.1.2 2024-01-09 11:44:40 +00:00
Jiaxin Peng
388693d5b4 Update version to 2.1.1 2024-01-09 11:38:03 +00:00
Jiaxin Peng
dda6710fe9 remove redundant settingtabs 2024-01-09 11:37:47 +00:00
Jiaxin Peng
76ea9a4aee Update version to 2.1.0 2024-01-09 11:34:11 +00:00
Jiaxin Peng
856f83e8a1 Add confirmation delete button and modify edit modal interface. 2024-01-09 11:33:39 +00:00
26 changed files with 1181 additions and 637 deletions

View File

@@ -7,85 +7,94 @@ on:
env: env:
PLUGIN_NAME: share-to-notionnext # Change this to match the id of your plugin. PLUGIN_NAME: share-to-notionnext # Change this to match the id of your plugin.
CHANGELOG_FILENAME: CHANGELOG.md
jobs: jobs:
build: build:
name: release name: release
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- name: Use Node.js - name: Use Node.js
uses: actions/setup-node@v3 uses: actions/setup-node@v3
with: with:
node-version: "18" node-version: "18"
- name: Build # - name: Generate changelog
id: build # id: changelog
run: | # uses: saadmk11/changelog-ci@v1.1.2
npm install # with:
npm run build # github_token: ${{ secrets.REPO_ACCESS_TOKEN }}
mkdir ${{ env.PLUGIN_NAME }} # release_version: ${{ github.ref }}
cp main.js manifest.json ${{ env.PLUGIN_NAME }} # changelog_filename: CHANGELOG.md
zip -r ${{ env.PLUGIN_NAME }}.zip ${{ env.PLUGIN_NAME }}
ls
echo "tag_name=$(git tag --sort version:refname | tail -n 1)" >> $GITHUB_OUTPUT
- name: Create Release - name: Build
id: create_release id: build
uses: actions/create-release@v1 run: |
env: npm install
GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }} npm run build
VERSION: ${{ github.ref }} mkdir ${{ env.PLUGIN_NAME }}
with: cp main.js manifest.json ${{ env.PLUGIN_NAME }}
tag_name: ${{ github.ref }} zip -r ${{ env.PLUGIN_NAME }}.zip ${{ env.PLUGIN_NAME }}
release_name: ${{ github.ref }} ls
draft: false echo "tag_name=$(git tag --sort version:refname | tail -n 1)" >> $GITHUB_OUTPUT
prerelease: false
- name: Upload zip file - name: Create Release
id: upload-zip id: create_release
uses: actions/upload-release-asset@v1 uses: actions/create-release@v1
env: env:
GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }} GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
with: VERSION: ${{ github.ref }}
upload_url: ${{ steps.create_release.outputs.upload_url }} with:
asset_path: ./${{ env.PLUGIN_NAME }}.zip tag_name: ${{ github.ref }}
asset_name: ${{ env.PLUGIN_NAME }}-${{ steps.build.outputs.tag_name }}.zip release_name: ${{ github.ref }}
asset_content_type: application/zip body_path: ${{ env.CHANGELOG_FILENAME }}
draft: false
prerelease: false
- name: Upload main.js - name: Upload zip file
id: upload-main id: upload-zip
uses: actions/upload-release-asset@v1 uses: actions/upload-release-asset@v1
env: env:
GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }} GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
with: with:
upload_url: ${{ steps.create_release.outputs.upload_url }} upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./main.js asset_path: ./${{ env.PLUGIN_NAME }}.zip
asset_name: main.js asset_name: ${{ env.PLUGIN_NAME }}-${{ steps.build.outputs.tag_name }}.zip
asset_content_type: text/javascript asset_content_type: application/zip
- name: Upload manifest.json - name: Upload main.js
id: upload-manifest id: upload-main
uses: actions/upload-release-asset@v1 uses: actions/upload-release-asset@v1
env: env:
GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }} GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
with: with:
upload_url: ${{ steps.create_release.outputs.upload_url }} upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./manifest.json asset_path: ./main.js
asset_name: manifest.json asset_name: main.js
asset_content_type: application/json asset_content_type: text/javascript
- name: Upload markdown template - name: Upload manifest.json
id: upload-md id: upload-manifest
uses: actions/upload-release-asset@v1 uses: actions/upload-release-asset@v1
env: env:
GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }} GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
with: with:
upload_url: ${{ steps.create_release.outputs.upload_url }} upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./obsidian_template.md asset_path: ./manifest.json
asset_name: template.md asset_name: manifest.json
asset_content_type: text/markdown asset_content_type: application/json
- name: Upload markdown template
id: upload-md
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.REPO_ACCESS_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./obsidian_template.md
asset_name: template.md
asset_content_type: text/markdown
# - name: Upload styles.css # - name: Upload styles.css
# id: upload-css # id: upload-css

5
CHANGELOG.md Normal file
View File

@@ -0,0 +1,5 @@
# Changelog v2.2.2
## Bug Fixes
- Fix the setting description of database. 修复数据库设置的描述错误。

View File

@@ -2,26 +2,73 @@
[![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)
[![Github all releases](https://img.shields.io/github/downloads/jxpeng98/obsidian-to-NotionNext/total.svg)](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/v/release/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/))
[中文文档](README-zh.md) [中文文档](README-zh.md)
**Now, support both NotionNext and General databases with customised properties.**
**现在支持NotionNext和普通Notion数据库可自定义数据库列表。**
## TODO List
- [x] Support custom properties for Notion General database. 支持自定义属性
- [ ] Support group upload with one click 支持一键多数据库上传
- [x] Support preview for database details in plugin settings. 支持预览数据库详情
- [x] Support edit for database details in plugin settings. 支持编辑数据库详情
## Update
### 2.2.2
- Fix the setting description of database. 修复数据库设置的描述错误。
### 2.2.1
- 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.
![](https://minioapi.pjx.ac.cn/img1/2024/01/665139962cc4cee2a0cb576b508b29f2.png)
---
## Acknowledgement
Thanks to the [original author](https://github.com/EasyChris/obsidian-to-notion) for developing such a useful plugin that can synchronize Obsidian to Notion. However, the original repository can only sync Name and Tag information. For those like me who use [NotionNext](https://github.com/tangly1024/NotionNext) to set up their website, this presents some limitations. Every time I import, I need to make a lot of modifications. Thanks to the [original author](https://github.com/EasyChris/obsidian-to-notion) for developing such a useful plugin that can synchronize Obsidian to Notion. However, the original repository can only sync Name and Tag information. For those like me who use [NotionNext](https://github.com/tangly1024/NotionNext) to set up their website, this presents some limitations. Every time I import, I need to make a lot of modifications.
Thus, based on the [original author's work](https://github.com/EasyChris/obsidian-to-notion), I've added a feature to match the [NotionNext](https://github.com/tangly1024/NotionNext) template. This way, you can edit directly in Obsidian and publish with a single click after organizing. Thus, based on the [original author's work](https://github.com/EasyChris/obsidian-to-notion), I've added a feature to match the [NotionNext](https://github.com/tangly1024/NotionNext) template. This way, you can edit directly in Obsidian and publish with a single click after organizing.
**Now, support both NotionNext and General databases.** ---
**现在支持NotionNext和普通Notion数据库。** ## Archive Update
### 2.1.0
## TODO List - add confirmation interface for deleting a database 增加删除数据库的确认界面
- fix the typo in the edit database modal 修复编辑数据库界面的标题错误
- [ ] Support custom properties for Notion General database. 支持自定义属性 - improve the logic for the database editing 改进数据库编辑界面的逻辑
- [x] Support preview for database details in plugin settings. 支持预览数据库详情
- [x] Support edit for database details in plugin settings. 支持编辑数据库详情
## Update
### 2.0.1 ### 2.0.1

View File

@@ -1,7 +1,7 @@
{ {
"id": "share-to-notionnext", "id": "share-to-notionnext",
"name": "Share to NotionNext", "name": "Share to NotionNext",
"version": "2.0.1", "version": "2.2.2",
"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

@@ -1,6 +1,6 @@
{ {
"name": "share-to-notionnext", "name": "share-to-notionnext",
"version": "2.0.1", "version": "2.2.2",
"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

@@ -1,7 +1,7 @@
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 { 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";
@@ -94,11 +94,11 @@ export default class RibbonCommands {
await uploadCommandGeneral(this.plugin, this.plugin.settings, dbDetails, this.plugin.app); await uploadCommandGeneral(this.plugin, this.plugin.settings, dbDetails, this.plugin.app);
}; };
} }
// else if (dbDetails.format === 'custom') { else if (dbDetails.format === 'custom') {
// editorCallback = async (editor, view) => { editorCallback = async (editor, view) => {
// await uploadCommandGeneral(this.plugin, dbDetails, this.plugin.app); await uploadCommandCustom(this.plugin, this.plugin.settings, dbDetails, this.plugin.app);
// }; };
// } }
this.Ncommand.push({ id: commandId, name: commandName, editorCallback }); this.Ncommand.push({ id: commandId, name: commandName, editorCallback });
} }

View File

@@ -23,10 +23,11 @@ export const en = {
NotionAPIDesc: "Generate from https://www.notion.so/my-integrations", NotionAPIDesc: "Generate from https://www.notion.so/my-integrations",
NotionAPIText: "Enter your Notion API Token", NotionAPIText: "Enter your Notion API Token",
DatabaseID: "Database ID", DatabaseID: "Database ID",
DatabaseIDDesc: "Collect from the top-right Share --> Publish",
DatabaseIDText: "Enter your Database ID", DatabaseIDText: "Enter your Database ID",
BannerUrl: "Banner url (optional)", BannerUrl: "Banner url (optional)",
BannerUrlDesc: BannerUrlDesc:
"Default is empty, if you want to show a banner, please enter the url (like: https://minioapi.pjx.ac.cn/img1/2023/11/b7b40a0724e93b7d7ab494bb3b8a2da8.png)", "Default is empty, if you want to show a banner, please enter the url (like: https://abc.com/b.png)",
BannerUrlText: "Enter your banner url", BannerUrlText: "Enter your banner url",
NotionUser: "Notion ID (username, optional)", NotionUser: "Notion ID (username, optional)",
NotionUserDesc: NotionUserDesc:
@@ -65,4 +66,11 @@ export const en = {
NotionCustomSettingHeader: "Notion Custom Database Settings", NotionCustomSettingHeader: "Notion Custom Database Settings",
NotionCustomButton: "Notion Customised command switch", NotionCustomButton: "Notion Customised command switch",
NotionCustomButtonDesc: "Open this option, Sync to Notion Customised Database command will be displayed in the command palette", NotionCustomButtonDesc: "Open this option, Sync to Notion Customised Database command will be displayed in the command palette",
CustomPropertyName: "Property Name",
CustomPropertyFirstColumn: "Title Column",
CustomPropertyFirstColumnDesc: "The title of the page, must be the first property",
CustomProperty: "Property",
AddCustomProperty: "Add Custom Property",
AddNewProperty: "Add New Property",
AddNewPropertyDesc: "Add new property match with your notion database",
} }

View File

@@ -23,9 +23,10 @@ export const ja = {
NotionAPIDesc: "https://www.notion.so/my-integrations から生成してください", NotionAPIDesc: "https://www.notion.so/my-integrations から生成してください",
NotionAPIText: "Notion API トークンを入力", NotionAPIText: "Notion API トークンを入力",
DatabaseID: "データベースID", DatabaseID: "データベースID",
DatabaseIDDesc: "右上の共有 --> 公開から取得してください",
DatabaseIDText: "データベースIDを入力", DatabaseIDText: "データベースIDを入力",
BannerUrl: "バナーのURL任意", BannerUrl: "バナーのURL任意",
BannerUrlDesc: "デフォルトは空白です。バナーを表示したい場合は、URLを入力してくださいhttps://minioapi.pjx.ac.cn/img1/2023/11/b7b40a0724e93b7d7ab494bb3b8a2da8.png", BannerUrlDesc: "デフォルトは空白です。バナーを表示したい場合は、URLを入力してくださいhttps://abc.com/b.png",
BannerUrlText: "バナーのURLを入力", BannerUrlText: "バナーのURLを入力",
NotionUser: "Notion IDユーザー名、任意", NotionUser: "Notion IDユーザー名、任意",
NotionUserDesc: "共有リンクから取得https://username.notion.site。Notion IDは[username]です", NotionUserDesc: "共有リンクから取得https://username.notion.site。Notion IDは[username]です",
@@ -57,4 +58,11 @@ export const ja = {
NotionCustomSettingHeader: "Notionカスタムデータベース設定", NotionCustomSettingHeader: "Notionカスタムデータベース設定",
NotionCustomButton: "Notionカスタマイズコマンドの切り替え", NotionCustomButton: "Notionカスタマイズコマンドの切り替え",
NotionCustomButtonDesc: "このオプションを開くと、Notionカスタムデータベース同期コマンドがコマンドパレットに表示されます", NotionCustomButtonDesc: "このオプションを開くと、Notionカスタムデータベース同期コマンドがコマンドパレットに表示されます",
CustomPropertyName: "カスタムプロパティ名",
CustomPropertyFirstColumn: "最初の列のカスタムプロパティ名",
CustomPropertyFirstColumnDesc: "最初の列のカスタムプロパティ名を入力してください",
CustomProperty: "カスタムプロパティ",
AddCustomProperty: "カスタムプロパティを追加",
AddNewProperty: "新しいプロパティを追加",
AddNewPropertyDesc: "新しいプロパティを追加してください",
}; };

View File

@@ -23,10 +23,11 @@ export const zh = {
NotionAPIDesc: "从 https://www.notion.so/my-integrations 生成", NotionAPIDesc: "从 https://www.notion.so/my-integrations 生成",
NotionAPIText: "输入你的 Notion API 令牌", NotionAPIText: "输入你的 Notion API 令牌",
DatabaseID: "数据库 ID", DatabaseID: "数据库 ID",
DatabaseIDDesc: "从右上角的分享 --> 发布中获取",
DatabaseIDText: "输入你的数据库 ID", DatabaseIDText: "输入你的数据库 ID",
BannerUrl: "封面图片地址(可选)", BannerUrl: "封面图片地址(可选)",
BannerUrlDesc: BannerUrlDesc:
"默认为空如果你想显示封面图片请输入图片地址例如https://minioapi.pjx.ac.cn/img1/2023/11/b7b40a0724e93b7d7ab494bb3b8a2da8.png", "默认为空如果你想显示封面图片请输入图片地址例如https://abc.com/b.png",
BannerUrlText: "输入你的封面图片地址", BannerUrlText: "输入你的封面图片地址",
NotionUser: "Notion ID用户名可选", NotionUser: "Notion ID用户名可选",
NotionUserDesc: NotionUserDesc:
@@ -60,4 +61,11 @@ export const zh = {
NotionCustomSettingHeader: "Notion 自定义数据库设置", NotionCustomSettingHeader: "Notion 自定义数据库设置",
NotionCustomButton: "Notion 自定义数据库同步命令开关", NotionCustomButton: "Notion 自定义数据库同步命令开关",
NotionCustomButtonDesc: "打开此选项,同步到自定义数据库命令将显示在命令面板中", NotionCustomButtonDesc: "打开此选项,同步到自定义数据库命令将显示在命令面板中",
CustomPropertyName: "自定义属性名",
CustomPropertyFirstColumn: "第一列属性名",
CustomPropertyFirstColumnDesc: "第一列必须为标题属性名",
CustomProperty: "自定义属性",
AddCustomProperty: "添加自定义属性",
AddNewProperty: "添加新属性",
AddNewPropertyDesc: "添加一个和Notion数据库匹配的新属性",
} }

161
src/ui/CustomModal.ts Normal file
View File

@@ -0,0 +1,161 @@
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("text", "Text")
.addOption("number", "Number")
.addOption("select", "Select")
.addOption("multi_select", "Multi-Select")
.addOption("date", "Date")
// .addOption("person", "Person")
.addOption("file", "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("text")
.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();
}
}

64
src/ui/DeleteModal.ts Normal file
View File

@@ -0,0 +1,64 @@
import {App, ButtonComponent, Modal, Setting} from "obsidian";
import {DatabaseDetails, ObsidianSettingTab} from "./settingTabs";
import ObsidianSyncNotionPlugin from "../main";
export class DeleteModal extends Modal {
data: Record<string, any> = {
deleted: false,
}
plugin: ObsidianSyncNotionPlugin;
settingTab: ObsidianSettingTab;
dbDetails: DatabaseDetails
constructor(app: App, plugin: ObsidianSyncNotionPlugin, settingTab: ObsidianSettingTab, dbDetails: DatabaseDetails) {
super(app);
this.plugin = plugin;
this.settingTab = settingTab;
this.dbDetails = dbDetails;
}
display() {
this.containerEl.addClass("delete-modal");
this.titleEl.setText('Delete Database');
let {contentEl} = this;
contentEl.empty();
const deleteDiv = contentEl.createDiv('delete-div');
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 +')'});
// add delete button
let footerEl = contentEl.createDiv('save-button');
let deleteButton = new Setting(footerEl)
deleteButton
.addButton((button: ButtonComponent): ButtonComponent => {
return button
.setTooltip("Delete")
.setIcon("trash")
.onClick(async () => {
this.data.deleted = true;
this.close();
})
});
deleteButton.addExtraButton((button) => {
return button
.setTooltip('Cancel')
.setIcon('cross')
.onClick(() => {
this.data.deleted = false;
this.close();
});
});
}
onOpen() {
this.display();
}
}

275
src/ui/EditModal.ts Normal file
View File

@@ -0,0 +1,275 @@
import {App, ButtonComponent, Modal, Setting} from "obsidian";
import {SettingModal} from "./settingModal";
import ObsidianSyncNotionPlugin from "../main";
import {DatabaseDetails, ObsidianSettingTab} from "./settingTabs";
import {i18nConfig} from "../lang/I18n";
import {CustomModal} from "./CustomModal";
export class EditModal extends SettingModal {
dataTemp: Record<string, any> = {
databaseFormatTemp: '',
// databaseFormatTempInd: false,
databaseFullNameTemp: '',
// databaseFullNameTempInd: false,
databaseAbbreviateNameTemp: '',
// databaseAbbreviateNameTempInd: false,
notionAPITemp: '',
// notionAPITempInd: false,
databaseIDTemp: '',
// databaseIDTempInd: false,
tagButtonTemp: false,
// tagButtonTempInd: false,
customTitleButtonTemp: false,
// customTitleButtonTempInd: false,
customTitleNameTemp: '',
customPropertiesTemp: [],
// customTitleNameTempInd: false,
// customValues: '',
savedTemp: false,
savedTempInd: false,
};
dataPrev: Record<string, any> = {
databaseFormatPrev: '',
// databaseFormatPrevInd: false,
databaseFullNamePrev: '',
// databaseFullNamePrevInd: false,
databaseAbbreviateNamePrev: '',
// databaseAbbreviateNamePrevInd: false,
notionAPIPrev: '',
// notionAPIPrevInd: false,
databaseIDPrev: '',
// databaseIDPrevInd: false,
tagButtonPrev: false,
// tagButtonPrevInd: false,
customTitleButtonPrev: false,
// customTitleButtonPrevInd: false,
customTitleNamePrev: '',
customPropertiesPrev: [],
// customTitleNamePrevInd: false,
// customValues: '',
savedPrev: false,
savedPrevInd: false,
};
plugin: ObsidianSyncNotionPlugin;
settingTab: ObsidianSettingTab;
dbDetails: DatabaseDetails;
constructor(app: App, plugin: ObsidianSyncNotionPlugin, settingTab: ObsidianSettingTab, dbDetails: DatabaseDetails) {
super(app, plugin, settingTab);
this.plugin = plugin;
this.settingTab = settingTab;
if (dbDetails) {
// Temp details
this.dataTemp.databaseFormatTemp = dbDetails.format;
this.dataTemp.databaseFullNameTemp = dbDetails.fullName;
this.dataTemp.databaseAbbreviateNameTemp = dbDetails.abName;
this.dataTemp.notionAPITemp = dbDetails.notionAPI;
this.dataTemp.databaseIDTemp = dbDetails.databaseID;
this.dataTemp.tagButtonTemp = dbDetails.tagButton;
this.dataTemp.customTitleButtonTemp = dbDetails.customTitleButton;
this.dataTemp.customTitleNameTemp = dbDetails.customTitleName;
this.dataTemp.customPropertiesTemp = dbDetails.customProperties;
// this.dataTemp.customValues = dbDetails.customValues;
this.dataTemp.savedTemp = dbDetails.saved;
// Prev details
this.dataPrev.databaseFormatPrev = dbDetails.format;
this.dataPrev.databaseFullNamePrev = dbDetails.fullName;
this.dataPrev.databaseAbbreviateNamePrev = dbDetails.abName;
this.dataPrev.notionAPIPrev = dbDetails.notionAPI;
this.dataPrev.databaseIDPrev = dbDetails.databaseID;
this.dataPrev.tagButtonPrev = dbDetails.tagButton;
this.dataPrev.customTitleButtonPrev = dbDetails.customTitleButton;
this.dataPrev.customTitleNamePrev = dbDetails.customTitleName;
this.dataPrev.customPropertiesPrev = dbDetails.customProperties;
// this.dataTemp.customValues = dbDetails.customValues;
this.dataPrev.savedPrev = dbDetails.saved;
}
}
display(): void {
this.containerEl.addClass("edit-modal");
this.titleEl.setText('Edit Database');
let {contentEl} = this;
contentEl.empty();
const editDiv = contentEl.createDiv('edit-div');
const nextTabs = contentEl.createDiv('next-tabs');
new Setting(editDiv)
.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.dataTemp.databaseFormatTemp)
.onChange(async (value) => {
this.dataTemp.databaseFormatTemp = value;
nextTabs.empty();
this.updateContentBasedOnSelection(value, nextTabs);
});
// Initialize content based on the current dropdown value
this.updateContentBasedOnSelection(this.dataTemp.databaseFormatTemp, nextTabs);
});
// add save button
let footerEl = contentEl.createDiv('save-button');
let saveButton = new Setting(footerEl)
saveButton.addButton((button: ButtonComponent) => {
return button
.setTooltip('Save')
.setIcon('checkmark')
.onClick(async () => {
this.dataTemp.savedTempInd = true;
this.dataTemp.savedTemp = true;
this.close();
});
}
);
saveButton.addExtraButton((button) => {
return button
.setTooltip('Cancel')
.setIcon('cross')
.onClick(() => {
this.dataTemp.savedTempInd = false;
this.close();
});
}
);
}
onOpen(): void {
this.display()
}
updateContentBasedOnSelection(value: string, nextTabs: HTMLElement): void {
// Clear existing content
nextTabs.empty();
// Generate content based on the selected value
if (value === 'general') {
nextTabs.createEl('h3', { text: i18nConfig.NotionGeneralSettingHeader });
// 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')
// tag button
this.createSettingEl(nextTabs, i18nConfig.NotionTagButton, i18nConfig.NotionTagButtonDesc, 'toggle', i18nConfig.NotionCustomTitleText, this.dataTemp.tagButtonTemp, 'dataTemp','tagButtonTemp')
// add custom title button
new Setting(nextTabs)
.setName(i18nConfig.NotionCustomTitle)
.setDesc(i18nConfig.NotionCustomTitleDesc)
.addToggle((toggle) =>
toggle
.setValue(this.dataTemp.customTitleButtonTemp)
.onChange(async (value) => {
this.dataTemp.customTitleButtonTemp = value;
this.updateSettingEl(CustomNameEl, value)
// this.updateSettingEl(CustomValuesEl, value)
// await this.plugin.saveSettings();
// await this.plugin.commands.updateCommand();
})
);
// add custom title name
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')
// 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 === 'next') {
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
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 new property button
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 = () => {
this.renderCustomPreview(customModal.properties, nextTabs)
this.dataTemp.customPropertiesTemp = customModal.properties;
}
customModal.open();
});
}
);
}
}
createStyleDiv(className: string, commandValue: boolean = false, parentEl: HTMLElement): HTMLDivElement {
return super.createStyleDiv(className, commandValue, parentEl);
}
updateSettingEl(element: HTMLElement, commandValue: boolean) {
super.updateSettingEl(element, commandValue);
}
createSettingEl(contentEl: HTMLElement, name: string, desc: string, type: string, placeholder: string, holderValue: any, dataRecord: string, settingsKey: string): Setting {
return super.createSettingEl(contentEl, name, desc, type, placeholder, holderValue, dataRecord, settingsKey);
}
}

View File

@@ -116,10 +116,24 @@ export class PreviewModal extends Modal {
dbIdSetting.settingEl.style.display = 'none'; // Hide initially dbIdSetting.settingEl.style.display = 'none'; // Hide initially
// Preview the custom properties
if (this.dbDetails.format === 'custom') {
const customPropertiesEl = new Setting(previewEl)
customPropertiesEl
.setName('Custom Properties')
.addTextArea(text => text
.setValue(JSON.stringify(this.dbDetails.customProperties, null, 2))
.setDisabled(true));
}
} }
onOpen() { onOpen() {
this.display() this.display()
} }
} }

View File

View File

@@ -1,116 +0,0 @@
import {App, PluginSettingTab, Setting} from "obsidian";
import ObsidianSyncNotionPlugin from "../main";
import {i18nConfig} from "../lang/I18n";
import {ObsidianSettingTab} from "./settingTabs";
export class SettingGeneralTabs extends PluginSettingTab {
plugin: ObsidianSyncNotionPlugin;
private settingTab: ObsidianSettingTab;
constructor(app: App, plugin: ObsidianSyncNotionPlugin, settingTab: ObsidianSettingTab) {
super(app, plugin);
this.plugin = plugin;
this.settingTab = settingTab;
}
display(): void {
// General Database Settings
this.settingTab.containerEl.createEl('h2', { text: i18nConfig.NotionGeneralSettingHeader });
// new Setting(containerEl)
// .setName(i18nConfig.NotYetFinish)
new Setting(this.settingTab.containerEl)
.setName(i18nConfig.NotionGeneralButton)
.setDesc(i18nConfig.NotionGeneralButtonDesc)
.addToggle((toggle) =>
toggle
.setValue(this.plugin.settings.GeneralButton)
.onChange(async (value) => {
this.plugin.settings.GeneralButton = value;
this.settingTab.updateSettingEl(tagButtonEl, value)
this.settingTab.updateSettingEl(CustomTitleEl, value)
// name should follow the result of the title button
if (value) {
this.settingTab.updateSettingEl(CustomNameEl, this.plugin.settings.CustomTitleButton)
this.settingTab.updateSettingEl(CustomValuesEl, this.plugin.settings.CustomTitleButton)
} else {
this.settingTab.updateSettingEl(CustomNameEl, value)
this.settingTab.updateSettingEl(CustomValuesEl, value)
}
this.settingTab.updateSettingEl(notionAPIGeneralEl, value)
this.settingTab.updateSettingEl(databaseIDGeneralEl, value)
await this.plugin.saveSettings();
await this.plugin.commands.updateCommand();
})
);
// add the tagButton to control whether to add tags to the general database
const tagButtonEl = this.settingTab.createStyleDiv('tag-button', (this.plugin.settings.GeneralButton && this.plugin.settings.CustomTitleButton));
this.settingTab.createSettingEl(tagButtonEl, i18nConfig.NotionTagButton, i18nConfig.NotionTagButtonDesc, 'toggle', i18nConfig.NotionCustomTitleText, this.plugin.settings.tagButton, 'tagButton')
// Custom Title Button
const CustomTitleEl = this.settingTab.createStyleDiv('custom-title', this.plugin.settings.GeneralButton);
new Setting(CustomTitleEl)
.setName(i18nConfig.NotionCustomTitle)
.setDesc(i18nConfig.NotionCustomTitleDesc)
.addToggle((toggle) =>
toggle
.setValue(this.plugin.settings.CustomTitleButton)
.onChange(async (value) => {
this.plugin.settings.CustomTitleButton = value;
this.settingTab.updateSettingEl(CustomNameEl, value)
this.settingTab.updateSettingEl(CustomValuesEl, value)
await this.plugin.saveSettings();
await this.plugin.commands.updateCommand();
})
);
// Custom Title Name
const CustomNameEl = this.settingTab.createStyleDiv('custom-name', (this.plugin.settings.CustomTitleButton && this.plugin.settings.GeneralButton));
this.settingTab.createSettingEl(CustomNameEl, i18nConfig.NotionCustomTitleName, i18nConfig.NotionCustomTitleNameDesc, 'text', i18nConfig.NotionCustomTitleText, this.plugin.settings.CustomTitleName, 'CustomTitleName')
// Custom database properties
const CustomValuesEl = this.settingTab.createStyleDiv('custom-values', (this.plugin.settings.CustomTitleButton && this.plugin.settings.GeneralButton));
new Setting(CustomValuesEl)
.setName(i18nConfig.NotionCustomValues)
.setDesc(i18nConfig.NotionCustomValuesDesc)
.addTextArea((text) =>
text
.setPlaceholder(i18nConfig.NotionCustomValuesText)
.setValue(this.plugin.settings.CustomValues)
.onChange(async (value) => {
this.plugin.settings.CustomValues = value;
await this.plugin.saveSettings();
await this.plugin.commands.updateCommand();
})
);
// new Setting(containerEl)
// .setName("Convert tags(optional)")
// .setDesc("Transfer the Obsidian tags to the Notion table. It requires the column with the name 'Tags'")
// .addToggle((toggle) =>
// toggle
// .setValue(this.plugin.settings.allowTags)
// .onChange(async (value) => {
// this.plugin.settings.allowTags = value;
// await this.plugin.saveSettings();
// })
// );
const notionAPIGeneralEl = this.settingTab.createStyleDiv('api-general', this.plugin.settings.GeneralButton);
this.settingTab.createSettingEl(notionAPIGeneralEl, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.plugin.settings.notionAPIGeneral, 'notionAPIGeneral')
const databaseIDGeneralEl = this.settingTab.createStyleDiv('databaseID-general', this.plugin.settings.GeneralButton);
this.settingTab.createSettingEl(databaseIDGeneralEl, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.plugin.settings.databaseIDGeneral, 'databaseIDGeneral')
}
}

View File

@@ -5,14 +5,14 @@ import {
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 {SettingNextTabs} from "./settingNextTabs"; import {CustomModal} from "./CustomModal";
import {SettingGeneralTabs} from "./settingGeneralTabs";
export class SettingModal extends Modal { export class SettingModal extends Modal {
[key: string]: any; // Index signature
data: Record<string, any> = { data: Record<string, any> = {
databaseFormat: 'none', databaseFormat: 'none',
databaseFullName: '', databaseFullName: '',
@@ -22,6 +22,7 @@ export class SettingModal extends Modal {
tagButton: true, tagButton: true,
customTitleButton: false, customTitleButton: false,
customTitleName: '', customTitleName: '',
customProperties: [],
// customValues: '', // customValues: '',
saved: false, saved: false,
}; };
@@ -32,6 +33,7 @@ export class SettingModal extends Modal {
super(app); super(app);
this.plugin = plugin; this.plugin = plugin;
this.settingTab = settingTab; this.settingTab = settingTab;
this.properties = [];
if (dbDetails) { if (dbDetails) {
this.data.databaseFormat = dbDetails.format; this.data.databaseFormat = dbDetails.format;
this.data.databaseFullName = dbDetails.fullName; this.data.databaseFullName = dbDetails.fullName;
@@ -41,6 +43,7 @@ export class SettingModal extends Modal {
this.data.tagButton = dbDetails.tagButton; this.data.tagButton = dbDetails.tagButton;
this.data.customTitleButton = dbDetails.customTitleButton; this.data.customTitleButton = dbDetails.customTitleButton;
this.data.customTitleName = dbDetails.customTitleName; this.data.customTitleName = dbDetails.customTitleName;
this.data.customProperties = dbDetails.customProperties;
// this.data.customValues = dbDetails.customValues; // this.data.customValues = dbDetails.customValues;
this.data.saved = dbDetails.saved; this.data.saved = dbDetails.saved;
} }
@@ -52,14 +55,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) { if (this.data.saved) {
new Setting(settingDiv) new Setting(settingDiv)
.setName(i18nConfig.databaseFormat) .setName(i18nConfig.databaseFormat)
@@ -69,7 +71,7 @@ export class SettingModal extends Modal {
.addOption('none', '') .addOption('none', '')
.addOption('general', i18nConfig.databaseGeneral) .addOption('general', i18nConfig.databaseGeneral)
.addOption('next', i18nConfig.databaseNext) .addOption('next', i18nConfig.databaseNext)
// .addOption('custom', i18nConfig.databaseCustom) .addOption('custom', i18nConfig.databaseCustom)
.setValue(this.data.databaseFormat) .setValue(this.data.databaseFormat)
.onChange(async (value) => { .onChange(async (value) => {
this.data.databaseFormat = value; this.data.databaseFormat = value;
@@ -90,7 +92,7 @@ export class SettingModal extends Modal {
.addOption('none', '') .addOption('none', '')
.addOption('general', i18nConfig.databaseGeneral) .addOption('general', i18nConfig.databaseGeneral)
.addOption('next', i18nConfig.databaseNext) .addOption('next', i18nConfig.databaseNext)
// .addOption('custom', i18nConfig.databaseCustom) .addOption('custom', i18nConfig.databaseCustom)
.setValue(this.data.databaseFormat) .setValue(this.data.databaseFormat)
.onChange(async (value) => { .onChange(async (value) => {
this.data.databaseFormat = value; this.data.databaseFormat = value;
@@ -104,29 +106,28 @@ export class SettingModal extends Modal {
} }
// add save button // add save button
let footerEl = contentEl.createDiv('save-button'); let footerEl = contentEl.createDiv('save-button');
let saveButton = new Setting(footerEl) let saveButton = new Setting(footerEl)
saveButton.addButton((button: ButtonComponent) => { saveButton.addButton((button: ButtonComponent) => {
return button return button
.setTooltip('Save') .setTooltip('Save')
.setIcon('checkmark') .setIcon('checkmark')
.onClick(async () => { .onClick(async () => {
this.data.saved = true; this.data.saved = true;
this.close(); this.close();
}); });
} }
); );
saveButton.addExtraButton((button) => { saveButton.addExtraButton((button) => {
return button return button
.setTooltip('Cancel') .setTooltip('Cancel')
.setIcon('cross') .setIcon('cross')
.onClick(() => { .onClick(() => {
this.data.saved = false; this.data.saved = false;
this.close(); this.close();
}); });
} }
); );
} }
@@ -136,16 +137,16 @@ 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, 'databaseFullName') this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.data.databaseFullName, 'data', 'databaseFullName')
// add abbreviate name // add abbreviate name
this.createSettingEl(nextTabs, i18nConfig.databaseAbbreviateName, i18nConfig.databaseAbbreviateNameDesc, 'text', i18nConfig.databaseAbbreviateNameText, this.data.databaseAbbreviateName, 'databaseAbbreviateName') this.createSettingEl(nextTabs, i18nConfig.databaseAbbreviateName, i18nConfig.databaseAbbreviateNameDesc, 'text', i18nConfig.databaseAbbreviateNameText, this.data.databaseAbbreviateName, 'data', 'databaseAbbreviateName')
// tag button // tag button
this.createSettingEl(nextTabs, i18nConfig.NotionTagButton, i18nConfig.NotionTagButtonDesc, 'toggle', i18nConfig.NotionCustomTitleText, this.data.tagButton, 'tagButton') this.createSettingEl(nextTabs, i18nConfig.NotionTagButton, i18nConfig.NotionTagButtonDesc, 'toggle', i18nConfig.NotionCustomTitleText, this.data.tagButton, 'data', 'tagButton')
// add custom title button // add custom title button
@@ -154,128 +155,114 @@ export class SettingModal extends Modal {
.setDesc(i18nConfig.NotionCustomTitleDesc) .setDesc(i18nConfig.NotionCustomTitleDesc)
.addToggle((toggle) => .addToggle((toggle) =>
toggle toggle
.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) // this.updateSettingEl(CustomValuesEl, value)
await this.plugin.saveSettings(); // await this.plugin.saveSettings();
await this.plugin.commands.updateCommand(); // await this.plugin.commands.updateCommand();
}) })
); );
// add custom title name // add custom title name
const CustomNameEl = this.createStyleDiv('custom-name', (this.data.CustomTitleButton), nextTabs); const CustomNameEl = this.createStyleDiv('custom-name', (this.data.customTitleButton), nextTabs);
this.createSettingEl(CustomNameEl, i18nConfig.NotionCustomTitleName, i18nConfig.NotionCustomTitleNameDesc, 'text', i18nConfig.NotionCustomTitleText, this.data.CustomTitleName, 'CustomTitleName') this.createSettingEl(CustomNameEl, i18nConfig.NotionCustomTitleName, i18nConfig.NotionCustomTitleNameDesc, 'text', i18nConfig.NotionCustomTitleText, this.data.customTitleName, 'data', 'customTitleName')
// add api key // add api key
this.createSettingEl(nextTabs, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.data.notionAPI, 'notionAPI') this.createSettingEl(nextTabs, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.data.notionAPI, 'data', 'notionAPI')
// add database id // add database id
this.createSettingEl(nextTabs, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.data.databaseID, 'databaseID') this.createSettingEl(nextTabs, i18nConfig.DatabaseID, i18nConfig.DatabaseIDDesc, 'password', i18nConfig.DatabaseIDText, this.data.databaseID, 'data', 'databaseID')
} 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, 'databaseFullName') this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.data.databaseFullName, 'data', 'databaseFullName')
// add abbreviate name // add abbreviate name
this.createSettingEl(nextTabs, i18nConfig.databaseAbbreviateName, i18nConfig.databaseAbbreviateNameDesc, 'text', i18nConfig.databaseAbbreviateNameText, this.data.databaseAbbreviateName, 'databaseAbbreviateName') this.createSettingEl(nextTabs, i18nConfig.databaseAbbreviateName, i18nConfig.databaseAbbreviateNameDesc, 'text', i18nConfig.databaseAbbreviateNameText, this.data.databaseAbbreviateName, 'data', 'databaseAbbreviateName')
// add api key // add api key
this.createSettingEl(nextTabs, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.data.notionAPI, 'notionAPI') this.createSettingEl(nextTabs, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.data.notionAPI, 'data', 'notionAPI')
// add database id // add database id
this.createSettingEl(nextTabs, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.data.databaseID, 'databaseID') this.createSettingEl(nextTabs, i18nConfig.DatabaseID, i18nConfig.DatabaseIDDesc, 'password', i18nConfig.DatabaseIDText, this.data.databaseID, 'data', 'databaseID')
} 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, 'databaseFullName') this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.data.databaseFullName, 'data', 'databaseFullName')
// add abbreviate name // add abbreviate name
this.createSettingEl(nextTabs, i18nConfig.databaseAbbreviateName, i18nConfig.databaseAbbreviateNameDesc, 'text', i18nConfig.databaseAbbreviateNameText, this.data.databaseAbbreviateName, 'databaseAbbreviateName') this.createSettingEl(nextTabs, i18nConfig.databaseAbbreviateName, i18nConfig.databaseAbbreviateNameDesc, 'text', i18nConfig.databaseAbbreviateNameText, this.data.databaseAbbreviateName, 'data', 'databaseAbbreviateName')
// tag button
this.createSettingEl(nextTabs, i18nConfig.NotionTagButton, i18nConfig.NotionTagButtonDesc, 'toggle', i18nConfig.NotionCustomTitleText, this.data.tagButton, 'tagButton')
// add custom title button
new Setting(nextTabs)
.setName(i18nConfig.NotionCustomTitle)
.setDesc(i18nConfig.NotionCustomTitleDesc)
.addToggle((toggle) =>
toggle
.setValue(this.data.CustomTitleButton)
.onChange(async (value) => {
this.data.CustomTitleButton = value;
this.updateSettingEl(CustomNameEl, value)
// this.updateSettingEl(CustomValuesEl, value)
await this.plugin.saveSettings();
await this.plugin.commands.updateCommand();
})
);
// add custom title name
const CustomNameEl = this.createStyleDiv('custom-name', (this.data.CustomTitleButton), nextTabs);
this.createSettingEl(CustomNameEl, i18nConfig.NotionCustomTitleName, i18nConfig.NotionCustomTitleNameDesc, 'text', i18nConfig.NotionCustomTitleText, this.data.CustomTitleName, 'CustomTitleName')
// // add custom values
// const CustomValuesEl = this.createStyleDiv('custom-values', (this.data.CustomTitleButton), nextTabs);
// new Setting(CustomValuesEl)
// .setName(i18nConfig.NotionCustomValues)
// .setDesc(i18nConfig.NotionCustomValuesDesc)
// .addTextArea((text) => {
// return text
// .setPlaceholder(i18nConfig.NotionCustomValuesText)
// .setValue(this.data.CustomValues)
// .onChange(async (value) => {
// this.data.CustomValues = value;
// await this.plugin.saveSettings();
// });
// });
// add api key // add api key
const notionAPIGeneralEl = this.createStyleDiv('api-general', this.plugin.settings.GeneralButton, nextTabs); this.createSettingEl(nextTabs, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.data.notionAPI, 'data', 'notionAPI')
this.createSettingEl(notionAPIGeneralEl, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.data.notionAPI, 'notionAPI')
// add database id // add database id
const databaseIDGeneralEl = this.createStyleDiv('databaseID-general', this.plugin.settings.GeneralButton, nextTabs); this.createSettingEl(nextTabs, i18nConfig.DatabaseID, i18nConfig.DatabaseIDDesc, 'password', i18nConfig.DatabaseIDText, this.data.databaseID, 'data', 'databaseID')
this.createSettingEl(databaseIDGeneralEl, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.data.databaseID, 'databaseID')
// add new property button
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 = () => {
this.renderCustomPreview(customModal.properties, nextTabs)
this.data.customProperties = customModal.properties;
}
customModal.open();
});
}
);
} }
} }
onOpen() { onOpen() {
// add console log to check if the modal is opened // add console log to check if the modal is opened
this.display() this.display()
} }
renderCustomPreview(properties: any[], nextTabs: HTMLElement) {
const previewContainer = nextTabs.createDiv('preview-container');
properties.forEach((property: { customName: any; customType: any; }) => {
const propertyEl = previewContainer.createEl('div', {cls: 'property-preview'});
propertyEl.createEl('span', {text: `Property: ${property.customName}, Type: ${property.customType}`});
});
}
// 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) {
return parentEl.createDiv(className, (div) => { return parentEl.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";
@@ -285,7 +272,7 @@ export class SettingModal extends Modal {
} }
// function to add one setting element in the setting tab. // function to add one setting element in the setting tab.
public createSettingEl(contentEl: HTMLElement, name: string, desc: string, type: string, placeholder: string, holderValue: any,settingsKey: string) { public createSettingEl(contentEl: HTMLElement, name: string, desc: string, type: string, placeholder: string, holderValue: any, dataRecord: string, settingsKey: string) {
if (type === 'password') { if (type === 'password') {
return new Setting(contentEl) return new Setting(contentEl)
.setName(name) .setName(name)
@@ -296,7 +283,7 @@ export class SettingModal extends Modal {
.setPlaceholder(placeholder) .setPlaceholder(placeholder)
.setValue(holderValue) .setValue(holderValue)
.onChange(async (value) => { .onChange(async (value) => {
this.data[settingsKey] = value; // Update the settings dictionary await this.plugin.saveSettings(); this[dataRecord][settingsKey] = value; // Update the settings dictionary await this.plugin.saveSettings();
}) })
}); });
} else if (type === 'toggle') { } else if (type === 'toggle') {
@@ -307,7 +294,7 @@ export class SettingModal extends Modal {
toggle toggle
.setValue(holderValue) .setValue(holderValue)
.onChange(async (value) => { .onChange(async (value) => {
this.data[settingsKey] = value; // Update the settings dictionary await this.plugin.saveSettings(); this[dataRecord][settingsKey] = value; // Update the settings dictionary await this.plugin.saveSettings();
}) })
); );
} else if (type === 'text') { } else if (type === 'text') {
@@ -319,7 +306,7 @@ export class SettingModal extends Modal {
.setPlaceholder(placeholder) .setPlaceholder(placeholder)
.setValue(holderValue) .setValue(holderValue)
.onChange(async (value) => { .onChange(async (value) => {
this.data[settingsKey] = value; // Update the settings dictionary await this.plugin.saveSettings(); this[dataRecord][settingsKey] = value; // Update the settings dictionary await this.plugin.saveSettings();
}) })
); );
} }

View File

@@ -1,49 +0,0 @@
import {App, PluginSettingTab, Setting} from "obsidian";
import ObsidianSyncNotionPlugin from "../main";
import {i18nConfig} from "../lang/I18n";
import {ObsidianSettingTab} from "./settingTabs";
import {SettingModal} from "./settingModal";
export class SettingNextTabs extends PluginSettingTab {
plugin: ObsidianSyncNotionPlugin;
settingModal: SettingModal;
constructor(app: App, plugin: ObsidianSyncNotionPlugin, settingTab: ObsidianSettingTab) {
super(app, plugin);
this.plugin = plugin;
}
display(): void {
// notion next database settings
this.containerEl.createEl('h2', { text: i18nConfig.NotionNextSettingHeader });
const NextButtonEl = this.containerEl.createDiv();
new Setting(NextButtonEl)
.setName(i18nConfig.NotionNextButton)
.setDesc(i18nConfig.NotionNextButtonDesc)
.addToggle((toggle) =>
toggle
.setValue(this.plugin.settings.NextButton)
.onChange(async (value) => {
this.plugin.settings.NextButton = value;
this.settingModal.updateSettingEl(notionAPINextEl, value)
this.settingModal.updateSettingEl(databaseIDNextEl, value)
await this.plugin.saveSettings();
await this.plugin.commands.updateCommand();
})
);
const notionAPINextEl = this.settingModal.createStyleDiv('api-next', this.plugin.settings.NextButton,NextButtonEl)
this.settingModal.createSettingEl(notionAPINextEl, i18nConfig.NotionAPI, i18nConfig.NotionAPIDesc, 'password', i18nConfig.NotionAPIText, this.plugin.settings.notionAPINext,'notionAPINext')
const databaseIDNextEl = this.settingModal.createStyleDiv('databaseID-next', this.plugin.settings.NextButton,NextButtonEl)
this.settingModal.createSettingEl(databaseIDNextEl, i18nConfig.DatabaseID, i18nConfig.NotionAPIDesc, 'password', i18nConfig.DatabaseIDText, this.plugin.settings.databaseIDNext,'databaseIDNext')
}
}

View File

@@ -1,11 +1,11 @@
import {App, ButtonComponent, PluginSettingTab, Setting} from "obsidian"; import {App, ButtonComponent, Modal, 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 {SettingNextTabs} from "./settingNextTabs";
import {SettingGeneralTabs} from "./settingGeneralTabs";
import {set} from "yaml/dist/schema/yaml-1.1/set"; import {set} from "yaml/dist/schema/yaml-1.1/set";
import {PreviewModal} from "./PreviewModal"; import {PreviewModal} from "./PreviewModal";
import {EditModal} from "./EditModal";
import {DeleteModal} from "./DeleteModal";
export interface PluginSettings { export interface PluginSettings {
NextButton: boolean; NextButton: boolean;
@@ -16,8 +16,8 @@ export interface PluginSettings {
proxy: string; proxy: string;
GeneralButton: boolean; GeneralButton: boolean;
tagButton: boolean; tagButton: boolean;
CustomTitleButton: boolean; customTitleButton: boolean;
CustomTitleName: string; customTitleName: string;
notionAPIGeneral: string; notionAPIGeneral: string;
databaseIDGeneral: string; databaseIDGeneral: string;
CustomButton: boolean; CustomButton: boolean;
@@ -37,6 +37,7 @@ export interface DatabaseDetails {
tagButton: boolean; tagButton: boolean;
customTitleButton: boolean; customTitleButton: boolean;
customTitleName: string; customTitleName: string;
customProperties:{ customName: string, customType: string }[];
// customValues: string; // customValues: string;
saved: boolean; saved: boolean;
} }
@@ -50,8 +51,8 @@ export const DEFAULT_SETTINGS: PluginSettings = {
proxy: "", proxy: "",
GeneralButton: true, GeneralButton: true,
tagButton: true, tagButton: true,
CustomTitleButton: false, customTitleButton: false,
CustomTitleName: "", customTitleName: "",
notionAPIGeneral: "", notionAPIGeneral: "",
databaseIDGeneral: "", databaseIDGeneral: "",
CustomButton: false, CustomButton: false,
@@ -107,6 +108,7 @@ export class ObsidianSettingTab extends PluginSettingTab {
tagButton: modal.data.tagButton, tagButton: modal.data.tagButton,
customTitleButton: modal.data.customTitleButton, customTitleButton: modal.data.customTitleButton,
customTitleName: modal.data.customTitleName, customTitleName: modal.data.customTitleName,
customProperties: modal.data.customProperties,
// customValues: modal.data.customValues, // customValues: modal.data.customValues,
saved: modal.data.saved, saved: modal.data.saved,
} }
@@ -251,30 +253,47 @@ export class ObsidianSettingTab extends PluginSettingTab {
}); });
}); });
// add a button for edit data
settingEl settingEl
.addButton((button: ButtonComponent): ButtonComponent => { .addButton((button: ButtonComponent): ButtonComponent => {
return button return button
.setTooltip("Edit Database") .setTooltip("Edit Database")
.setIcon("pencil") .setIcon("pencil")
.onClick(async () => { .onClick(async () => {
let modal = new SettingModal(this.app, this.plugin, this, dbDetails); let modal = new EditModal(this.app, this.plugin, this, dbDetails);
modal.onClose = () => { modal.onClose = () => {
if (modal.data.saved) { if (modal.dataTemp.savedTempInd) {
const dbDetails = { const dbDetailsNew: DatabaseDetails = {
format: modal.data.databaseFormat, format: modal.dataTemp.databaseFormatTemp,
fullName: modal.data.databaseFullName, fullName: modal.dataTemp.databaseFullNameTemp,
abName: modal.data.databaseAbbreviateName, abName: modal.dataTemp.databaseAbbreviateNameTemp,
notionAPI: modal.data.notionAPI, notionAPI: modal.dataTemp.notionAPITemp,
databaseID: modal.data.databaseID, databaseID: modal.dataTemp.databaseIDTemp,
tagButton: modal.data.tagButton, tagButton: modal.dataTemp.tagButtonTemp,
customTitleButton: modal.data.customTitleButton, customTitleButton: modal.dataTemp.customTitleButtonTemp,
customTitleName: modal.data.customTitleName, customTitleName: modal.dataTemp.customTitleNameTemp,
customProperties: modal.dataTemp.customPropertiesTemp,
// customValues: modal.data.customValues, // customValues: modal.data.customValues,
saved: modal.data.saved, saved: modal.dataTemp.savedTemp,
} }
this.plugin.updateDatabaseDetails(dbDetails); const dbDetailsPrev: DatabaseDetails = {
format: modal.dataPrev.databaseFormatPrev,
fullName: modal.dataPrev.databaseFullNamePrev,
abName: modal.dataPrev.databaseAbbreviateNamePrev,
notionAPI: modal.dataPrev.notionAPIPrev,
databaseID: modal.dataPrev.databaseIDPrev,
tagButton: modal.dataPrev.tagButtonPrev,
customTitleButton: modal.dataPrev.customTitleButtonPrev,
customTitleName: modal.dataPrev.customTitleNamePrev,
customProperties: modal.dataPrev.customPropertiesPrev,
// customValues: modal.data.customValues,
saved: modal.dataPrev.savedPrev,
}
this.plugin.deleteDatabaseDetails(dbDetailsPrev);
this.plugin.updateDatabaseDetails(dbDetailsNew);
this.plugin.commands.updateCommand(); this.plugin.commands.updateCommand();
@@ -292,11 +311,20 @@ export class ObsidianSettingTab extends PluginSettingTab {
.setTooltip("Delete Database") .setTooltip("Delete Database")
.setIcon("trash") .setIcon("trash")
.onClick(async () => { .onClick(async () => {
await this.plugin.deleteDatabaseDetails(dbDetails); let modal = new DeleteModal(this.app, this.plugin, this, dbDetails);
await this.plugin.commands.updateCommand(); modal.onClose = () => {
if (modal.data.deleted) {
this.plugin.deleteDatabaseDetails(dbDetails);
this.plugin.commands.updateCommand();
this.display()
}
}
modal.open();
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, PluginSettings} from "../ui/settingTabs"; import {DatabaseDetails} from "../ui/settingTabs";
export async function updateYamlInfo( export async function updateYamlInfo(
yamlContent: string, yamlContent: string,

View File

@@ -1,118 +1,131 @@
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,
settings: PluginSettings, settings: PluginSettings,
dbDetails: DatabaseDetails, dbDetails: DatabaseDetails,
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) {
// const NNonmessage = i18nConfig.NNonMissing; // const NNonmessage = i18nConfig.NNonMissing;
// new Notice(NNonmessage); // new Notice(NNonmessage);
// return; // return;
// } // }
// 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 === "") {
const setAPIMessage = i18nConfig["set-api-id"]; const setAPIMessage = i18nConfig["set-api-id"];
new Notice(setAPIMessage); new Notice(setAPIMessage);
return; return;
} }
const { markDownData, nowFile, emoji, cover, tags, type, slug, stats, category, summary, paword, favicon, datetime } = await getNowFileMarkdownContentNext(app, settings) const {
markDownData,
nowFile,
emoji,
cover,
tags,
type,
slug,
stats,
category,
summary,
paword,
favicon,
datetime
} = 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);
if (res.status === 200) { if (res.status === 200) {
new Notice(`${i18nConfig["sync-success"]}${basename}`); new Notice(`${i18nConfig["sync-success"]}${basename}`);
} else { } else {
new Notice(`${i18nConfig["sync-fail"]}${basename}`, 5000); new Notice(`${i18nConfig["sync-fail"]}${basename}`, 5000);
} }
} }
} }
export async function uploadCommandGeneral( export async function uploadCommandGeneral(
plugin: ObsidianSyncNotionPlugin, plugin: ObsidianSyncNotionPlugin,
settings: PluginSettings, settings: PluginSettings,
dbDetails: DatabaseDetails, dbDetails: DatabaseDetails,
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 === "") {
const setAPIMessage = i18nConfig["set-api-id"]; const setAPIMessage = i18nConfig["set-api-id"];
new Notice(setAPIMessage); new Notice(setAPIMessage);
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);
if (res.status === 200) { if (res.status === 200) {
new Notice(`${i18nConfig["sync-success"]}${basename}`); new Notice(`${i18nConfig["sync-success"]}${basename}`);
} else { } else {
new Notice(`${i18nConfig["sync-fail"]}${basename}`, 5000); new Notice(`${i18nConfig["sync-fail"]}${basename}`, 5000);
} }
} }
} }
export async function uploadCommandCustom( export async function uploadCommandCustom(
plugin: ObsidianSyncNotionPlugin, plugin: ObsidianSyncNotionPlugin,
settings: PluginSettings, settings: PluginSettings,
dbDetails: DatabaseDetails, dbDetails: DatabaseDetails,
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 === "") {
const setAPIMessage = i18nConfig["set-api-id"]; const setAPIMessage = i18nConfig["set-api-id"];
new Notice(setAPIMessage); new Notice(setAPIMessage);
return; return;
} }
const { markDownData, nowFile, cover, tags ,customValues} = await getNowFileMarkdownContentCustom(app, settings) 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(basename, cover, tags, customValues, markDownData, nowFile, this.app); const res = await upload.syncMarkdownToNotionCustom(cover, customValues, markDownData, nowFile, this.app);
if (res.status === 200) { if (res.status === 200) {
new Notice(`${i18nConfig["sync-success"]}${basename}`); new Notice(`${i18nConfig["sync-success"]}${basename}`);
} else { } else {
new Notice(`${i18nConfig["sync-fail"]}${basename}`, 5000); new Notice(`${i18nConfig["sync-fail"]}${basename}`, 5000);
} }
} }
} }

View File

@@ -7,89 +7,90 @@ 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;
notion: Client; notion: Client;
agent: any; agent: any;
dbDetails: DatabaseDetails dbDetails: DatabaseDetails
constructor(plugin: MyPlugin, dbDetails: DatabaseDetails) {
this.plugin = plugin; constructor(plugin: MyPlugin, dbDetails: DatabaseDetails) {
this.plugin = plugin;
this.dbDetails = dbDetails this.dbDetails = dbDetails
} }
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',
headers: { headers: {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
'Authorization': 'Bearer ' + notionAPI, 'Authorization': 'Bearer ' + notionAPI,
'Notion-Version': '2022-06-28', 'Notion-Version': '2022-06-28',
}, },
body: '' body: ''
}); });
} }
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',
headers: { headers: {
'Authorization': 'Bearer ' + notionAPI, 'Authorization': 'Bearer ' + notionAPI,
'Notion-Version': '2022-06-28', 'Notion-Version': '2022-06-28',
} }
} }
) )
// Check if cover is present in the JSON response and then get the URL // Check if cover is present in the JSON response and then get the URL
if (response.json.cover && response.json.cover.external) { if (response.json.cover && response.json.cover.external) {
return response.json.cover.external.url; return response.json.cover.external.url;
} else { } else {
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) { // async updateYamlInfo(yamlContent: string, nowFile: TFile, res: any, app: App, settings: any) {
// let {url, id} = res.json // let {url, id} = res.json
// // replace www to notionID // // replace www to notionID
// const {notionUser} = this.plugin.settings; // const {notionUser} = this.plugin.settings;
// //
// if (notionUser !== "") { // if (notionUser !== "") {
// // replace url str "www" to notionID // // replace url str "www" to notionID
// url = url.replace("www.notion.so", `${notionUser}.notion.site`) // url = url.replace("www.notion.so", `${notionUser}.notion.site`)
// } // }
// //
// await app.fileManager.processFrontMatter(nowFile, yamlContent => { // await app.fileManager.processFrontMatter(nowFile, yamlContent => {
// if (yamlContent['notionID']) { // if (yamlContent['notionID']) {
// delete yamlContent['notionID'] // delete yamlContent['notionID']
// } // }
// if (yamlContent['link']) { // if (yamlContent['link']) {
// delete yamlContent['link'] // delete yamlContent['link']
// } // }
// // add new notionID and link // // add new notionID and link
// yamlContent.notionID = id; // yamlContent.notionID = id;
// yamlContent.link = url; // yamlContent.link = url;
// }); // });
// //
// try { // try {
// await navigator.clipboard.writeText(url) // await navigator.clipboard.writeText(url)
// } catch (error) { // } catch (error) {
// new Notice(`复制链接失败,请手动复制${error}`) // new Notice(`复制链接失败,请手动复制${error}`)
// } // }
// // const __content = yamlContent.__content; // // const __content = yamlContent.__content;
// // delete yamlContent.__content // // delete yamlContent.__content
// // const yamlhead = yaml.stringify(yamlContent) // // const yamlhead = yaml.stringify(yamlContent)
// // // if yamlhead hava last \n remove it // // // if yamlhead hava last \n remove it
// // const yamlhead_remove_n = yamlhead.replace(/\n$/, '') // // const yamlhead_remove_n = yamlhead.replace(/\n$/, '')
// // // if __content have start \n remove it // // // if __content have start \n remove it
// // const __content_remove_n = __content.replace(/^\n/, '') // // const __content_remove_n = __content.replace(/^\n/, '')
// // const content = '---\n' +yamlhead_remove_n +'\n---\n' + __content_remove_n; // // const content = '---\n' +yamlhead_remove_n +'\n---\n' + __content_remove_n;
// // try { // // try {
// // await nowFile.vault.modify(nowFile, content) // // await nowFile.vault.modify(nowFile, content)
// // } catch (error) { // // } catch (error) {
// // new Notice(`write file error ${error}`) // // new Notice(`write file error ${error}`)
// // } // // }
// } // }
} }

View File

@@ -139,7 +139,7 @@ export class Upload2NotionGeneral extends UploadBaseGeneral {
const frontmasster = const frontmasster =
app.metadataCache.getFileCache(nowFile)?.frontmatter; app.metadataCache.getFileCache(nowFile)?.frontmatter;
const {abName} = this.dbDetails const {abName} = this.dbDetails
const notionIDKey = `${abName}-NotionID`; const notionIDKey = `NotionID-${abName}`;
const notionID = frontmasster ? frontmasster[notionIDKey] : null; const notionID = frontmasster ? frontmasster[notionIDKey] : null;

View File

@@ -3,31 +3,31 @@ 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,
settings: PluginSettings, settings: PluginSettings,
) { ) {
const nowFile = app.workspace.getActiveFile(); const nowFile = app.workspace.getActiveFile();
let cover = ''; let cover = '';
let tags = []; let tags = [];
const FileCache = app.metadataCache.getFileCache(nowFile); const FileCache = app.metadataCache.getFileCache(nowFile);
try { try {
cover = FileCache.frontmatter.coverurl; cover = FileCache.frontmatter.coverurl;
tags = FileCache.frontmatter.tags; tags = FileCache.frontmatter.tags;
} catch (error) { } catch (error) {
new Notice(i18nConfig["set-tags-fail"]); new Notice(i18nConfig["set-tags-fail"]);
} }
if (nowFile) { if (nowFile) {
const markDownData = await nowFile.vault.read(nowFile); const markDownData = await nowFile.vault.read(nowFile);
return { return {
markDownData, markDownData,
nowFile, nowFile,
cover, cover,
tags, tags,
}; };
} else { } else {
new Notice(i18nConfig["open-file"]); new Notice(i18nConfig["open-file"]);
return; return;
} }
} }

View File

@@ -228,7 +228,7 @@ export class Upload2NotionNext extends UploadBaseNext {
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 = `${abName}-NotionID`; const notionIDKey = `NotionID-${abName}`;
const notionID = frontmasster ? frontmasster[notionIDKey] : null; const notionID = frontmasster ? frontmasster[notionIDKey] : null;

View File

@@ -1,11 +1,10 @@
import { App, Notice, requestUrl, TFile } from "obsidian"; import {App, Notice, requestUrl, TFile} from "obsidian";
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, 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 {
@@ -21,15 +20,13 @@ export class Upload2NotionCustom extends UploadBaseCustom {
// 暂时就直接删除新建一个page // 暂时就直接删除新建一个page
async updatePage( async updatePage(
notionID: string, notionID: string,
title: string,
cover: string, cover: string,
tags: string[],
customValues: Record<string, string>, customValues: Record<string, string>,
childArr: any, childArr: any,
) { ) {
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
@@ -39,56 +36,22 @@ export class Upload2NotionCustom extends UploadBaseCustom {
cover = databaseCover; cover = databaseCover;
} }
return await this.createPage(title, cover, tags, customValues, childArr); return await this.createPage(cover, customValues, childArr);
} }
async createPage( async createPage(
title: string,
cover: string, cover: string,
tags: string[],
customValues: Record<string, string>, customValues: Record<string, string>,
childArr: any, childArr: any,
) { ) {
const { const {
databaseID, databaseID,
customTitleButton, customProperties,
customTitleName,
tagButton,
notionAPI notionAPI
} = this.dbDetails; } = this.dbDetails;
const bodyString: any = { const bodyString: any = this.buildBodyString(customProperties, customValues, childArr);
parent: {
database_id: databaseID,
},
properties: {
[customTitleButton
? customTitleName
: "title"]: {
title: [
{
text: {
content: title,
},
},
],
},
...(Object.keys(customValues).reduce((acc, key) => {
acc[key] = {
rich_text: [
{
text: {
content: customValues[key] || '',
},
},
],
};
return acc;
}, {} as Record<string, { rich_text: { text: { content: string } }[] } >)),
},
children: childArr,
};
if (cover) { if (cover) {
bodyString.cover = { bodyString.cover = {
@@ -127,9 +90,7 @@ export class Upload2NotionCustom extends UploadBaseCustom {
} }
async syncMarkdownToNotionCustom( async syncMarkdownToNotionCustom(
title: string,
cover: string, cover: string,
tags: string[],
customValues: Record<string, string>, customValues: Record<string, string>,
markdown: string, markdown: string,
nowFile: TFile, nowFile: TFile,
@@ -146,19 +107,19 @@ 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 notionID = frontmasster ? frontmasster.notionID : null; const {abName} = this.dbDetails
const notionIDKey = `NotionID-${abName}`;
const notionID = frontmasster ? frontmasster[notionIDKey] : null;
if (notionID) { if (notionID) {
res = await this.updatePage( res = await this.updatePage(
notionID, notionID,
title,
cover, cover,
tags,
customValues, customValues,
file2Block, file2Block,
); );
} else { } else {
res = await this.createPage(title, cover, tags, customValues, file2Block); res = await this.createPage(cover, customValues, file2Block);
} }
if (res.status === 200) { if (res.status === 200) {
await updateYamlInfo(markdown, nowFile, res, app, this.plugin, this.dbDetails); await updateYamlInfo(markdown, nowFile, res, app, this.plugin, this.dbDetails);
@@ -167,4 +128,110 @@ export class Upload2NotionCustom extends UploadBaseCustom {
} }
return res; return res;
} }
private buildPropertyObject(customName: string, customType: string, customValues: Record<string, any>) {
const value = customValues[customName] || '';
switch (customType) {
case "title":
return {
title: [
{
text: {
content: value,
},
},
],
};
case "rich_text":
return {
rich_text: [
{
text: {
content: value || '',
},
},
],
};
case "date":
return {
date: {
start: value || new Date().toISOString(),
},
};
case "number":
return {
number: Number(value),
};
case "phone_number":
return {
phone_number: value,
};
case "email":
return {
email: value,
};
case "url":
return {
url: value,
};
case "files":
return {
files: Array.isArray(value) ? value.map(url => ({
name: url,
type: "external",
external: {
url: url,
},
})) : [
{
name: value,
type: "external",
external: {
url: value,
},
},
],
};
case "checkbox":
return {
checkbox: Boolean(value) || false,
};
case "select":
return {
select: {
name: value,
},
};
case "multi_select":
return {
multi_select: Array.isArray(value) ? value.map(item => ({name: item})) : [{name: value}],
};
}
}
private buildBodyString(
customProperties: { customName: string; customType: string }[],
customValues: Record<string, string>,
childArr: any,
) {
const properties: { [key: string]: any } = {};
customProperties.forEach(({customName, customType}) => {
properties[customName] = this.buildPropertyObject(customName, customType, customValues);
}
);
return {
parent: {
database_id: this.dbDetails.databaseID,
},
properties,
children: childArr,
};
}
} }

View File

@@ -1,43 +1,57 @@
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 {DatabaseDetails} from "../../ui/settingTabs";
export async function getNowFileMarkdownContentCustom( export async function getNowFileMarkdownContentCustom(
app: App, app: App,
settings: PluginSettings, dbDetails: DatabaseDetails,
) { ) {
const nowFile = app.workspace.getActiveFile(); const nowFile = app.workspace.getActiveFile();
let cover = ''; if (!nowFile) {
let tags = []; new Notice(i18nConfig["open-file"]);
let customValues: Record<string, string> = {}; return;
}
let cover = '';
let customValues: Record<string, any> = {};
const FileCache = app.metadataCache.getFileCache(nowFile); const FileCache = app.metadataCache.getFileCache(nowFile);
try { try {
cover = FileCache.frontmatter.coverurl; cover = FileCache.frontmatter.coverurl;
tags = FileCache.frontmatter.tags;
// split the CustomValues into an array // Get custom property names from dbDetails excluding the title type property
const customValuesNames = settings.CustomValues.split('\n').map(value => value.trim()); const customPropertyNames = dbDetails.customProperties
.filter(property => property.customType !== 'title') // Exclude 'title' type property
.map(property => property.customName);
// get the custom values from the frontmatter // Extract custom values from the front matter based on the names
customValuesNames.forEach(valueName => { customPropertyNames.forEach(propertyName => {
customValues[valueName] = FileCache.frontmatter[valueName]; if (FileCache.frontmatter && FileCache.frontmatter[propertyName] !== undefined) {
}); customValues[propertyName] = FileCache.frontmatter[propertyName];
} catch (error) { }
new Notice(i18nConfig["set-tags-fail"]); });
}
if (nowFile) { // Check if any of the customProperties has a customType of 'title'
const markDownData = await nowFile.vault.read(nowFile); const titleProperty = dbDetails.customProperties.find(property => property.customType === 'title');
return {
markDownData, // If a 'title' type property exists, use the file's basename as its value
nowFile, if (titleProperty) {
cover, customValues[titleProperty.customName] = nowFile.basename; // Use 'basename' for the file name without extension
tags, }
customValues,
}; } catch (error) {
} else { new Notice(i18nConfig["set-tags-fail"]);
new Notice(i18nConfig["open-file"]); }
return;
} if (nowFile) {
const markDownData = await nowFile.vault.read(nowFile);
return {
markDownData,
nowFile,
cover,
customValues,
};
} else {
new Notice(i18nConfig["open-file"]);
return;
}
} }