mirror of
https://github.com/aleksejs1/obsidian-contact-sync-plugin.git
synced 2026-07-22 05:48:16 +00:00
Add support for "Relations" fields (#29)
* Update target to EcmaScript 2021 According to this: https://forum.obsidian.md/t/what-is-the-most-sensible-ecmascript-build-target-for-a-plugin/103193 There is no reason to go lower right now. * Start loading Relations from the People API * Add relationsAsLink setting * Add relations adapter with VCF support --------- Co-authored-by: Aleksejs Kovalovs <aleks4444@inbox.lv>
This commit is contained in:
parent
5845592af3
commit
1f4d8bf078
13 changed files with 63 additions and 3 deletions
|
|
@ -122,6 +122,7 @@ describe('ContactNoteWriter', () => {
|
|||
folderPath: 'path/to/folder',
|
||||
noteBody: mockNoteBody,
|
||||
organizationAsLink: false,
|
||||
relationsAsLink: false,
|
||||
trackSyncTime: true,
|
||||
renameFiles: false,
|
||||
namingStrategy: NamingStrategy.Default,
|
||||
|
|
@ -172,6 +173,7 @@ describe('ContactNoteWriter', () => {
|
|||
folderPath: 'path/to/folder',
|
||||
noteBody: mockNoteBody,
|
||||
organizationAsLink: false,
|
||||
relationsAsLink: false,
|
||||
trackSyncTime: true,
|
||||
renameFiles: false,
|
||||
namingStrategy: NamingStrategy.Default,
|
||||
|
|
@ -221,6 +223,7 @@ describe('ContactNoteWriter', () => {
|
|||
folderPath: 'path/to/folder',
|
||||
noteBody: mockNoteBody,
|
||||
organizationAsLink: false,
|
||||
relationsAsLink: false,
|
||||
trackSyncTime: true,
|
||||
renameFiles: false,
|
||||
namingStrategy: NamingStrategy.Default,
|
||||
|
|
@ -264,6 +267,7 @@ describe('ContactNoteWriter', () => {
|
|||
folderPath: 'path/to/folder',
|
||||
noteBody: mockNoteBody,
|
||||
organizationAsLink: false,
|
||||
relationsAsLink: false,
|
||||
trackSyncTime: true,
|
||||
renameFiles: false,
|
||||
namingStrategy: NamingStrategy.Default,
|
||||
|
|
@ -305,6 +309,7 @@ describe('ContactNoteWriter', () => {
|
|||
folderPath: 'path/to/folder',
|
||||
noteBody: mockNoteBody,
|
||||
organizationAsLink: false,
|
||||
relationsAsLink: false,
|
||||
trackSyncTime: true,
|
||||
renameFiles: false,
|
||||
namingStrategy: NamingStrategy.Default,
|
||||
|
|
|
|||
|
|
@ -112,6 +112,7 @@ describe('ContactNoteWriterUpdate', () => {
|
|||
syncLabel: '',
|
||||
noteBody: mockNoteBody,
|
||||
organizationAsLink: false,
|
||||
relationsAsLink: false,
|
||||
trackSyncTime: true,
|
||||
renameFiles: false,
|
||||
namingStrategy: NamingStrategy.Default,
|
||||
|
|
@ -158,6 +159,7 @@ describe('ContactNoteWriterUpdate', () => {
|
|||
syncLabel: '',
|
||||
noteBody: mockNoteBody,
|
||||
organizationAsLink: false,
|
||||
relationsAsLink: false,
|
||||
trackSyncTime: true,
|
||||
renameFiles: false,
|
||||
namingStrategy: NamingStrategy.Default,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ export const URL_OAUTH_TOKEN = 'https://oauth2.googleapis.com/token';
|
|||
/** Google People API endpoints */
|
||||
const URL_PEOPLE_BASE = 'https://people.googleapis.com/v1';
|
||||
export const URL_PEOPLE_CONNECTIONS = `${URL_PEOPLE_BASE}/people/me/connections`;
|
||||
export const PERSONAL_FIELDS = `names,emailAddresses,phoneNumbers,birthdays,memberships,metadata,addresses,biographies,organizations`;
|
||||
export const PERSONAL_FIELDS = `names,emailAddresses,phoneNumbers,birthdays,memberships,metadata,addresses,biographies,organizations,relations`;
|
||||
export const OTHER_CONTACTS_FIELDS = `names,emailAddresses,phoneNumbers`;
|
||||
export const URL_CONTACT_GROUPS = `${URL_PEOPLE_BASE}/contactGroups?pageSize=1000`;
|
||||
|
||||
|
|
@ -38,6 +38,7 @@ export const DEFAULT_SETTINGS: ContactSyncSettings = {
|
|||
syncOnStartup: false,
|
||||
trackSyncTime: false,
|
||||
organizationAsLink: false,
|
||||
relationsAsLink: true,
|
||||
renameFiles: false,
|
||||
namingStrategy: NamingStrategy.Default,
|
||||
lastFirst: false,
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import { JobTitleAdapter } from './adapters/JobTitleAdapter';
|
|||
import { DepartmentAdapter } from './adapters/DepartmentAdapter';
|
||||
import { BirthdayAdapter } from './adapters/BirthdayAdapter';
|
||||
import { LabelAdapter } from './adapters/LabelAdapter';
|
||||
import { RelationsAdapter } from './adapters/RelationsAdapter';
|
||||
|
||||
/**
|
||||
* Formatter class responsible for coordinating field extraction and key generation.
|
||||
|
|
@ -99,6 +100,7 @@ export function createDefaultFormatter(
|
|||
jobtitle: new JobTitleAdapter(),
|
||||
department: new DepartmentAdapter(),
|
||||
labels: new LabelAdapter(),
|
||||
relations: new RelationsAdapter(),
|
||||
};
|
||||
|
||||
if (strategyType === NamingStrategy.VCF) {
|
||||
|
|
|
|||
19
src/core/adapters/RelationsAdapter.ts
Normal file
19
src/core/adapters/RelationsAdapter.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
import { FieldAdapter, ExtractionResult } from '../interfaces';
|
||||
import { GoogleContact } from '../../types/Contact';
|
||||
import { NamingStrategy } from 'src/types/Settings';
|
||||
|
||||
export class RelationsAdapter implements FieldAdapter {
|
||||
extract(
|
||||
contact: GoogleContact,
|
||||
context?: Record<string, unknown>
|
||||
): ExtractionResult[] {
|
||||
const relationsAsLink = context?.relationsAsLink as boolean;
|
||||
const isVcfStrategy = context?.namingStrategy === NamingStrategy.VCF;
|
||||
return (contact.relations ?? [])
|
||||
.filter((relation) => !!relation.person)
|
||||
.map((relation) => ({
|
||||
// For VCF strategy, don't use wiki links even if organizationsAsLink is true
|
||||
value: relationsAsLink && !isVcfStrategy ? `[[${relation.person}|${relation.person} (${relation.type})]]` : `${relation.person} (${relation.type})`,
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,7 @@ export class VcfNamingStrategy implements KeyNamingStrategy {
|
|||
phone: 'TEL',
|
||||
address: 'ADR',
|
||||
organization: 'ORG',
|
||||
relations: 'X-RELATION',
|
||||
jobtitle: 'TITLE',
|
||||
bio: 'NOTE',
|
||||
birthday: 'BDAY',
|
||||
|
|
|
|||
|
|
@ -209,6 +209,7 @@ export default class GoogleContactsSyncPlugin extends Plugin {
|
|||
syncLabel: this.settings.syncLabel,
|
||||
noteBody: this.settings.noteTemplate || '# Notes\n',
|
||||
organizationAsLink: this.settings.organizationAsLink,
|
||||
relationsAsLink: this.settings.relationsAsLink,
|
||||
trackSyncTime: this.settings.trackSyncTime,
|
||||
renameFiles: this.settings.renameFiles,
|
||||
namingStrategy: this.settings.namingStrategy,
|
||||
|
|
|
|||
|
|
@ -147,6 +147,22 @@ export class ContactSyncSettingTab extends PluginSettingTab {
|
|||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName(t('Relations as links'))
|
||||
.setDesc(
|
||||
t(
|
||||
'Related people names will be stored as a obsidian link [[...]] instead of plain text'
|
||||
)
|
||||
)
|
||||
.addToggle((toggle) =>
|
||||
toggle
|
||||
.setValue(this.plugin.settings.relationsAsLink)
|
||||
.onChange(async (value) => {
|
||||
this.plugin.settings.relationsAsLink = value;
|
||||
await this.plugin.saveSettings();
|
||||
})
|
||||
);
|
||||
|
||||
new Setting(containerEl)
|
||||
.setName(t('Label to sync'))
|
||||
.setDesc(
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ export class ContactNoteWriter {
|
|||
invertedLabelMap,
|
||||
config.namingStrategy,
|
||||
config.organizationAsLink,
|
||||
config.relationsAsLink,
|
||||
config.trackSyncTime
|
||||
)
|
||||
)
|
||||
|
|
@ -266,6 +267,7 @@ export class ContactNoteWriter {
|
|||
invertedLabelMap: Record<string, string>,
|
||||
namingStrategy: NamingStrategy,
|
||||
organizationAsLink = false,
|
||||
relationsAsLink = false,
|
||||
trackSyncTime = false
|
||||
): Record<string, string | string[]> {
|
||||
const formatter = createDefaultFormatter(namingStrategy);
|
||||
|
|
@ -275,6 +277,7 @@ export class ContactNoteWriter {
|
|||
{
|
||||
labelMap: invertedLabelMap,
|
||||
organizationAsLink: organizationAsLink,
|
||||
relationsAsLink: relationsAsLink,
|
||||
namingStrategy: namingStrategy,
|
||||
}
|
||||
);
|
||||
|
|
|
|||
|
|
@ -56,6 +56,12 @@ export interface GoogleContact {
|
|||
title: string;
|
||||
department: string;
|
||||
}[];
|
||||
|
||||
relations?: {
|
||||
person: string;
|
||||
type: string;
|
||||
metadata: string;
|
||||
}[];
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ export interface ContactNoteConfig {
|
|||
syncLabel: string;
|
||||
noteBody: string;
|
||||
organizationAsLink: boolean;
|
||||
relationsAsLink: boolean;
|
||||
trackSyncTime: boolean;
|
||||
renameFiles: boolean;
|
||||
namingStrategy: NamingStrategy;
|
||||
|
|
|
|||
|
|
@ -47,6 +47,9 @@ export interface ContactSyncSettings {
|
|||
/** Save organization as obsidian link */
|
||||
organizationAsLink: boolean;
|
||||
|
||||
/** Save relationships as links */
|
||||
relationsAsLink: boolean;
|
||||
|
||||
/** Whether to rename existing contact files in case if name has been changed based on current naming settings */
|
||||
renameFiles: boolean;
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2017",
|
||||
"target": "es2021",
|
||||
"lib": [
|
||||
"es2017",
|
||||
"es2021",
|
||||
"dom"
|
||||
],
|
||||
"module": "esnext",
|
||||
|
|
|
|||
Loading…
Reference in a new issue