From 5799ffe79b220e2cdf51f85b0ff4d105fe1febe8 Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Tue, 2 Jul 2024 23:48:37 +0100 Subject: [PATCH 01/14] Update custom function and adjust the custom interface ui --- src/ui/CustomModal.ts | 162 ------------------ src/ui/settingModal.ts | 104 +++++++++-- .../upoload_custom/BaseUpload2NotionCustom.ts | 42 ----- .../upoload_custom/Upload2NotionCustom.ts | 6 + 4 files changed, 100 insertions(+), 214 deletions(-) delete mode 100644 src/ui/CustomModal.ts diff --git a/src/ui/CustomModal.ts b/src/ui/CustomModal.ts deleted file mode 100644 index 003e367..0000000 --- a/src/ui/CustomModal.ts +++ /dev/null @@ -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(); - } -} diff --git a/src/ui/settingModal.ts b/src/ui/settingModal.ts index 6195085..feaf89c 100644 --- a/src/ui/settingModal.ts +++ b/src/ui/settingModal.ts @@ -8,10 +8,12 @@ import { import {i18nConfig} from "../lang/I18n"; import ObsidianSyncNotionPlugin from "../main"; import {DatabaseDetails, ObsidianSettingTab} from "./settingTabs"; -import {CustomModal} from "./CustomModal"; +// import {CustomModal} from "./CustomModal"; export class SettingModal extends Modal { + propertyLines: Setting[] = []; // Store all property line settings + properties: { customName: string, customType: string }[] = []; // Array to store property values and types [key: string]: any; // Index signature data: Record = { databaseFormat: 'none', @@ -223,15 +225,8 @@ export class SettingModal extends Modal { .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(); + const customTabs = nextTabs.createDiv("custom-tabs"); + this.createPropertyLine(customTabs); }); } ); @@ -255,6 +250,95 @@ export class SettingModal extends Modal { } + 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); + } + // create a function to create a div with a style for pop over elements public createStyleDiv(className: string, commandValue: boolean = false, parentEl: HTMLElement) { diff --git a/src/upload/upoload_custom/BaseUpload2NotionCustom.ts b/src/upload/upoload_custom/BaseUpload2NotionCustom.ts index 5c49e60..54ae60d 100644 --- a/src/upload/upoload_custom/BaseUpload2NotionCustom.ts +++ b/src/upload/upoload_custom/BaseUpload2NotionCustom.ts @@ -50,46 +50,4 @@ export class UploadBaseCustom { 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}`) - // // } - // } } diff --git a/src/upload/upoload_custom/Upload2NotionCustom.ts b/src/upload/upoload_custom/Upload2NotionCustom.ts index 69998f8..74d28d2 100644 --- a/src/upload/upoload_custom/Upload2NotionCustom.ts +++ b/src/upload/upoload_custom/Upload2NotionCustom.ts @@ -71,6 +71,8 @@ export class Upload2NotionCustom extends UploadBaseCustom { }; } + console.log(bodyString) + try { return await requestUrl({ url: `https://api.notion.com/v1/pages`, @@ -218,11 +220,15 @@ export class Upload2NotionCustom extends UploadBaseCustom { const properties: { [key: string]: any } = {}; + // Only include custom properties that have values customProperties.forEach(({customName, customType}) => { + if (customValues[customName] !== undefined) { properties[customName] = this.buildPropertyObject(customName, customType, customValues); } + } ); + console.log(properties) return { parent: { From 863a6fb0dc567ca2af08c661fc28ebab27491a4c Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Tue, 2 Jul 2024 23:56:35 +0100 Subject: [PATCH 02/14] more clear logic customised database setting code --- src/ui/settingModal.ts | 114 +++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 72 deletions(-) diff --git a/src/ui/settingModal.ts b/src/ui/settingModal.ts index feaf89c..9139195 100644 --- a/src/ui/settingModal.ts +++ b/src/ui/settingModal.ts @@ -240,89 +240,58 @@ export class SettingModal extends Modal { 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}`}); - }); - - } createPropertyLine(containerEl: HTMLElement): void { const propertyIndex = this.properties.length; this.properties.push({customName: "", customType: ""}); // Initialize with empty values const propertyLine = new Setting(containerEl) + .setName(propertyIndex === 0 ? i18nConfig.CustomPropertyFirstColumn : `${i18nConfig.CustomProperty} ${propertyIndex}`) + .setDesc(propertyIndex === 0 ? i18nConfig.CustomPropertyFirstColumnDesc : ""); - if (propertyIndex === 0) { - propertyLine - .setName(i18nConfig.CustomPropertyFirstColumn) - .setDesc(i18nConfig.CustomPropertyFirstColumnDesc) + propertyLine.addText(text => { + text.setPlaceholder(i18nConfig.CustomPropertyName) + .setValue("") + .onChange(value => { + this.properties[propertyIndex].customName = value; + }); + }); - 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) => { + const options: Record = { + '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', + }; + if (propertyIndex === 0) { + dropdown.addOption("title", "Title"); + } + Object.keys(options).forEach(key => { + dropdown.addOption(key, options[key]); + }); + dropdown.setValue("") + .onChange(value => { + this.properties[propertyIndex].customType = value; + }); + }); - 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 - }); - } - ) + if (propertyIndex > 0) { propertyLine.addButton((button) => { return button .setTooltip("Delete") @@ -336,6 +305,7 @@ export class SettingModal extends Modal { } ); } + this.propertyLines.push(propertyLine); } From 16e08279911d8484e8d893d2ef36e0fc02ecb066 Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Wed, 3 Jul 2024 08:47:33 +0100 Subject: [PATCH 03/14] update the basic function of edit modal --- src/ui/EditModal.ts | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/ui/EditModal.ts b/src/ui/EditModal.ts index c6a3527..cc98c24 100644 --- a/src/ui/EditModal.ts +++ b/src/ui/EditModal.ts @@ -3,7 +3,6 @@ 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 = { @@ -244,15 +243,14 @@ export class EditModal extends SettingModal { .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(); + const customTabs = nextTabs.createDiv("custom-tabs"); + this.createPropertyLine(customTabs); + // let customModal = new CustomModal(this.app); + // customModal.onClose = () => { + // this.renderCustomPreview(customModal.properties, nextTabs) + // this.dataTemp.customPropertiesTemp = customModal.properties; + // } + // customModal.open(); }); } ); @@ -261,6 +259,7 @@ export class EditModal extends SettingModal { } + createStyleDiv(className: string, commandValue: boolean = false, parentEl: HTMLElement): HTMLDivElement { return super.createStyleDiv(className, commandValue, parentEl); } From 9bcdb42edb506140380d4be93950c749c4256eb5 Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Wed, 3 Jul 2024 11:06:54 +0100 Subject: [PATCH 04/14] settingmodal save mapping for reference --- src/ui/settingModal.ts | 60 +++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/src/ui/settingModal.ts b/src/ui/settingModal.ts index 9139195..6a9b49e 100644 --- a/src/ui/settingModal.ts +++ b/src/ui/settingModal.ts @@ -240,7 +240,6 @@ export class SettingModal extends Modal { this.display() } - createPropertyLine(containerEl: HTMLElement): void { const propertyIndex = this.properties.length; this.properties.push({customName: "", customType: ""}); // Initialize with empty values @@ -291,25 +290,62 @@ export class SettingModal extends Modal { }); + // TODO: update the index of the property line if (propertyIndex > 0) { 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(); - }); - } - ); + return button + .setTooltip("Delete") + .setIcon("trash") + .onClick(() => { + const currentIndex = this.properties.findIndex((p, idx) => idx === propertyIndex); + // Directly use propertyIndex captured in closure + if (currentIndex > 0) { + this.properties.splice(currentIndex, 1); // Remove the property from the array + + // Update UI components + containerEl.querySelectorAll('.setting-line').forEach((line, index) => { + if (index > currentIndex) { + // Reduce the index in the UI component ID or data attribute if you are using them + const settingComponent = this.propertyLines[index]; + settingComponent.setName(i18nConfig.CustomProperty + (index - 1)); + } + }); + + propertyLine.settingEl.remove(); // Remove the UI element + this.propertyLines.splice(currentIndex, 1); // Remove the property line from the tracking array + + // Update remaining property lines to reflect new indices + this.updatePropertyLines(); + + } + }); + }); } this.propertyLines.push(propertyLine); } + deleteProperty(index: number) { + if (index > 0 && index < this.properties.length) { + this.properties.splice(index, 1); + this.propertyLines[index].dispose(); // Assuming dispose method exists for cleanup + this.propertyLines.splice(index, 1); + this.updatePropertyLines(); + } + } + + updatePropertyLines() { + this.propertyLines.forEach((line, index) => { + line.setName(`${i18nConfig.CustomProperty} ${index}`); + // Assuming buttons are accessible directly; adjust if needed + const deleteButton = line.containerEl.querySelector('.delete-button'); + if (deleteButton) { + deleteButton.setAttribute('data-index', index.toString()); + } + }); + } + // create a function to create a div with a style for pop over elements public createStyleDiv(className: string, commandValue: boolean = false, parentEl: HTMLElement) { return parentEl.createDiv(className, (div) => { From 72146afe4846cc75503ae1b414efb0c9863e0656 Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Wed, 3 Jul 2024 13:39:56 +0100 Subject: [PATCH 05/14] update settingModal.ts refactor the customise database and improve the creating logic --- src/ui/settingModal.ts | 167 ++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 95 deletions(-) diff --git a/src/ui/settingModal.ts b/src/ui/settingModal.ts index 6a9b49e..2e8c217 100644 --- a/src/ui/settingModal.ts +++ b/src/ui/settingModal.ts @@ -13,7 +13,7 @@ import {DatabaseDetails, ObsidianSettingTab} from "./settingTabs"; export class SettingModal extends Modal { propertyLines: Setting[] = []; // Store all property line settings - properties: { customName: string, customType: string }[] = []; // Array to store property values and types + properties: { customName: string, customType: string , index: number}[] = []; // Array to store property values and types [key: string]: any; // Index signature data: Record = { databaseFormat: 'none', @@ -49,7 +49,6 @@ export class SettingModal extends Modal { // this.data.customValues = dbDetails.customValues; this.data.saved = dbDetails.saved; } - } display(): void { @@ -64,48 +63,26 @@ export class SettingModal extends Modal { const nextTabs = contentEl.createDiv('next-tabs'); - if (this.data.saved) { - 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); - }); + 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.data.databaseFormat, nextTabs); - }); + // Initialize content based on the current dropdown value + (this.data.saved) ? this.updateContentBasedOnSelection(this.data.databaseFormat, nextTabs) : this.updateContentBasedOnSelection(this.data.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 @@ -117,6 +94,7 @@ export class SettingModal extends Modal { .setIcon('checkmark') .onClick(async () => { this.data.saved = true; + this.data.customProperties = this.properties; this.close(); }); } @@ -127,6 +105,7 @@ export class SettingModal extends Modal { .setIcon('cross') .onClick(() => { this.data.saved = false; + this.data.customProperties = this.properties; this.close(); }); } @@ -163,10 +142,6 @@ export class SettingModal extends Modal { this.updateSettingEl(CustomNameEl, value) - // this.updateSettingEl(CustomValuesEl, value) - - // await this.plugin.saveSettings(); - // await this.plugin.commands.updateCommand(); }) ); @@ -242,17 +217,22 @@ export class SettingModal extends Modal { createPropertyLine(containerEl: HTMLElement): void { const propertyIndex = this.properties.length; - this.properties.push({customName: "", customType: ""}); // Initialize with empty values + + this.properties.push({customName: "", customType: "", index: propertyIndex}); + + console.log(this.properties[propertyIndex].index); 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 => { - this.properties[propertyIndex].customName = value; + let actualIndex = this.properties.findIndex(p => p.index === propertyIndex); + if (actualIndex !== -1) { + this.properties[actualIndex].customName = value; + } }); }); @@ -269,55 +249,46 @@ export class SettingModal extends Modal { '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', + // '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', }; + + // Use a reference to the current property object + const currentProperty = this.properties[propertyIndex]; + if (propertyIndex === 0) { dropdown.addOption("title", "Title"); + } else { + Object.keys(options).forEach(key => { + dropdown.addOption(key, options[key]); + }); } - Object.keys(options).forEach(key => { - dropdown.addOption(key, options[key]); - }); dropdown.setValue("") .onChange(value => { - this.properties[propertyIndex].customType = value; + if (currentProperty) { + currentProperty.customType = value; + // Retrieve the index of currentProperty from the properties array + const updatedIndex = this.properties.findIndex(p => p === currentProperty); + console.log(`Updated value at index ${updatedIndex}: ${value}`); + } else { + console.log("Property not found, may have been deleted."); + } }); }); - // TODO: update the index of the property line if (propertyIndex > 0) { - propertyLine.addButton((button) => { + propertyLine.addButton(button => { return button .setTooltip("Delete") .setIcon("trash") .onClick(() => { - const currentIndex = this.properties.findIndex((p, idx) => idx === propertyIndex); - // Directly use propertyIndex captured in closure - if (currentIndex > 0) { - this.properties.splice(currentIndex, 1); // Remove the property from the array - - // Update UI components - containerEl.querySelectorAll('.setting-line').forEach((line, index) => { - if (index > currentIndex) { - // Reduce the index in the UI component ID or data attribute if you are using them - const settingComponent = this.propertyLines[index]; - settingComponent.setName(i18nConfig.CustomProperty + (index - 1)); - } - }); - - propertyLine.settingEl.remove(); // Remove the UI element - this.propertyLines.splice(currentIndex, 1); // Remove the property line from the tracking array - - // Update remaining property lines to reflect new indices - this.updatePropertyLines(); - - } + this.deleteProperty(propertyIndex); }); }); } @@ -325,24 +296,30 @@ export class SettingModal extends Modal { this.propertyLines.push(propertyLine); } + deleteProperty(propertyIndex: number) { + let actualIndex = this.properties.findIndex(p => p.index === propertyIndex); + if (actualIndex !== -1) { + this.properties.splice(actualIndex, 1); + this.propertyLines[actualIndex].settingEl.remove(); + this.propertyLines.splice(actualIndex, 1); + + // Update indices in the properties array + this.properties.forEach((prop, idx) => { + prop.index = idx; + }); - deleteProperty(index: number) { - if (index > 0 && index < this.properties.length) { - this.properties.splice(index, 1); - this.propertyLines[index].dispose(); // Assuming dispose method exists for cleanup - this.propertyLines.splice(index, 1); this.updatePropertyLines(); + + console.log("Updated indices after deletion:"); + this.properties.forEach((prop, idx) => { + console.log(`Index ${idx}: ${prop.index}`); + }); } } updatePropertyLines() { - this.propertyLines.forEach((line, index) => { - line.setName(`${i18nConfig.CustomProperty} ${index}`); - // Assuming buttons are accessible directly; adjust if needed - const deleteButton = line.containerEl.querySelector('.delete-button'); - if (deleteButton) { - deleteButton.setAttribute('data-index', index.toString()); - } + this.propertyLines.forEach((line, idx) => { + line.setName(idx === 0 ? i18nConfig.CustomPropertyFirstColumn : `${i18nConfig.CustomProperty} ${idx}`); }); } From f7bcf71020c2b081f597ff7da9bcdeb4bd5448e0 Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Wed, 3 Jul 2024 14:26:02 +0100 Subject: [PATCH 06/14] create retrieve function to get all created properties for customised database --- src/ui/EditModal.ts | 97 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 90 insertions(+), 7 deletions(-) diff --git a/src/ui/EditModal.ts b/src/ui/EditModal.ts index cc98c24..8f0dc17 100644 --- a/src/ui/EditModal.ts +++ b/src/ui/EditModal.ts @@ -3,8 +3,12 @@ import {SettingModal} from "./settingModal"; import ObsidianSyncNotionPlugin from "../main"; import {DatabaseDetails, ObsidianSettingTab} from "./settingTabs"; import {i18nConfig} from "../lang/I18n"; +import {customProperty} from "./settingModal"; export class EditModal extends SettingModal { + propertyLines: Setting[] = []; // Store all property line settings + properties: { customName: string, customType: string , index: number}[] = []; // Array to store property values and types + [key: string]: any; // Index signature dataTemp: Record = { databaseFormatTemp: '', // databaseFormatTempInd: false, @@ -245,19 +249,98 @@ export class EditModal extends SettingModal { .onClick(async () => { const customTabs = nextTabs.createDiv("custom-tabs"); this.createPropertyLine(customTabs); - // let customModal = new CustomModal(this.app); - // customModal.onClose = () => { - // this.renderCustomPreview(customModal.properties, nextTabs) - // this.dataTemp.customPropertiesTemp = customModal.properties; - // } - // customModal.open(); + + + }); } ); + const retrieveTabs = nextTabs.createDiv("retrieve-tabs"); + this.retrievePropertyLine(retrieveTabs, this.dataTemp.customPropertiesTemp) } - + } + retrievePropertyLine(containerEl: HTMLElement, properties: customProperty[]): void { + const propertyIndex = properties.length; + + console.log(propertyIndex, "have been created"); + + this.properties.forEach((property, index) => { + 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 = { + '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', + }; + + // Use a reference to the current property object + 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); + }); + }); + } + }); + + } + + createStyleDiv(className: string, commandValue: boolean = false, parentEl: HTMLElement): HTMLDivElement { From d7372c7c55033de1cb39c2b66d694a48a05ab624 Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Wed, 3 Jul 2024 16:05:24 +0100 Subject: [PATCH 07/14] Improve preview function for customised database --- src/ui/PreviewModal.ts | 52 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/src/ui/PreviewModal.ts b/src/ui/PreviewModal.ts index adec2bc..d7c059a 100644 --- a/src/ui/PreviewModal.ts +++ b/src/ui/PreviewModal.ts @@ -1,6 +1,8 @@ import {App, ExtraButtonComponent, Modal, Notice, Setting} from "obsidian"; import ObsidianSyncNotionPlugin from "../main"; import {DatabaseDetails, ObsidianSettingTab} from "./settingTabs"; +import {customProperty} from "./settingModal"; +import {i18nConfig} from "../lang/I18n"; export class PreviewModal extends Modal { plugin: ObsidianSyncNotionPlugin; @@ -120,12 +122,10 @@ export class PreviewModal extends Modal { 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)); + const customPrv = previewEl.createDiv("custom-tabs"); + + + this.previewPropertyLine(previewEl, this.dbDetails.customProperties); } } @@ -136,4 +136,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 = { + '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 + }); + }); + } + } From 24ebb0bf8a837a9c73ed9bf358e1c9b1ae082659 Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Wed, 3 Jul 2024 22:01:46 +0100 Subject: [PATCH 08/14] Back up edit modal --- src/ui/EditModal.ts | 188 +++++++++++++++++++++++--------------------- 1 file changed, 98 insertions(+), 90 deletions(-) diff --git a/src/ui/EditModal.ts b/src/ui/EditModal.ts index 8f0dc17..4b0b47a 100644 --- a/src/ui/EditModal.ts +++ b/src/ui/EditModal.ts @@ -1,13 +1,11 @@ import {App, ButtonComponent, Modal, Setting} from "obsidian"; -import {SettingModal} from "./settingModal"; +import {customProperty, SettingModal} from "./settingModal"; import ObsidianSyncNotionPlugin from "../main"; import {DatabaseDetails, ObsidianSettingTab} from "./settingTabs"; import {i18nConfig} from "../lang/I18n"; -import {customProperty} from "./settingModal"; export class EditModal extends SettingModal { propertyLines: Setting[] = []; // Store all property line settings - properties: { customName: string, customType: string , index: number}[] = []; // Array to store property values and types [key: string]: any; // Index signature dataTemp: Record = { databaseFormatTemp: '', @@ -100,6 +98,8 @@ export class EditModal extends SettingModal { let {contentEl} = this; contentEl.empty(); + let properties: { customName: string, customType: string , index: number} = this.dataTemp.customPropertiesTemp; + const editDiv = contentEl.createDiv('edit-div'); const nextTabs = contentEl.createDiv('next-tabs'); @@ -144,6 +144,8 @@ export class EditModal extends SettingModal { .setIcon('cross') .onClick(() => { this.dataTemp.savedTempInd = false; + // reset the properties + const properties: any[] = []; this.close(); }); } @@ -186,10 +188,6 @@ export class EditModal extends SettingModal { this.updateSettingEl(CustomNameEl, value) - // this.updateSettingEl(CustomValuesEl, value) - - // await this.plugin.saveSettings(); - // await this.plugin.commands.updateCommand(); }) ); @@ -239,6 +237,9 @@ export class EditModal extends SettingModal { this.createSettingEl(nextTabs, i18nConfig.DatabaseID, i18nConfig.DatabaseIDDesc, 'password', i18nConfig.DatabaseIDText, this.dataTemp.databaseIDTemp, 'dataTemp', 'databaseIDTemp') // add new property button + const properties = this.dataTemp.customPropertiesTemp; + const propertiesContainer = nextTabs.createDiv("properties-container"); + new Setting(nextTabs) .setName(i18nConfig.NotionCustomValues) .setDesc(i18nConfig.NotionCustomValuesDesc) @@ -247,100 +248,107 @@ export class EditModal extends SettingModal { .setTooltip('Add new property') .setIcon('plus') .onClick(async () => { - const customTabs = nextTabs.createDiv("custom-tabs"); - this.createPropertyLine(customTabs); - - - + this.createPropertyLine(propertiesContainer, properties); }); } ); - const retrieveTabs = nextTabs.createDiv("retrieve-tabs"); - this.retrievePropertyLine(retrieveTabs, this.dataTemp.customPropertiesTemp) + + this.initializePropertyLines(propertiesContainer, properties) } - } - retrievePropertyLine(containerEl: HTMLElement, properties: customProperty[]): void { - const propertyIndex = properties.length; - - console.log(propertyIndex, "have been created"); - - this.properties.forEach((property, index) => { - 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; - } - }); - }); + initializePropertyLines(containerEl: HTMLElement, properties: customProperty[]): void { - propertyLine.addDropdown((dropdown) => { - const options: Record = { - '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', - }; + console.log(properties.length, "properties have been created"); - // Use a reference to the current property object - const currentProperty = properties[propertyIndex]; + containerEl.innerHTML = ''; - 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); - }); - }); - } + // Retrieve and display existing properties + properties.forEach(property => { + createOrUpdatePropertyLine(containerEl, property); }); - + + // Add a button for creating new properties at the end of the container + const addButton = document.createElement('button'); + addButton.textContent = "Add New Property"; + addButton.onclick = () => { + createOrUpdatePropertyLine(containerEl, null, properties); + }; + + containerEl.appendChild(addButton); + } + + createOrUpdatePropertyLine(containerEl: HTMLElement, property: null, properties: customProperty[]) { + const 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 => { + let actualIndex = properties.findIndex(p => p.index === propertyIndex); + if (actualIndex !== -1) { + properties[actualIndex].customName = value; + } + }); + }); + + propertyLine.addDropdown((dropdown) => { + const options = { + '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' + }; + Object.keys(options).forEach(key => { + dropdown.addOption(key, options[key]); + }); + dropdown.setValue(isExistingProperty ? property.customType : "") + .onChange(value => { + if (isExistingProperty) { + property.customType = value; + } else { + const newProperty = { customName: '', customType: value, index: propertyIndex }; + properties.push(newProperty); + } + }); + }); + + if (isExistingProperty && propertyIndex > 0) { + propertyLine.addButton(button => { + return button + .setTooltip("Delete") + .setIcon("trash") + .onClick(() => { + deleteProperty(propertyIndex, properties); + }); + }); + } + + if (!isExistingProperty) { + properties.push({ customName: "", customType: "", index: propertyIndex }); + } + + } + + + + deleteProperty(index: number, properties: customProperty[]): void { + const updatedProperties = properties.filter(p => p.index !== index); + properties.length = 0; // Clear existing array + updatedProperties.forEach(p => properties.push(p)); // Re-add filtered properties + initializePropertyLines(document.getElementById('propertiesContainer'), properties); // Reinitialize UI } - - createStyleDiv(className: string, commandValue: boolean = false, parentEl: HTMLElement): HTMLDivElement { From 70f30f0713027cc2ef39fa19a80bc8d57af32d74 Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Wed, 3 Jul 2024 22:35:47 +0100 Subject: [PATCH 09/14] Add support for notion link display in the front matter. --- src/lang/locale/en.ts | 2 ++ src/lang/locale/ja.ts | 2 ++ src/lang/locale/zh.ts | 2 ++ src/ui/settingTabs.ts | 40 +++++++--------------------------------- 4 files changed, 13 insertions(+), 33 deletions(-) diff --git a/src/lang/locale/en.ts b/src/lang/locale/en.ts index 93c4e92..cbba596 100644 --- a/src/lang/locale/en.ts +++ b/src/lang/locale/en.ts @@ -33,6 +33,8 @@ export const en = { NotionUserDesc: "Collect from share link likes:https://username.notion.site. Your notion id is [username]", 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", NotionGeneralButton: "Notion General Sync", NotionGeneralButtonDesc: "Open this option, Sync to Notion General Database command will be displayed in the command palette (default: ON)", diff --git a/src/lang/locale/ja.ts b/src/lang/locale/ja.ts index d6ab0c8..0221025 100644 --- a/src/lang/locale/ja.ts +++ b/src/lang/locale/ja.ts @@ -31,6 +31,8 @@ export const ja = { NotionUser: "Notion ID(ユーザー名、任意)", NotionUserDesc: "共有リンクから取得(例:https://username.notion.site)。Notion IDは[username]です", NotionUserText: "Notion IDを入力", + NotionLinkDisplay: "Notionリンク表示", + NotionLinkDisplayDesc: "デフォルトはONです。front matterにリンクを非表示にしたい場合は、オフにしてください", NotionGeneralSettingHeader: "一般的なNotionデータベース設定", NotionGeneralButton: "一般的なNotion同期", NotionGeneralButtonDesc: "このオプションを開くと、一般的なNotionデータベース同期コマンドがコマンドパレットに表示されます(デフォルト:ON)", diff --git a/src/lang/locale/zh.ts b/src/lang/locale/zh.ts index 89f1f67..08a9375 100644 --- a/src/lang/locale/zh.ts +++ b/src/lang/locale/zh.ts @@ -33,6 +33,8 @@ export const zh = { NotionUserDesc: "数据库分享链接类似:https://username.notion.site/。你的 Notion ID 是 [username]", NotionUserText: "输入你的 Notion ID", + NotionLinkDisplay: "Notion 链接显示", + NotionLinkDisplayDesc: "默认开启,如果你不想在front matter中显示链接,请关闭", NotionGeneralSettingHeader: "普通 Notion 数据库设置", NotionGeneralButton: "普通数据库同步", NotionGeneralButtonDesc: "打开此选项,同步到普通数据库命令将显示在命令面板中(默认:开)", diff --git a/src/ui/settingTabs.ts b/src/ui/settingTabs.ts index 28291d3..d4316fc 100644 --- a/src/ui/settingTabs.ts +++ b/src/ui/settingTabs.ts @@ -13,6 +13,7 @@ export interface PluginSettings { databaseIDNext: string; bannerUrl: string; notionUser: string; + NotionLinkDisplay: boolean; proxy: string; GeneralButton: boolean; tagButton: boolean; @@ -37,7 +38,7 @@ export interface DatabaseDetails { tagButton: boolean; customTitleButton: boolean; customTitleName: string; - customProperties:{ customName: string, customType: string }[]; + customProperties:{ customName: string, customType: string, index: number}[]; // customValues: string; saved: boolean; } @@ -48,6 +49,7 @@ export const DEFAULT_SETTINGS: PluginSettings = { databaseIDNext: "", bannerUrl: "", notionUser: "", + NotionLinkDisplay: true, proxy: "", GeneralButton: true, tagButton: true, @@ -84,6 +86,10 @@ export class ObsidianSettingTab extends PluginSettingTab { this.createSettingEl(containerEl, i18nConfig.NotionUser, i18nConfig.NotionUserDesc, 'text', i18nConfig.NotionUserText, this.plugin.settings.notionUser, 'notionUser') + this.createSettingEl(containerEl, i18nConfig.NotionLinkDisplay, i18nConfig.NotionLinkDisplayDesc, 'toggle', i18nConfig.NotionLinkDisplay, this.plugin.settings.NotionLinkDisplay, 'NotionLinkDisplay') + + // TODO: add toggle to enable or disable link display + // add new button @@ -132,38 +138,6 @@ export class ObsidianSettingTab extends PluginSettingTab { // list all created database 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 From 82529ce56a534ac4b8843a777c70bafa00baeaf6 Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Thu, 4 Jul 2024 10:00:46 +0100 Subject: [PATCH 10/14] back up for edit modal --- src/ui/EditModal.ts | 173 +++++++++++++++++++++----------------------- 1 file changed, 83 insertions(+), 90 deletions(-) diff --git a/src/ui/EditModal.ts b/src/ui/EditModal.ts index 4b0b47a..8029ec2 100644 --- a/src/ui/EditModal.ts +++ b/src/ui/EditModal.ts @@ -1,8 +1,8 @@ -import {App, ButtonComponent, Modal, Setting} from "obsidian"; -import {customProperty, SettingModal} from "./settingModal"; +import { App, ButtonComponent, Modal, Setting } from "obsidian"; +import { customProperty, SettingModal } from "./settingModal"; import ObsidianSyncNotionPlugin from "../main"; -import {DatabaseDetails, ObsidianSettingTab} from "./settingTabs"; -import {i18nConfig} from "../lang/I18n"; +import { DatabaseDetails, ObsidianSettingTab } from "./settingTabs"; +import { i18nConfig } from "../lang/I18n"; export class EditModal extends SettingModal { propertyLines: Setting[] = []; // Store all property line settings @@ -95,60 +95,60 @@ export class EditModal extends SettingModal { this.containerEl.addClass("edit-modal"); this.titleEl.setText('Edit Database'); - let {contentEl} = this; + let { contentEl } = this; contentEl.empty(); - let properties: { customName: string, customType: string , index: number} = this.dataTemp.customPropertiesTemp; + let properties: { customName: string, customType: string, index: number } = this.dataTemp.customPropertiesTemp; 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); - }); + 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); - }); + // 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(); - }); - } + 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; - // reset the properties - const properties: any[] = []; - this.close(); - }); - } + return button + .setTooltip('Cancel') + .setIcon('cross') + .onClick(() => { + this.dataTemp.savedTempInd = false; + // reset the properties + const properties: any[] = []; + this.close(); + }); + } ); } @@ -167,13 +167,13 @@ export class EditModal extends SettingModal { nextTabs.createEl('h3', { text: i18nConfig.NotionGeneralSettingHeader }); // 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 - 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 - 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 @@ -185,7 +185,6 @@ export class EditModal extends SettingModal { .setValue(this.dataTemp.customTitleButtonTemp) .onChange(async (value) => { this.dataTemp.customTitleButtonTemp = value; - this.updateSettingEl(CustomNameEl, value) }) @@ -194,14 +193,14 @@ export class EditModal extends SettingModal { // 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') + 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') + 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') + this.createSettingEl(nextTabs, i18nConfig.DatabaseID, i18nConfig.DatabaseIDDesc, 'password', i18nConfig.DatabaseIDText, this.dataTemp.databaseIDTemp, 'dataTemp', 'databaseIDTemp') } else if (value === 'next') { @@ -209,20 +208,20 @@ export class EditModal extends SettingModal { nextTabs.createEl('h3', { text: i18nConfig.NotionNextSettingHeader }); // 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 - 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') // 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 - 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 === 'custom') { - nextTabs.createEl('h3', {text: i18nConfig.NotionCustomSettingHeader}); + nextTabs.createEl('h3', { text: i18nConfig.NotionCustomSettingHeader }); // add full name this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.dataTemp.databaseFullNameTemp, 'dataTemp', 'databaseFullNameTemp') @@ -237,23 +236,9 @@ export class EditModal extends SettingModal { this.createSettingEl(nextTabs, i18nConfig.DatabaseID, i18nConfig.DatabaseIDDesc, 'password', i18nConfig.DatabaseIDText, this.dataTemp.databaseIDTemp, 'dataTemp', 'databaseIDTemp') // add new property button - const properties = this.dataTemp.customPropertiesTemp; const propertiesContainer = nextTabs.createDiv("properties-container"); - new Setting(nextTabs) - .setName(i18nConfig.NotionCustomValues) - .setDesc(i18nConfig.NotionCustomValuesDesc) - .addButton((button: ButtonComponent) => { - return button - .setTooltip('Add new property') - .setIcon('plus') - .onClick(async () => { - this.createPropertyLine(propertiesContainer, properties); - }); - } - ); - - this.initializePropertyLines(propertiesContainer, properties) + this.initializePropertyLines(propertiesContainer, this.dataTemp.customPropertiesTemp); } } @@ -261,24 +246,28 @@ export class EditModal extends SettingModal { console.log(properties.length, "properties have been created"); - containerEl.innerHTML = ''; + new Setting(containerEl) + .setName(i18nConfig.NotionCustomValues) + .setDesc(i18nConfig.NotionCustomValuesDesc) + .addButton((button: ButtonComponent) => { + return button + .setTooltip('Add one more property') + .setButtonText('Add New Property') + .onClick(async () => { this.createOrUpdatePropertyLine(containerEl, null, properties); }) + }); + // const addButton = document.createElement('button'); + // addButton.textContent = "Add New Property"; + // addButton.onclick = () => this.createOrUpdatePropertyLine(containerEl, null, properties); + // containerEl.appendChild(addButton); - // Retrieve and display existing properties + // Retrieve and display existing properties below the button properties.forEach(property => { - createOrUpdatePropertyLine(containerEl, property); + this.createOrUpdatePropertyLine(containerEl, property, properties); }); - // Add a button for creating new properties at the end of the container - const addButton = document.createElement('button'); - addButton.textContent = "Add New Property"; - addButton.onclick = () => { - createOrUpdatePropertyLine(containerEl, null, properties); - }; - - containerEl.appendChild(addButton); } - createOrUpdatePropertyLine(containerEl: HTMLElement, property: null, properties: customProperty[]) { + createOrUpdatePropertyLine(containerEl: HTMLElement, property: customProperty | null, properties: customProperty[]) { const isExistingProperty = property !== null; const propertyIndex = isExistingProperty ? property.index : properties.length; @@ -298,7 +287,7 @@ export class EditModal extends SettingModal { }); propertyLine.addDropdown((dropdown) => { - const options = { + const options: Record = { 'text': 'Text', 'number': 'Number', 'select': 'Select', @@ -310,9 +299,14 @@ export class EditModal extends SettingModal { 'email': 'Email', 'phone_number': 'Phone Number' }; - Object.keys(options).forEach(key => { - dropdown.addOption(key, options[key]); - }); + + 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 => { if (isExistingProperty) { @@ -324,13 +318,13 @@ export class EditModal extends SettingModal { }); }); - if (isExistingProperty && propertyIndex > 0) { + if (propertyIndex > 0) { propertyLine.addButton(button => { return button .setTooltip("Delete") .setIcon("trash") .onClick(() => { - deleteProperty(propertyIndex, properties); + this.deleteProperty(propertyIndex, properties); }); }); } @@ -341,13 +335,12 @@ export class EditModal extends SettingModal { } - deleteProperty(index: number, properties: customProperty[]): void { const updatedProperties = properties.filter(p => p.index !== index); properties.length = 0; // Clear existing array updatedProperties.forEach(p => properties.push(p)); // Re-add filtered properties - initializePropertyLines(document.getElementById('propertiesContainer'), properties); // Reinitialize UI + this.initializePropertyLines(document.getElementById('propertiesContainer'), properties); // Reinitialize UI } From 1cee2b67a689c6bee3ea18807486975bf8efc705 Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Thu, 4 Jul 2024 17:06:23 +0100 Subject: [PATCH 11/14] update edit modal with better display setting. --- src/ui/EditModal.ts | 102 +++++++++++++++++++++++++------------------- 1 file changed, 59 insertions(+), 43 deletions(-) diff --git a/src/ui/EditModal.ts b/src/ui/EditModal.ts index 8029ec2..bbf0815 100644 --- a/src/ui/EditModal.ts +++ b/src/ui/EditModal.ts @@ -5,7 +5,6 @@ import { DatabaseDetails, ObsidianSettingTab } from "./settingTabs"; import { i18nConfig } from "../lang/I18n"; export class EditModal extends SettingModal { - propertyLines: Setting[] = []; // Store all property line settings [key: string]: any; // Index signature dataTemp: Record = { databaseFormatTemp: '', @@ -98,11 +97,10 @@ export class EditModal extends SettingModal { let { contentEl } = this; contentEl.empty(); - let properties: { customName: string, customType: string, index: number } = this.dataTemp.customPropertiesTemp; - const editDiv = contentEl.createDiv('edit-div'); const nextTabs = contentEl.createDiv('next-tabs'); + new Setting(editDiv) .setName(i18nConfig.databaseFormat) .setDesc(i18nConfig.databaseFormatDesc) @@ -134,6 +132,8 @@ export class EditModal extends SettingModal { .onClick(async () => { this.dataTemp.savedTempInd = true; this.dataTemp.savedTemp = true; + this.dataPrev = { ...this.dataTemp }; + this.dataPrev.customPropertiesPrev = this.dataTemp.customPropertiesTemp.slice(); this.close(); }); } @@ -143,17 +143,19 @@ export class EditModal extends SettingModal { .setTooltip('Cancel') .setIcon('cross') .onClick(() => { - this.dataTemp.savedTempInd = false; - // reset the properties - const properties: any[] = []; + this.dataTemp = { ...this.dataPrev }; + this.dataTemp.customPropertiesTemp = this.dataPrev.customPropertiesPrev.slice(); + nextTabs.empty(); + this.updateContentBasedOnSelection(this.dataTemp.databaseFormatTemp, nextTabs); this.close(); }); } ); - } onOpen(): void { + // Backup initial state when the modal is opened + this.dataPrev.customPropertiesPrev = this.dataTemp.customPropertiesTemp.slice(); this.display() } @@ -235,40 +237,37 @@ export class EditModal extends SettingModal { // add database id this.createSettingEl(nextTabs, i18nConfig.DatabaseID, i18nConfig.DatabaseIDDesc, 'password', i18nConfig.DatabaseIDText, this.dataTemp.databaseIDTemp, 'dataTemp', 'databaseIDTemp') - // add new property button - const propertiesContainer = nextTabs.createDiv("properties-container"); - - this.initializePropertyLines(propertiesContainer, this.dataTemp.customPropertiesTemp); + // add custom properties + this.initializePropertyLines(nextTabs, this.dataTemp.customPropertiesTemp); } } initializePropertyLines(containerEl: HTMLElement, properties: customProperty[]): void { - - console.log(properties.length, "properties have been created"); + if (!containerEl) { + console.error('Failed to initialize property lines: containerEl is null'); + return; + } new Setting(containerEl) - .setName(i18nConfig.NotionCustomValues) - .setDesc(i18nConfig.NotionCustomValuesDesc) - .addButton((button: ButtonComponent) => { + .setName("Add New Property") + .setDesc("Click to add a new property") + .addButton(button => { return button + .setButtonText('Add') .setTooltip('Add one more property') - .setButtonText('Add New Property') - .onClick(async () => { this.createOrUpdatePropertyLine(containerEl, null, properties); }) + .onClick(() => { + this.createPropertyLine(containerEl, properties); + }); }); - // const addButton = document.createElement('button'); - // addButton.textContent = "Add New Property"; - // addButton.onclick = () => this.createOrUpdatePropertyLine(containerEl, null, properties); - // containerEl.appendChild(addButton); - // Retrieve and display existing properties below the button properties.forEach(property => { - this.createOrUpdatePropertyLine(containerEl, property, properties); + this.updatePropertyLine(containerEl, property, properties); }); - } - createOrUpdatePropertyLine(containerEl: HTMLElement, property: customProperty | null, properties: customProperty[]) { - const isExistingProperty = property !== null; + + updatePropertyLine(containerEl: HTMLElement, property: customProperty, properties: customProperty[]) { + let isExistingProperty = property !== null; const propertyIndex = isExistingProperty ? property.index : properties.length; const propertyLine = new Setting(containerEl) @@ -279,9 +278,12 @@ export class EditModal extends SettingModal { text.setPlaceholder(i18nConfig.CustomPropertyName) .setValue(isExistingProperty ? property.customName : "") .onChange(value => { - let actualIndex = properties.findIndex(p => p.index === propertyIndex); + 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; } }); }); @@ -307,13 +309,15 @@ export class EditModal extends SettingModal { dropdown.addOption(key, options[key]); }); } + dropdown.setValue(isExistingProperty ? property.customType : "") .onChange(value => { - if (isExistingProperty) { - property.customType = value; - } else { - const newProperty = { customName: '', customType: value, index: propertyIndex }; - properties.push(newProperty); + 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 } }); }); @@ -328,19 +332,31 @@ export class EditModal extends SettingModal { }); }); } - - if (!isExistingProperty) { - properties.push({ customName: "", customType: "", index: propertyIndex }); - } - } + createPropertyLine(containerEl: HTMLElement, properties: customProperty[]) { + super.createPropertyLine(containerEl, properties); + } - deleteProperty(index: number, properties: customProperty[]): void { - const updatedProperties = properties.filter(p => p.index !== index); - properties.length = 0; // Clear existing array - updatedProperties.forEach(p => properties.push(p)); // Re-add filtered properties - this.initializePropertyLines(document.getElementById('propertiesContainer'), properties); // Reinitialize UI + deleteProperty(propertyIndex: number, properties: customProperty[]) { + let actualIndex = properties.findIndex(p => p.index === propertyIndex); + if (actualIndex > 0) { + properties.splice(actualIndex, 1); + this.propertyLines[actualIndex].settingEl.remove(); + this.propertyLines.splice(actualIndex, 1); + + properties.forEach((prop, idx) => { + prop.index = idx; + }); + + this.updatePropertyLines(); + } + } + + updatePropertyLines() { + this.propertyLines.forEach((line, idx) => { + line.setName(idx === 0 ? i18nConfig.CustomPropertyFirstColumn : `${i18nConfig.CustomProperty} ${idx}`); + }); } From d8eb3c89841b2f6ce31b943b1817b3a1061f09da Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Thu, 4 Jul 2024 18:12:31 +0100 Subject: [PATCH 12/14] feat: cancel function works well --- src/ui/EditModal.ts | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/ui/EditModal.ts b/src/ui/EditModal.ts index bbf0815..b1b7b11 100644 --- a/src/ui/EditModal.ts +++ b/src/ui/EditModal.ts @@ -70,7 +70,7 @@ export class EditModal extends SettingModal { this.dataTemp.tagButtonTemp = dbDetails.tagButton; this.dataTemp.customTitleButtonTemp = dbDetails.customTitleButton; 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.savedTemp = dbDetails.saved; @@ -83,7 +83,7 @@ export class EditModal extends SettingModal { this.dataPrev.tagButtonPrev = dbDetails.tagButton; this.dataPrev.customTitleButtonPrev = dbDetails.customTitleButton; 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.dataPrev.savedPrev = dbDetails.saved; } @@ -132,8 +132,6 @@ export class EditModal extends SettingModal { .onClick(async () => { this.dataTemp.savedTempInd = true; this.dataTemp.savedTemp = true; - this.dataPrev = { ...this.dataTemp }; - this.dataPrev.customPropertiesPrev = this.dataTemp.customPropertiesTemp.slice(); this.close(); }); } @@ -143,10 +141,8 @@ export class EditModal extends SettingModal { .setTooltip('Cancel') .setIcon('cross') .onClick(() => { - this.dataTemp = { ...this.dataPrev }; - this.dataTemp.customPropertiesTemp = this.dataPrev.customPropertiesPrev.slice(); - nextTabs.empty(); - this.updateContentBasedOnSelection(this.dataTemp.databaseFormatTemp, nextTabs); + console.log(this.dataTemp); + console.log(this.dataPrev); this.close(); }); } @@ -154,12 +150,9 @@ export class EditModal extends SettingModal { } onOpen(): void { - // Backup initial state when the modal is opened - this.dataPrev.customPropertiesPrev = this.dataTemp.customPropertiesTemp.slice(); this.display() } - updateContentBasedOnSelection(value: string, nextTabs: HTMLElement): void { // Clear existing content nextTabs.empty(); From bfde5dfe1a75d03f574fb5bcce28b8bc79e933a2 Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Thu, 4 Jul 2024 20:28:28 +0100 Subject: [PATCH 13/14] finish the edit modal --- src/ui/EditModal.ts | 34 +++--------- src/ui/settingModal.ts | 118 ++++++++++++++++++++--------------------- src/ui/settingTabs.ts | 7 ++- 3 files changed, 68 insertions(+), 91 deletions(-) diff --git a/src/ui/EditModal.ts b/src/ui/EditModal.ts index b1b7b11..8a562f3 100644 --- a/src/ui/EditModal.ts +++ b/src/ui/EditModal.ts @@ -5,6 +5,7 @@ import { DatabaseDetails, ObsidianSettingTab } from "./settingTabs"; import { i18nConfig } from "../lang/I18n"; export class EditModal extends SettingModal { + propertyLines: Setting[] = []; // Store all property line settings [key: string]: any; // Index signature dataTemp: Record = { databaseFormatTemp: '', @@ -132,6 +133,8 @@ export class EditModal extends SettingModal { .onClick(async () => { this.dataTemp.savedTempInd = true; this.dataTemp.savedTemp = true; + console.log(this.dataTemp); + console.log(this.dataPrev); this.close(); }); } @@ -321,38 +324,17 @@ export class EditModal extends SettingModal { .setTooltip("Delete") .setIcon("trash") .onClick(() => { + console.log('Deleting property', properties[propertyIndex]); this.deleteProperty(propertyIndex, properties); }); }); } + + this.propertyLines.push(propertyLine); + this.updatePropertyLines(); + } - createPropertyLine(containerEl: HTMLElement, properties: customProperty[]) { - super.createPropertyLine(containerEl, properties); - } - - deleteProperty(propertyIndex: number, properties: customProperty[]) { - let actualIndex = properties.findIndex(p => p.index === propertyIndex); - if (actualIndex > 0) { - properties.splice(actualIndex, 1); - this.propertyLines[actualIndex].settingEl.remove(); - this.propertyLines.splice(actualIndex, 1); - - properties.forEach((prop, idx) => { - prop.index = idx; - }); - - this.updatePropertyLines(); - } - } - - updatePropertyLines() { - this.propertyLines.forEach((line, idx) => { - line.setName(idx === 0 ? i18nConfig.CustomPropertyFirstColumn : `${i18nConfig.CustomProperty} ${idx}`); - }); - } - - createStyleDiv(className: string, commandValue: boolean = false, parentEl: HTMLElement): HTMLDivElement { return super.createStyleDiv(className, commandValue, parentEl); } diff --git a/src/ui/settingModal.ts b/src/ui/settingModal.ts index 2e8c217..754ef67 100644 --- a/src/ui/settingModal.ts +++ b/src/ui/settingModal.ts @@ -1,19 +1,22 @@ import { Modal, Setting, - PluginSettingTab, ButtonComponent, App } from 'obsidian'; -import {i18nConfig} from "../lang/I18n"; +import { i18nConfig } from "../lang/I18n"; import ObsidianSyncNotionPlugin from "../main"; -import {DatabaseDetails, ObsidianSettingTab} from "./settingTabs"; -// import {CustomModal} from "./CustomModal"; +import { DatabaseDetails, ObsidianSettingTab } from "./settingTabs"; +export interface customProperty { + customName: string; + customType: string; + index: number; +} export class SettingModal extends Modal { propertyLines: Setting[] = []; // Store all property line settings - properties: { customName: string, customType: string , index: number}[] = []; // Array to store property values and types + properties: customProperty[] = []; // Array to store property values and types [key: string]: any; // Index signature data: Record = { databaseFormat: 'none', @@ -56,7 +59,7 @@ export class SettingModal extends Modal { this.titleEl.setText('Add new database'); // create the dropdown button to select the database format - let {contentEl} = this; + let { contentEl } = this; contentEl.empty(); const settingDiv = contentEl.createDiv('setting-div'); @@ -80,7 +83,7 @@ export class SettingModal extends Modal { }); // Initialize content based on the current dropdown value - (this.data.saved) ? this.updateContentBasedOnSelection(this.data.databaseFormat, nextTabs) : this.updateContentBasedOnSelection(this.data.databaseFormat, nextTabs); + (this.data.saved) ? this.updateContentBasedOnSelection(this.data.databaseFormat, nextTabs) : this.updateContentBasedOnSelection(this.plugin.settings.databaseFormat, nextTabs); }); @@ -89,26 +92,26 @@ export class SettingModal extends Modal { let footerEl = contentEl.createDiv('save-button'); let saveButton = new Setting(footerEl) saveButton.addButton((button: ButtonComponent) => { - return button - .setTooltip('Save') - .setIcon('checkmark') - .onClick(async () => { - this.data.saved = true; - this.data.customProperties = this.properties; - this.close(); - }); - } + return button + .setTooltip('Save') + .setIcon('checkmark') + .onClick(async () => { + this.data.saved = true; + this.data.customProperties = this.properties; + this.close(); + }); + } ); saveButton.addExtraButton((button) => { - return button - .setTooltip('Cancel') - .setIcon('cross') - .onClick(() => { - this.data.saved = false; - this.data.customProperties = this.properties; - this.close(); - }); - } + return button + .setTooltip('Cancel') + .setIcon('cross') + .onClick(() => { + this.data.saved = false; + // this.data.customProperties = this.properties; + this.close(); + }); + } ); } @@ -118,7 +121,7 @@ export class SettingModal extends Modal { // Generate content based on the selected value if (value === 'general') { - nextTabs.createEl('h3', {text: i18nConfig.NotionGeneralSettingHeader}); + nextTabs.createEl('h3', { text: i18nConfig.NotionGeneralSettingHeader }); // add full name this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.data.databaseFullName, 'data', 'databaseFullName') @@ -139,7 +142,6 @@ export class SettingModal extends Modal { .setValue(this.data.customTitleButton) .onChange(async (value) => { this.data.customTitleButton = value; - this.updateSettingEl(CustomNameEl, value) }) @@ -160,7 +162,7 @@ export class SettingModal extends Modal { } 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.data.databaseFullName, 'data', 'databaseFullName') @@ -177,7 +179,7 @@ export class SettingModal extends Modal { } else if (value === 'custom') { - nextTabs.createEl('h3', {text: i18nConfig.NotionCustomSettingHeader}); + nextTabs.createEl('h3', { text: i18nConfig.NotionCustomSettingHeader }); // add full name this.createSettingEl(nextTabs, i18nConfig.databaseFullName, i18nConfig.databaseFullNameDesc, 'text', i18nConfig.databaseFullNameText, this.data.databaseFullName, 'data', 'databaseFullName') @@ -196,17 +198,16 @@ export class SettingModal extends Modal { .setName(i18nConfig.NotionCustomValues) .setDesc(i18nConfig.NotionCustomValuesDesc) .addButton((button: ButtonComponent) => { - return button - .setTooltip('Add new property') - .setIcon('plus') - .onClick(async () => { - const customTabs = nextTabs.createDiv("custom-tabs"); - this.createPropertyLine(customTabs); - }); - } + return button + .setTooltip('Add one more property') + .setButtonText('Add New Property') + .onClick(async () => { + const customTabs = nextTabs.createDiv("custom-tabs"); + this.createPropertyLine(customTabs, this.properties); + }); + } ); } - } @@ -215,23 +216,22 @@ export class SettingModal extends Modal { this.display() } - createPropertyLine(containerEl: HTMLElement): void { - const propertyIndex = this.properties.length; + createPropertyLine(containerEl: HTMLElement, properties: customProperty[]): void { + const propertyIndex = properties.length; - this.properties.push({customName: "", customType: "", index: propertyIndex}); - - console.log(this.properties[propertyIndex].index); + properties.push({ customName: "", customType: "", index: propertyIndex }); 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 = this.properties.findIndex(p => p.index === propertyIndex); + let actualIndex = properties.findIndex(p => p.index === propertyIndex); if (actualIndex !== -1) { - this.properties[actualIndex].customName = value; + properties[actualIndex].customName = value; } }); }); @@ -258,8 +258,7 @@ export class SettingModal extends Modal { // 'last_edited_by': 'Last Edited By', }; - // Use a reference to the current property object - const currentProperty = this.properties[propertyIndex]; + const currentProperty = properties[propertyIndex]; if (propertyIndex === 0) { dropdown.addOption("title", "Title"); @@ -273,7 +272,7 @@ export class SettingModal extends Modal { if (currentProperty) { currentProperty.customType = value; // Retrieve the index of currentProperty from the properties array - const updatedIndex = this.properties.findIndex(p => p === currentProperty); + 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."); @@ -288,32 +287,29 @@ export class SettingModal extends Modal { .setTooltip("Delete") .setIcon("trash") .onClick(() => { - this.deleteProperty(propertyIndex); + this.deleteProperty(propertyIndex, properties); }); }); } this.propertyLines.push(propertyLine); + this.updatePropertyLines(); // Ensure property lines are updated after creation } - deleteProperty(propertyIndex: number) { - let actualIndex = this.properties.findIndex(p => p.index === propertyIndex); + deleteProperty(propertyIndex: number, properties: customProperty[]): void { + let actualIndex = properties.findIndex(p => p.index === propertyIndex); if (actualIndex !== -1) { - this.properties.splice(actualIndex, 1); - this.propertyLines[actualIndex].settingEl.remove(); - this.propertyLines.splice(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 - this.properties.forEach((prop, idx) => { + properties.forEach((prop, idx) => { prop.index = idx; }); this.updatePropertyLines(); - - console.log("Updated indices after deletion:"); - this.properties.forEach((prop, idx) => { - console.log(`Index ${idx}: ${prop.index}`); - }); } } diff --git a/src/ui/settingTabs.ts b/src/ui/settingTabs.ts index d4316fc..3ea7dc9 100644 --- a/src/ui/settingTabs.ts +++ b/src/ui/settingTabs.ts @@ -88,9 +88,6 @@ export class ObsidianSettingTab extends PluginSettingTab { this.createSettingEl(containerEl, i18nConfig.NotionLinkDisplay, i18nConfig.NotionLinkDisplayDesc, 'toggle', i18nConfig.NotionLinkDisplay, this.plugin.settings.NotionLinkDisplay, 'NotionLinkDisplay') - // TODO: add toggle to enable or disable link display - - // add new button new Setting(containerEl) @@ -275,7 +272,7 @@ export class ObsidianSettingTab extends PluginSettingTab { } } - modal.open(); + modal.open (); }); }); @@ -291,6 +288,8 @@ export class ObsidianSettingTab extends PluginSettingTab { if (modal.data.deleted) { this.plugin.deleteDatabaseDetails(dbDetails); + console.log(dbDetails.fullName + " deleted"); + this.plugin.commands.updateCommand(); this.display() From 9c93e38aff1844e21c7e0f25c345f5abf6a5d53b Mon Sep 17 00:00:00 2001 From: Jiaxin Peng Date: Thu, 4 Jul 2024 20:51:07 +0100 Subject: [PATCH 14/14] reformat code and update readme file --- CHANGELOG.md | 28 +- README.md | 201 +-------------- src/commands/FuzzySuggester.ts | 2 +- src/commands/NotionCommands.ts | 6 +- src/main.ts | 42 +-- src/ui/DeleteModal.ts | 10 +- src/ui/EditModal.ts | 10 +- src/ui/PreviewModal.ts | 35 ++- src/ui/settingTabs.ts | 243 +++++++++--------- src/upload/updateYaml.ts | 10 +- src/upload/uploadCommand.ts | 34 +-- .../BaseUpload2NotionGeneral.ts | 24 +- .../upload_general/Upload2NotionGeneral.ts | 4 +- .../upload_general/getMarkdownGeneral.ts | 6 +- .../upload_next/BaseUpload2NotionNext.ts | 10 +- src/upload/upload_next/Upload2NotionNext.ts | 142 +++++----- src/upload/upload_next/getMarkdownNext.ts | 2 +- .../upoload_custom/BaseUpload2NotionCustom.ts | 28 +- .../upoload_custom/Upload2NotionCustom.ts | 20 +- .../upoload_custom/getMarkdownCustom.ts | 6 +- 20 files changed, 352 insertions(+), 511 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e98b570..5d2e100 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,25 @@ -- Update NotionNext function that - - `tags`, `titleicon`, `slug` and `summary` are now optional. You can remove them from the frontmatter if you don't need them. +## 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`。 -- 更新 NotionNext 同步功能 - - `tags`, `titleicon`, `slug` 和 `summary` 现在不是必选项了。你可以从你的模板中删除这些字段。 + +## 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) diff --git a/README.md b/README.md index fbcfe56..c4a72b2 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ [//]: # ([![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.** @@ -16,11 +16,18 @@ ## 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 支持一键多数据库上传 -- [x] Support custom properties for Notion General database. 支持自定义属性 -- [x] Support preview for database details in plugin settings. 支持预览数据库详情 -- [x] Support edit for database details in plugin settings. 支持编辑数据库详情 +- [x] ~~Support custom properties for Notion General database. 支持自定义属性~~ +- [x] ~~Support preview for database details in plugin settings. 支持预览数据库详情~~ +- [x] ~~Support edit for database details in plugin settings. 支持编辑数据库详情~~ + +## 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.3.0版本,你需要重新创建自定义数据库。新版本有一个新的数据库结构,旧的数据库结构无法构建索引。** ## How to use You need seven steps to use this plugin in your Obsidian. @@ -78,50 +85,10 @@ tags: - web # add more tags if you want --- ``` -
Update -### 2.2.5 - -- Update NotionNext function that - - `tags`, `titleicon`, `slug` and `summary` are now optional. You can remove them from the frontmatter if you don't need them. - - -### 2.2.3 - -- Fix a bug that 'text' property cannot be synchronized. 修复了一个无法同步'text'属性的bug。 - -### 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) +![](https://minioapi.pjx.ac.cn/img1/2024/07/7a1550aefd71175c981077ce46d03c87.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) +![](https://minioapi.pjx.ac.cn/img1/2024/07/9599d77116afad065d2e31129942acc7.png) --- @@ -133,146 +100,6 @@ Thus, based on the [original author's work](https://github.com/EasyChris/obsidia --- -
Archive Update - -### 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. - - - -### 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. - -
-
Previous How to Use ### Precautions diff --git a/src/commands/FuzzySuggester.ts b/src/commands/FuzzySuggester.ts index 34d2de0..7b5ea5d 100644 --- a/src/commands/FuzzySuggester.ts +++ b/src/commands/FuzzySuggester.ts @@ -11,7 +11,7 @@ export interface DatabaseList { } -export class FuzzySuggester extends FuzzySuggestModal{ +export class FuzzySuggester extends FuzzySuggestModal { private plugin: MyPlugin; private data: DatabaseList[]; private callback: any; diff --git a/src/commands/NotionCommands.ts b/src/commands/NotionCommands.ts index 1b8a767..0953dd0 100644 --- a/src/commands/NotionCommands.ts +++ b/src/commands/NotionCommands.ts @@ -1,9 +1,9 @@ import { i18nConfig } from "src/lang/I18n"; -import {Editor, MarkdownView, setTooltip} from "obsidian"; +import { Editor, MarkdownView, setTooltip } from "obsidian"; 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 {DatabaseDetails} from "../ui/settingTabs"; +import { DatabaseDetails } from "../ui/settingTabs"; interface Command { diff --git a/src/main.ts b/src/main.ts index 099a7f4..4938e18 100644 --- a/src/main.ts +++ b/src/main.ts @@ -55,33 +55,33 @@ export default class ObsidianSyncNotionPlugin extends Plugin { await this.saveData(this.settings); } - async addDatabaseDetails(dbDetails: DatabaseDetails) { - this.settings.databaseDetails = { - ...this.settings.databaseDetails, - [dbDetails.abName]: dbDetails, - }; + async addDatabaseDetails(dbDetails: DatabaseDetails) { + this.settings.databaseDetails = { + ...this.settings.databaseDetails, + [dbDetails.abName]: dbDetails, + }; - await this.saveSettings(); - } + await this.saveSettings(); + } - async deleteDatabaseDetails(dbDetails: DatabaseDetails) { - delete this.settings.databaseDetails[dbDetails.abName]; + async deleteDatabaseDetails(dbDetails: DatabaseDetails) { + delete this.settings.databaseDetails[dbDetails.abName]; - await this.saveSettings(); - } + await this.saveSettings(); + } - async updateDatabaseDetails(dbDetails: DatabaseDetails) { - // delete the old database details - delete this.settings.databaseDetails[dbDetails.abName]; + async updateDatabaseDetails(dbDetails: DatabaseDetails) { + // delete the old database details + delete this.settings.databaseDetails[dbDetails.abName]; - this.settings.databaseDetails = { - ...this.settings.databaseDetails, - [dbDetails.abName]: dbDetails, - }; + this.settings.databaseDetails = { + ...this.settings.databaseDetails, + [dbDetails.abName]: dbDetails, + }; + + await this.saveSettings(); + } - await this.saveSettings(); - } - } diff --git a/src/ui/DeleteModal.ts b/src/ui/DeleteModal.ts index 8f03d24..47eb678 100644 --- a/src/ui/DeleteModal.ts +++ b/src/ui/DeleteModal.ts @@ -1,5 +1,5 @@ -import {App, ButtonComponent, Modal, Setting} from "obsidian"; -import {DatabaseDetails, ObsidianSettingTab} from "./settingTabs"; +import { App, ButtonComponent, Modal, Setting } from "obsidian"; +import { DatabaseDetails, ObsidianSettingTab } from "./settingTabs"; import ObsidianSyncNotionPlugin from "../main"; export class DeleteModal extends Modal { @@ -21,12 +21,12 @@ export class DeleteModal extends Modal { this.containerEl.addClass("delete-modal"); this.titleEl.setText('Delete Database'); - let {contentEl} = this; + 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 +')'}); + 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 diff --git a/src/ui/EditModal.ts b/src/ui/EditModal.ts index 8a562f3..e69300e 100644 --- a/src/ui/EditModal.ts +++ b/src/ui/EditModal.ts @@ -1,4 +1,4 @@ -import { App, ButtonComponent, Modal, Setting } from "obsidian"; +import { App, ButtonComponent, Setting } from "obsidian"; import { customProperty, SettingModal } from "./settingModal"; import ObsidianSyncNotionPlugin from "../main"; import { DatabaseDetails, ObsidianSettingTab } from "./settingTabs"; @@ -133,8 +133,8 @@ export class EditModal extends SettingModal { .onClick(async () => { this.dataTemp.savedTempInd = true; this.dataTemp.savedTemp = true; - console.log(this.dataTemp); - console.log(this.dataPrev); + // console.log(this.dataTemp); + // console.log(this.dataPrev); this.close(); }); } @@ -144,8 +144,8 @@ export class EditModal extends SettingModal { .setTooltip('Cancel') .setIcon('cross') .onClick(() => { - console.log(this.dataTemp); - console.log(this.dataPrev); + // console.log(this.dataTemp); + // console.log(this.dataPrev); this.close(); }); } diff --git a/src/ui/PreviewModal.ts b/src/ui/PreviewModal.ts index d7c059a..d311411 100644 --- a/src/ui/PreviewModal.ts +++ b/src/ui/PreviewModal.ts @@ -1,15 +1,15 @@ -import {App, ExtraButtonComponent, Modal, Notice, Setting} from "obsidian"; +import { App, ExtraButtonComponent, Modal, Notice, Setting } from "obsidian"; import ObsidianSyncNotionPlugin from "../main"; -import {DatabaseDetails, ObsidianSettingTab} from "./settingTabs"; -import {customProperty} from "./settingModal"; -import {i18nConfig} from "../lang/I18n"; +import { DatabaseDetails, ObsidianSettingTab } from "./settingTabs"; +import { customProperty } from "./settingModal"; +import { i18nConfig } from "../lang/I18n"; export class PreviewModal extends Modal { plugin: ObsidianSyncNotionPlugin; settingTab: ObsidianSettingTab; dbDetails: DatabaseDetails; - constructor(app:App, plugin: ObsidianSyncNotionPlugin, settingTab: ObsidianSettingTab, dbDetails: DatabaseDetails) { + constructor(app: App, plugin: ObsidianSyncNotionPlugin, settingTab: ObsidianSettingTab, dbDetails: DatabaseDetails) { super(app); this.plugin = plugin; this.settingTab = settingTab; @@ -26,25 +26,25 @@ export class PreviewModal extends Modal { const previewEl = contentEl.createDiv('preview-content') const dbFormatEl = new Setting(previewEl) - dbFormatEl + dbFormatEl .setName('Database Format') - .addText(text => text - .setValue(this.dbDetails.format) - .setDisabled(true)); + .addText(text => text + .setValue(this.dbDetails.format) + .setDisabled(true)); const dbFullEl = new Setting(previewEl) - dbFullEl + dbFullEl .setName('Database Full Name') - .addText(text => text - .setValue(this.dbDetails.fullName) - .setDisabled(true)); + .addText(text => text + .setValue(this.dbDetails.fullName) + .setDisabled(true)); const dbAbbrEl = new Setting(previewEl) - dbAbbrEl + dbAbbrEl .setName('Database Abbreviate Name') - .addText(text => text - .setValue(this.dbDetails.abName) - .setDisabled(true)); + .addText(text => text + .setValue(this.dbDetails.abName) + .setDisabled(true)); // .controlEl.createEl('p', { text: this.dbDetails.abName }) // Setting for toggle and copy buttons @@ -124,7 +124,6 @@ export class PreviewModal extends Modal { const customPrv = previewEl.createDiv("custom-tabs"); - this.previewPropertyLine(previewEl, this.dbDetails.customProperties); } diff --git a/src/ui/settingTabs.ts b/src/ui/settingTabs.ts index 3ea7dc9..dc390fa 100644 --- a/src/ui/settingTabs.ts +++ b/src/ui/settingTabs.ts @@ -1,31 +1,29 @@ -import {App, ButtonComponent, Modal, PluginSettingTab, Setting} from "obsidian"; -import {i18nConfig} from "../lang/I18n"; +import { App, ButtonComponent, PluginSettingTab, Setting } from "obsidian"; +import { i18nConfig } from "../lang/I18n"; import ObsidianSyncNotionPlugin from "../main"; -import {SettingModal} from "./settingModal"; -import {set} from "yaml/dist/schema/yaml-1.1/set"; -import {PreviewModal} from "./PreviewModal"; -import {EditModal} from "./EditModal"; -import {DeleteModal} from "./DeleteModal"; +import { SettingModal } from "./settingModal"; +import { PreviewModal } from "./PreviewModal"; +import { EditModal } from "./EditModal"; +import { DeleteModal } from "./DeleteModal"; export interface PluginSettings { - NextButton: boolean; - notionAPINext: string; - databaseIDNext: string; - bannerUrl: string; - notionUser: string; - NotionLinkDisplay: boolean; - proxy: string; - GeneralButton: boolean; - tagButton: boolean; - customTitleButton: boolean; - customTitleName: string; - notionAPIGeneral: string; - databaseIDGeneral: string; - CustomButton: boolean; - CustomValues: string; - notionAPICustom: string; - databaseIDCustom: string; - [key: string]: any; + NextButton: boolean; + notionAPINext: string; + databaseIDNext: string; + bannerUrl: string; + notionUser: string; + proxy: string; + GeneralButton: boolean; + tagButton: boolean; + customTitleButton: boolean; + customTitleName: string; + notionAPIGeneral: string; + databaseIDGeneral: string; + CustomButton: boolean; + CustomValues: string; + notionAPICustom: string; + databaseIDCustom: string; + [key: string]: any; databaseDetails: Record } @@ -38,58 +36,54 @@ export interface DatabaseDetails { tagButton: boolean; customTitleButton: boolean; customTitleName: string; - customProperties:{ customName: string, customType: string, index: number}[]; + customProperties: { customName: string, customType: string, index: number }[]; // customValues: string; saved: boolean; } export const DEFAULT_SETTINGS: PluginSettings = { - NextButton: true, - notionAPINext: "", - databaseIDNext: "", - bannerUrl: "", - notionUser: "", - NotionLinkDisplay: true, - proxy: "", - GeneralButton: true, - tagButton: true, - customTitleButton: false, - customTitleName: "", - notionAPIGeneral: "", - databaseIDGeneral: "", - CustomButton: false, - CustomValues: "", - notionAPICustom: "", - databaseIDCustom: "", + NextButton: true, + notionAPINext: "", + databaseIDNext: "", + bannerUrl: "", + notionUser: "", + proxy: "", + GeneralButton: true, + tagButton: true, + customTitleButton: false, + customTitleName: "", + notionAPIGeneral: "", + databaseIDGeneral: "", + CustomButton: false, + CustomValues: "", + notionAPICustom: "", + databaseIDCustom: "", databaseDetails: {}, }; export class ObsidianSettingTab extends PluginSettingTab { - plugin: ObsidianSyncNotionPlugin; + plugin: ObsidianSyncNotionPlugin; databaseEl: HTMLDivElement; - constructor(app: App, plugin: ObsidianSyncNotionPlugin) { - super(app, plugin); - this.plugin = plugin; - } + constructor(app: App, plugin: ObsidianSyncNotionPlugin) { + super(app, plugin); + this.plugin = plugin; + } - display(): void { - const { containerEl } = this; + display(): void { + const { containerEl } = this; - containerEl.empty(); + containerEl.empty(); - // General Settings - containerEl.createEl('h2', { text: i18nConfig.GeneralSetting }); + // General Settings + containerEl.createEl('h2', { text: i18nConfig.GeneralSetting }); - this.createSettingEl(containerEl, i18nConfig.BannerUrl, i18nConfig.BannerUrlDesc, 'text', i18nConfig.BannerUrlText, this.plugin.settings.bannerUrl, 'bannerUrl') + this.createSettingEl(containerEl, i18nConfig.BannerUrl, i18nConfig.BannerUrlDesc, 'text', i18nConfig.BannerUrlText, this.plugin.settings.bannerUrl, 'bannerUrl') - this.createSettingEl(containerEl, i18nConfig.NotionUser, i18nConfig.NotionUserDesc, 'text', i18nConfig.NotionUserText, this.plugin.settings.notionUser, 'notionUser') - - this.createSettingEl(containerEl, i18nConfig.NotionLinkDisplay, i18nConfig.NotionLinkDisplayDesc, 'toggle', i18nConfig.NotionLinkDisplay, this.plugin.settings.NotionLinkDisplay, 'NotionLinkDisplay') + this.createSettingEl(containerEl, i18nConfig.NotionUser, i18nConfig.NotionUserDesc, 'text', i18nConfig.NotionUserText, this.plugin.settings.notionUser, 'notionUser') // add new button - new Setting(containerEl) .setName("Add New Database") .setDesc("Add New Database") @@ -129,73 +123,74 @@ export class ObsidianSettingTab extends PluginSettingTab { }); // 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'); // list all created database this.showDatabase(); - } + } - // create a function to create a div with a style for pop over elements - public createStyleDiv(className: string, commandValue: boolean = false) { - return this.containerEl.createDiv(className, (div) => { - this.updateSettingEl(div, commandValue); - }); - } - // update the setting display style in the setting tab - public updateSettingEl(element: HTMLElement, commandValue: boolean) { - element.style.borderTop = commandValue ? "1px solid var(--background-modifier-border)" : "none"; - element.style.paddingTop = commandValue ? "0.75em" : "0"; - element.style.display = commandValue ? "block" : "none"; - element.style.alignItems = "center"; - } + // create a function to create a div with a style for pop over elements + // public createStyleDiv(className: string, commandValue: boolean = false) { + // return this.containerEl.createDiv(className, (div) => { + // this.updateSettingEl(div, commandValue); + // }); + // } - // function to add one setting element in the setting tab. - public createSettingEl(containerEl: HTMLElement, name: string, desc: string, type: string, placeholder: string, holderValue: any, settingsKey: string) { - if (type === 'password') { - return new Setting(containerEl) - .setName(name) - .setDesc(desc) - .addText((text) => { - text.inputEl.type = type; - return text - .setPlaceholder(placeholder) - .setValue(holderValue) - .onChange(async (value) => { - this.plugin.settings[settingsKey] = value; // Update the plugin settings directly - await this.plugin.saveSettings(); - }) - }); - } else if (type === 'toggle') { - return new Setting(containerEl) - .setName(name) - .setDesc(desc) - .addToggle((toggle) => - toggle - .setValue(holderValue) - .onChange(async (value) => { - this.plugin.settings[settingsKey] = value; // Update the plugin settings directly - await this.plugin.saveSettings(); - await this.plugin.commands.updateCommand(); - }) - ); - } else if (type === 'text') { - return new Setting(containerEl) - .setName(name) - .setDesc(desc) - .addText((text) => - text - .setPlaceholder(placeholder) - .setValue(holderValue) - .onChange(async (value) => { - this.plugin.settings[settingsKey] = value; // Update the plugin settings directly - await this.plugin.saveSettings(); - await this.plugin.commands.updateCommand(); - }) - ); - } - } + // update the setting display style in the setting tab + public updateSettingEl(element: HTMLElement, commandValue: boolean) { + element.style.borderTop = commandValue ? "1px solid var(--background-modifier-border)" : "none"; + element.style.paddingTop = commandValue ? "0.75em" : "0"; + element.style.display = commandValue ? "block" : "none"; + element.style.alignItems = "center"; + } + + // function to add one setting element in the setting tab. + public createSettingEl(containerEl: HTMLElement, name: string, desc: string, type: string, placeholder: string, holderValue: any, settingsKey: string) { + if (type === 'password') { + return new Setting(containerEl) + .setName(name) + .setDesc(desc) + .addText((text) => { + text.inputEl.type = type; + return text + .setPlaceholder(placeholder) + .setValue(holderValue) + .onChange(async (value) => { + this.plugin.settings[settingsKey] = value; // Update the plugin settings directly + await this.plugin.saveSettings(); + }) + }); + } else if (type === 'toggle') { + return new Setting(containerEl) + .setName(name) + .setDesc(desc) + .addToggle((toggle) => + toggle + .setValue(holderValue) + .onChange(async (value) => { + this.plugin.settings[settingsKey] = value; // Update the plugin settings directly + await this.plugin.saveSettings(); + await this.plugin.commands.updateCommand(); + }) + ); + } else if (type === 'text') { + return new Setting(containerEl) + .setName(name) + .setDesc(desc) + .addText((text) => + text + .setPlaceholder(placeholder) + .setValue(holderValue) + .onChange(async (value) => { + this.plugin.settings[settingsKey] = value; // Update the plugin settings directly + await this.plugin.saveSettings(); + await this.plugin.commands.updateCommand(); + }) + ); + } + } // function to show all the database details showDatabase() { @@ -211,8 +206,8 @@ export class ObsidianSettingTab extends PluginSettingTab { .setDesc(dbDetails.format) - // add a button for preview data - settingEl + // add a button for preview data + settingEl .addButton((button: ButtonComponent): ButtonComponent => { return button .setTooltip("Preview Database") @@ -224,8 +219,8 @@ export class ObsidianSettingTab extends PluginSettingTab { }); }); - // add a button for edit data - settingEl + // add a button for edit data + settingEl .addButton((button: ButtonComponent): ButtonComponent => { return button .setTooltip("Edit Database") @@ -272,11 +267,11 @@ export class ObsidianSettingTab extends PluginSettingTab { } } - modal.open (); + modal.open(); }); }); - settingEl + settingEl .addButton((button: ButtonComponent): ButtonComponent => { return button .setTooltip("Delete Database") diff --git a/src/upload/updateYaml.ts b/src/upload/updateYaml.ts index 219254d..10d9e83 100644 --- a/src/upload/updateYaml.ts +++ b/src/upload/updateYaml.ts @@ -1,6 +1,6 @@ import { App, Notice, TFile } from "obsidian"; import ObsidianSyncNotionPlugin from "../main"; -import {DatabaseDetails} from "../ui/settingTabs"; +import { DatabaseDetails } from "../ui/settingTabs"; export async function updateYamlInfo( yamlContent: string, @@ -8,14 +8,14 @@ export async function updateYamlInfo( res: any, app: App, plugin: ObsidianSyncNotionPlugin, - dbDetails: DatabaseDetails, + dbDetails: DatabaseDetails, ) { let { url, id } = res.json // replace www to notionID const { notionUser } = plugin.settings; - const { abName } = dbDetails - const notionIDKey = `NotionID-${abName}`; - const linkKey = `link-${abName}`; + const { abName } = dbDetails + const notionIDKey = `NotionID-${abName}`; + const linkKey = `link-${abName}`; if (notionUser !== "") { // replace url str "www" to notionID diff --git a/src/upload/uploadCommand.ts b/src/upload/uploadCommand.ts index 78c5be0..9f9bc3b 100644 --- a/src/upload/uploadCommand.ts +++ b/src/upload/uploadCommand.ts @@ -1,13 +1,13 @@ -import {i18nConfig} from "../lang/I18n"; -import {App, Notice} from "obsidian"; -import {Upload2NotionNext} from "./upload_next/Upload2NotionNext"; -import {Upload2NotionGeneral} from "./upload_general/Upload2NotionGeneral"; -import {Upload2NotionCustom} from "./upoload_custom/Upload2NotionCustom"; -import {DatabaseDetails, PluginSettings} from "../ui/settingTabs"; +import { i18nConfig } from "../lang/I18n"; +import { App, Notice } from "obsidian"; +import { Upload2NotionNext } from "./upload_next/Upload2NotionNext"; +import { Upload2NotionGeneral } from "./upload_general/Upload2NotionGeneral"; +import { Upload2NotionCustom } from "./upoload_custom/Upload2NotionCustom"; +import { DatabaseDetails, PluginSettings } from "../ui/settingTabs"; import ObsidianSyncNotionPlugin from "../main"; -import {getNowFileMarkdownContentNext} from "./upload_next/getMarkdownNext"; -import {getNowFileMarkdownContentGeneral} from "./upload_general/getMarkdownGeneral"; -import {getNowFileMarkdownContentCustom} from "./upoload_custom/getMarkdownCustom"; +import { getNowFileMarkdownContentNext } from "./upload_next/getMarkdownNext"; +import { getNowFileMarkdownContentGeneral } from "./upload_general/getMarkdownGeneral"; +import { getNowFileMarkdownContentCustom } from "./upoload_custom/getMarkdownCustom"; export async function uploadCommandNext( plugin: ObsidianSyncNotionPlugin, @@ -16,7 +16,7 @@ export async function uploadCommandNext( app: App, ) { - const {notionAPI, databaseID} = dbDetails; + const { notionAPI, databaseID } = dbDetails; // Check if NNon exists // if (NNon === undefined) { @@ -49,7 +49,7 @@ export async function uploadCommandNext( } = await getNowFileMarkdownContentNext(app, settings) if (markDownData) { - const {basename} = nowFile; + const { basename } = nowFile; 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); @@ -70,7 +70,7 @@ export async function uploadCommandGeneral( app: App, ) { - const {notionAPI, databaseID} = dbDetails; + const { notionAPI, databaseID } = dbDetails; // Check if the user has set up the Notion API and database ID if (notionAPI === "" || databaseID === "") { @@ -79,10 +79,10 @@ export async function uploadCommandGeneral( return; } - const {markDownData, nowFile, cover, tags} = await getNowFileMarkdownContentGeneral(app, settings) + const { markDownData, nowFile, cover, tags } = await getNowFileMarkdownContentGeneral(app, settings) if (markDownData) { - const {basename} = nowFile; + const { basename } = nowFile; const upload = new Upload2NotionGeneral(plugin, dbDetails); const res = await upload.syncMarkdownToNotionGeneral(basename, cover, tags, markDownData, nowFile, this.app); @@ -104,7 +104,7 @@ export async function uploadCommandCustom( app: App, ) { - const {notionAPI, databaseID} = settings; + const { notionAPI, databaseID } = settings; // Check if the user has set up the Notion API and database ID if (notionAPI === "" || databaseID === "") { @@ -113,10 +113,10 @@ export async function uploadCommandCustom( return; } - const {markDownData, nowFile, cover, customValues} = await getNowFileMarkdownContentCustom(app, dbDetails) + const { markDownData, nowFile, cover, customValues } = await getNowFileMarkdownContentCustom(app, dbDetails) if (markDownData) { - const { basename} = nowFile; + const { basename } = nowFile; const upload = new Upload2NotionCustom(plugin, dbDetails); const res = await upload.syncMarkdownToNotionCustom(cover, customValues, markDownData, nowFile, this.app); diff --git a/src/upload/upload_general/BaseUpload2NotionGeneral.ts b/src/upload/upload_general/BaseUpload2NotionGeneral.ts index 7cca716..f40ddc1 100644 --- a/src/upload/upload_general/BaseUpload2NotionGeneral.ts +++ b/src/upload/upload_general/BaseUpload2NotionGeneral.ts @@ -1,10 +1,10 @@ -import {App, Notice, requestUrl, TFile} from "obsidian"; -import {Client} from '@notionhq/client'; -import {markdownToBlocks,} from "@tryfabric/martian"; +import { App, Notice, requestUrl, TFile } from "obsidian"; +import { Client } from '@notionhq/client'; +import { markdownToBlocks, } from "@tryfabric/martian"; import * as yamlFrontMatter from "yaml-front-matter"; // import * as yaml from "yaml" import MyPlugin from "src/main"; -import {DatabaseDetails} from "../../ui/settingTabs"; +import { DatabaseDetails } from "../../ui/settingTabs"; export class UploadBaseGeneral { plugin: MyPlugin; @@ -19,7 +19,7 @@ export class UploadBaseGeneral { async deletePage(notionID: string) { - const {notionAPI} = this.dbDetails + const { notionAPI } = this.dbDetails return requestUrl({ url: `https://api.notion.com/v1/blocks/${notionID}`, method: 'DELETE', @@ -33,15 +33,15 @@ export class UploadBaseGeneral { } async getDataBase(databaseID: string) { - const {notionAPI} = this.dbDetails + const { notionAPI } = this.dbDetails const response = await requestUrl({ - url: `https://api.notion.com/v1/databases/${databaseID}`, - method: 'GET', - headers: { - 'Authorization': 'Bearer ' + notionAPI, - 'Notion-Version': '2022-06-28', - } + url: `https://api.notion.com/v1/databases/${databaseID}`, + method: 'GET', + headers: { + 'Authorization': 'Bearer ' + notionAPI, + 'Notion-Version': '2022-06-28', } + } ) // Check if cover is present in the JSON response and then get the URL diff --git a/src/upload/upload_general/Upload2NotionGeneral.ts b/src/upload/upload_general/Upload2NotionGeneral.ts index 266f666..5bf590b 100644 --- a/src/upload/upload_general/Upload2NotionGeneral.ts +++ b/src/upload/upload_general/Upload2NotionGeneral.ts @@ -4,7 +4,7 @@ import { markdownToBlocks } from "@tryfabric/martian"; import * as yamlFrontMatter from "yaml-front-matter"; // import * as yaml from "yaml" import MyPlugin from "src/main"; -import {DatabaseDetails, PluginSettings} from "../../ui/settingTabs"; +import { DatabaseDetails, PluginSettings } from "../../ui/settingTabs"; import { UploadBaseGeneral } from "./BaseUpload2NotionGeneral"; import { updateYamlInfo } from "../updateYaml"; @@ -138,7 +138,7 @@ export class Upload2NotionGeneral extends UploadBaseGeneral { const file2Block = markdownToBlocks(__content, options); const frontmasster = app.metadataCache.getFileCache(nowFile)?.frontmatter; - const {abName} = this.dbDetails + const { abName } = this.dbDetails const notionIDKey = `NotionID-${abName}`; const notionID = frontmasster ? frontmasster[notionIDKey] : null; diff --git a/src/upload/upload_general/getMarkdownGeneral.ts b/src/upload/upload_general/getMarkdownGeneral.ts index a1f7379..5db5e91 100644 --- a/src/upload/upload_general/getMarkdownGeneral.ts +++ b/src/upload/upload_general/getMarkdownGeneral.ts @@ -1,6 +1,6 @@ -import {App, Notice} from "obsidian"; -import {i18nConfig} from "../../lang/I18n"; -import {PluginSettings} from "../../ui/settingTabs"; +import { App, Notice } from "obsidian"; +import { i18nConfig } from "../../lang/I18n"; +import { PluginSettings } from "../../ui/settingTabs"; export async function getNowFileMarkdownContentGeneral( app: App, diff --git a/src/upload/upload_next/BaseUpload2NotionNext.ts b/src/upload/upload_next/BaseUpload2NotionNext.ts index a67cf2b..69b3507 100644 --- a/src/upload/upload_next/BaseUpload2NotionNext.ts +++ b/src/upload/upload_next/BaseUpload2NotionNext.ts @@ -4,21 +4,21 @@ import { markdownToBlocks, } from "@tryfabric/martian"; import * as yamlFrontMatter from "yaml-front-matter"; // import * as yaml from "yaml" import MyPlugin from "src/main"; -import {DatabaseDetails} from "../../ui/settingTabs"; +import { DatabaseDetails } from "../../ui/settingTabs"; export class UploadBaseNext { plugin: MyPlugin; notion: Client; agent: any; - dbDetails: DatabaseDetails + dbDetails: DatabaseDetails constructor(plugin: MyPlugin, dbDetails: DatabaseDetails) { this.plugin = plugin; - this.dbDetails = dbDetails + this.dbDetails = dbDetails } async deletePage(notionID: string) { - const {notionAPI} = this.dbDetails + const { notionAPI } = this.dbDetails return requestUrl({ url: `https://api.notion.com/v1/blocks/${notionID}`, method: 'DELETE', @@ -32,7 +32,7 @@ export class UploadBaseNext { } async getDataBase(databaseID: string) { - const {notionAPI} = this.dbDetails + const { notionAPI } = this.dbDetails const response = await requestUrl({ url: `https://api.notion.com/v1/databases/${databaseID}`, diff --git a/src/upload/upload_next/Upload2NotionNext.ts b/src/upload/upload_next/Upload2NotionNext.ts index fb2a4ab..05856e6 100644 --- a/src/upload/upload_next/Upload2NotionNext.ts +++ b/src/upload/upload_next/Upload2NotionNext.ts @@ -5,17 +5,17 @@ import { markdownToBlocks, } from "@tryfabric/martian"; import * as yamlFrontMatter from "yaml-front-matter"; // import * as yaml from "yaml" import MyPlugin from "src/main"; -import {DatabaseDetails, PluginSettings} from "../../ui/settingTabs"; +import { DatabaseDetails, PluginSettings } from "../../ui/settingTabs"; 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 { settings: PluginSettings; - dbDetails: DatabaseDetails + dbDetails: DatabaseDetails constructor(plugin: MyPlugin, dbDetails: DatabaseDetails) { super(plugin, dbDetails); - this.dbDetails = dbDetails + this.dbDetails = dbDetails } // 因为需要解析notion的block进行对比,非常的麻烦, @@ -38,7 +38,7 @@ export class Upload2NotionNext extends UploadBaseNext { ) { await this.deletePage(notionID) - const { databaseID} = this.dbDetails + const { databaseID } = this.dbDetails const databaseCover = await this.getDataBase(databaseID) @@ -78,10 +78,10 @@ export class Upload2NotionNext extends UploadBaseNext { childArr: any ) { - const { - databaseID, - notionAPI - } = this.dbDetails + const { + databaseID, + notionAPI + } = this.dbDetails const bodyString: any = { @@ -141,47 +141,47 @@ export class Upload2NotionNext extends UploadBaseNext { children: childArr, } - // add tags - if (tags) { - bodyString.properties.tags = { - multi_select: tags.map(tag => { - return { "name": tag } - }) - } - } + // 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 title icon + if (emoji) { + bodyString.icon = { + emoji: emoji + } + } - // add slug - if (slug) { - bodyString.properties.slug = { - rich_text: [ - { - text: { - content: slug - } - } - ] - } - } + // 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 - } - } - ] - } - } + // check if summary is available + if (summary) { + bodyString.properties.summary = { + rich_text: [ + { + text: { + content: summary + } + } + ] + } + } @@ -238,41 +238,41 @@ export class Upload2NotionNext extends UploadBaseNext { nowFile: TFile, app: App, ): Promise { - const options = { - notionLimits: { - truncate: false, - } - } + const options = { + notionLimits: { + truncate: false, + } + } let res: any const yamlContent: any = yamlFrontMatter.loadFront(markdown); const __content = yamlContent.__content const file2Block = markdownToBlocks(__content, options); const frontmasster = app.metadataCache.getFileCache(nowFile)?.frontmatter - const {abName} = this.dbDetails - const notionIDKey = `NotionID-${abName}`; - const notionID = frontmasster ? frontmasster[notionIDKey] : null; + const { abName } = this.dbDetails + const notionIDKey = `NotionID-${abName}`; + const notionID = frontmasster ? frontmasster[notionIDKey] : null; - // increase the limits - // Motivated by https://github.com/tryfabric/martian/issues/51 - file2Block.forEach((block,index) => { - if ( - block.type === 'paragraph' && - block.paragraph.rich_text.length > LIMITS.RICH_TEXT_ARRAYS - ) { + // increase the limits + // Motivated by https://github.com/tryfabric/martian/issues/51 + file2Block.forEach((block, index) => { + if ( + block.type === 'paragraph' && + block.paragraph.rich_text.length > LIMITS.RICH_TEXT_ARRAYS + ) { - const newParagraphBlocks: any[] = [] - const chunk:any = [] - const richTextChunks = chunk(block.paragraph.rich_text, 100) + const newParagraphBlocks: any[] = [] + const chunk: any = [] + const richTextChunks = chunk(block.paragraph.rich_text, 100) - richTextChunks.forEach((chunk: any) => { - newParagraphBlocks.push(paragraph(chunk)) - }) + richTextChunks.forEach((chunk: any) => { + newParagraphBlocks.push(paragraph(chunk)) + }) - file2Block.splice(index, 1, ...newParagraphBlocks) + file2Block.splice(index, 1, ...newParagraphBlocks) - } - }) + } + }) if (notionID) { res = await this.updatePage( diff --git a/src/upload/upload_next/getMarkdownNext.ts b/src/upload/upload_next/getMarkdownNext.ts index f5f8875..cfd96ee 100644 --- a/src/upload/upload_next/getMarkdownNext.ts +++ b/src/upload/upload_next/getMarkdownNext.ts @@ -13,7 +13,7 @@ export async function getNowFileMarkdownContentNext( let type = ''; let slug = ''; let stats = ''; - let status = ''; + let status = ''; let category = ''; let summary = ''; let paword = ''; diff --git a/src/upload/upoload_custom/BaseUpload2NotionCustom.ts b/src/upload/upoload_custom/BaseUpload2NotionCustom.ts index 54ae60d..1a16b9b 100644 --- a/src/upload/upoload_custom/BaseUpload2NotionCustom.ts +++ b/src/upload/upoload_custom/BaseUpload2NotionCustom.ts @@ -1,24 +1,24 @@ -import {App, Notice, requestUrl, TFile} from "obsidian"; -import {Client} from '@notionhq/client'; -import {markdownToBlocks,} from "@tryfabric/martian"; +import { App, Notice, requestUrl, TFile } from "obsidian"; +import { Client } from '@notionhq/client'; +import { markdownToBlocks, } from "@tryfabric/martian"; import * as yamlFrontMatter from "yaml-front-matter"; // import * as yaml from "yaml" import MyPlugin from "src/main"; -import {DatabaseDetails} from "../../ui/settingTabs"; +import { DatabaseDetails } from "../../ui/settingTabs"; export class UploadBaseCustom { plugin: MyPlugin; notion: Client; agent: any; - dbDetails: DatabaseDetails + dbDetails: DatabaseDetails constructor(plugin: MyPlugin, dbDetails: DatabaseDetails) { this.plugin = plugin; - this.dbDetails = dbDetails + this.dbDetails = dbDetails } async deletePage(notionID: string) { - const {notionAPI} = this.dbDetails + const { notionAPI } = this.dbDetails return requestUrl({ url: `https://api.notion.com/v1/blocks/${notionID}`, method: 'DELETE', @@ -32,15 +32,15 @@ export class UploadBaseCustom { } async getDataBase(databaseID: string) { - const {notionAPI} = this.dbDetails + const { notionAPI } = this.dbDetails const response = await requestUrl({ - url: `https://api.notion.com/v1/databases/${databaseID}`, - method: 'GET', - headers: { - 'Authorization': 'Bearer ' + notionAPI, - 'Notion-Version': '2022-06-28', - } + url: `https://api.notion.com/v1/databases/${databaseID}`, + method: 'GET', + headers: { + 'Authorization': 'Bearer ' + notionAPI, + 'Notion-Version': '2022-06-28', } + } ) // Check if cover is present in the JSON response and then get the URL diff --git a/src/upload/upoload_custom/Upload2NotionCustom.ts b/src/upload/upoload_custom/Upload2NotionCustom.ts index 74d28d2..da03bf9 100644 --- a/src/upload/upoload_custom/Upload2NotionCustom.ts +++ b/src/upload/upoload_custom/Upload2NotionCustom.ts @@ -1,11 +1,11 @@ -import {App, Notice, requestUrl, TFile} from "obsidian"; -import {markdownToBlocks} from "@tryfabric/martian"; +import { App, Notice, requestUrl, TFile } from "obsidian"; +import { markdownToBlocks } from "@tryfabric/martian"; import * as yamlFrontMatter from "yaml-front-matter"; // import * as yaml from "yaml" import MyPlugin from "src/main"; -import {DatabaseDetails, PluginSettings} from "../../ui/settingTabs"; -import {updateYamlInfo} from "../updateYaml"; -import {UploadBaseCustom} from "./BaseUpload2NotionCustom"; +import { DatabaseDetails, PluginSettings } from "../../ui/settingTabs"; +import { updateYamlInfo } from "../updateYaml"; +import { UploadBaseCustom } from "./BaseUpload2NotionCustom"; export class Upload2NotionCustom extends UploadBaseCustom { settings: PluginSettings; @@ -26,7 +26,7 @@ export class Upload2NotionCustom extends UploadBaseCustom { ) { await this.deletePage(notionID); - const {databaseID} = this.dbDetails; + const { databaseID } = this.dbDetails; const databaseCover = await this.getDataBase( databaseID @@ -109,7 +109,7 @@ export class Upload2NotionCustom extends UploadBaseCustom { const file2Block = markdownToBlocks(__content, options); const frontmasster = app.metadataCache.getFileCache(nowFile)?.frontmatter; - const {abName} = this.dbDetails + const { abName } = this.dbDetails const notionIDKey = `NotionID-${abName}`; const notionID = frontmasster ? frontmasster[notionIDKey] : null; @@ -207,7 +207,7 @@ export class Upload2NotionCustom extends UploadBaseCustom { }; case "multi_select": 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 }], }; } } @@ -221,9 +221,9 @@ export class Upload2NotionCustom extends UploadBaseCustom { const properties: { [key: string]: any } = {}; // Only include custom properties that have values - customProperties.forEach(({customName, customType}) => { + customProperties.forEach(({ customName, customType }) => { if (customValues[customName] !== undefined) { - properties[customName] = this.buildPropertyObject(customName, customType, customValues); + properties[customName] = this.buildPropertyObject(customName, customType, customValues); } } ); diff --git a/src/upload/upoload_custom/getMarkdownCustom.ts b/src/upload/upoload_custom/getMarkdownCustom.ts index ed33655..75bd41b 100644 --- a/src/upload/upoload_custom/getMarkdownCustom.ts +++ b/src/upload/upoload_custom/getMarkdownCustom.ts @@ -1,6 +1,6 @@ -import {App, Notice} from "obsidian"; -import {i18nConfig} from "../../lang/I18n"; -import {DatabaseDetails} from "../../ui/settingTabs"; +import { App, Notice } from "obsidian"; +import { i18nConfig } from "../../lang/I18n"; +import { DatabaseDetails } from "../../ui/settingTabs"; export async function getNowFileMarkdownContentCustom( app: App,