Refactor bulk folder import logic to better switch between title and id lookup methods
This commit is contained in:
parent
a10f9ec609
commit
4798f1144b
2 changed files with 63 additions and 56 deletions
35
src/main.ts
35
src/main.ts
|
|
@ -621,14 +621,14 @@ export default class MediaDbPlugin extends Plugin {
|
|||
const erroredFiles: { filePath: string; error: string }[] = [];
|
||||
let canceled: boolean = false;
|
||||
|
||||
const { selectedAPI, titleFieldName, idFieldName, appendContent } = await new Promise<{
|
||||
const { selectedAPI, lookupMethod, fieldName, appendContent } = await new Promise<{
|
||||
selectedAPI: string;
|
||||
titleFieldName: string;
|
||||
idFieldName: string;
|
||||
lookupMethod: string;
|
||||
fieldName: string;
|
||||
appendContent: boolean;
|
||||
}>(resolve => {
|
||||
new MediaDbFolderImportModal(this.app, this, (selectedAPI: string, titleFieldName: string, idFieldName: string, appendContent: boolean) => {
|
||||
resolve({ selectedAPI, titleFieldName, idFieldName, appendContent });
|
||||
new MediaDbFolderImportModal(this.app, this, (selectedAPI: string, lookupMethod: string, fieldName: string, appendContent: boolean) => {
|
||||
resolve({ selectedAPI, lookupMethod, fieldName, appendContent });
|
||||
}).open();
|
||||
});
|
||||
|
||||
|
|
@ -641,32 +641,27 @@ export default class MediaDbPlugin extends Plugin {
|
|||
}
|
||||
|
||||
const metadata = this.getMetadataFromFileCache(file);
|
||||
const lookupValue = metadata[fieldName];
|
||||
|
||||
// Querying by ID takes priority, doesn't require user to select from multiple matches
|
||||
const id = metadata[idFieldName];
|
||||
if (id && typeof id === 'string') {
|
||||
if (!lookupValue || typeof lookupValue !== 'string') {
|
||||
erroredFiles.push({ filePath: file.path, error: `metadata field '${fieldName}' not found, empty, or not a string` });
|
||||
continue;
|
||||
} else if (lookupMethod == 'id') {
|
||||
try {
|
||||
const model = await this.apiManager.queryDetailedInfoById(id, selectedAPI);
|
||||
const model = await this.apiManager.queryDetailedInfoById(lookupValue, selectedAPI);
|
||||
if (model) {
|
||||
await this.createMediaDbNotes([model], appendContent ? file : undefined);
|
||||
} else {
|
||||
erroredFiles.push({ filePath: file.path, error: `Failed to query API with id: ${id}` });
|
||||
erroredFiles.push({ filePath: file.path, error: `Failed to query API with id: ${lookupValue}` });
|
||||
}
|
||||
} catch (e) {
|
||||
erroredFiles.push({ filePath: file.path, error: `${e}` });
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
// Query API with title instead, requires user to select best match
|
||||
const title = metadata[titleFieldName];
|
||||
if (!title || typeof title !== 'string') {
|
||||
erroredFiles.push({ filePath: file.path, error: `metadata field '${titleFieldName}' not found, empty, or not a string` });
|
||||
continue;
|
||||
}
|
||||
|
||||
} else if (lookupMethod == 'title') {
|
||||
let results: MediaTypeModel[] = [];
|
||||
try {
|
||||
results = await this.apiManager.query(title, [selectedAPI]);
|
||||
results = await this.apiManager.query(lookupValue, [selectedAPI]);
|
||||
} catch (e) {
|
||||
erroredFiles.push({ filePath: file.path, error: `${e}` });
|
||||
continue;
|
||||
|
|
@ -679,7 +674,7 @@ export default class MediaDbPlugin extends Plugin {
|
|||
const { selectModalResult, selectModal } = await this.modalHelper.createSelectModal({
|
||||
elements: results,
|
||||
skipButton: true,
|
||||
modalTitle: `Results for '${title}'`,
|
||||
modalTitle: `Results for '${lookupValue}'`,
|
||||
});
|
||||
|
||||
if (selectModalResult.code === ModalResultCode.ERROR) {
|
||||
|
|
|
|||
|
|
@ -1,28 +1,29 @@
|
|||
import type { App, ButtonComponent } from 'obsidian';
|
||||
import { DropdownComponent, Modal, Setting, TextComponent, ToggleComponent } from 'obsidian';
|
||||
import type MediaDbPlugin from '../main';
|
||||
import type { APIModel } from 'src/api/APIModel';
|
||||
|
||||
export class MediaDbFolderImportModal extends Modal {
|
||||
plugin: MediaDbPlugin;
|
||||
onSubmit: (selectedAPI: string, titleFieldName: string, idFieldName: string, appendContent: boolean) => void;
|
||||
onSubmit: (selectedAPI: string, lookupMethod: string, fieldName: string, appendContent: boolean) => void;
|
||||
selectedApi: string;
|
||||
searchBtn?: ButtonComponent;
|
||||
titleFieldName: string;
|
||||
idFieldName: string;
|
||||
lookupMethod: string;
|
||||
fieldName: string;
|
||||
appendContent: boolean;
|
||||
|
||||
constructor(app: App, plugin: MediaDbPlugin, onSubmit: (selectedAPI: string, titleFieldName: string, idFieldName: string, appendContent: boolean) => void) {
|
||||
constructor(app: App, plugin: MediaDbPlugin, onSubmit: (selectedAPI: string, lookupMethod: string, fieldName: string, appendContent: boolean) => void) {
|
||||
super(app);
|
||||
this.plugin = plugin;
|
||||
this.onSubmit = onSubmit;
|
||||
this.selectedApi = plugin.apiManager.apis[0].apiName;
|
||||
this.titleFieldName = '';
|
||||
this.idFieldName = '';
|
||||
this.lookupMethod = '';
|
||||
this.fieldName = '';
|
||||
this.appendContent = false;
|
||||
}
|
||||
|
||||
submit(): void {
|
||||
this.onSubmit(this.selectedApi, this.titleFieldName, this.idFieldName, this.appendContent);
|
||||
this.onSubmit(this.selectedApi, this.lookupMethod, this.fieldName, this.appendContent);
|
||||
this.close();
|
||||
}
|
||||
|
||||
|
|
@ -31,18 +32,14 @@ export class MediaDbFolderImportModal extends Modal {
|
|||
|
||||
contentEl.createEl('h2', { text: 'Import folder as Media DB entries' });
|
||||
|
||||
const apiSelectorWrapper = contentEl.createEl('div', { cls: 'media-db-plugin-list-wrapper' });
|
||||
const apiSelectorTextWrapper = apiSelectorWrapper.createEl('div', { cls: 'media-db-plugin-list-text-wrapper' });
|
||||
apiSelectorTextWrapper.createEl('span', { text: 'API to search', cls: 'media-db-plugin-list-text' });
|
||||
|
||||
const apiSelectorComponent = new DropdownComponent(apiSelectorWrapper);
|
||||
apiSelectorComponent.onChange((value: string) => {
|
||||
const onAPIChange = (value: string) => {
|
||||
this.selectedApi = value;
|
||||
};
|
||||
const apiOptions = this.plugin.apiManager.apis.map((api: APIModel) => {
|
||||
return { value: api.apiName, display: api.apiName };
|
||||
});
|
||||
for (const api of this.plugin.apiManager.apis) {
|
||||
apiSelectorComponent.addOption(api.apiName, api.apiName);
|
||||
}
|
||||
apiSelectorWrapper.appendChild(apiSelectorComponent.selectEl);
|
||||
|
||||
this.createDropdownEl(contentEl, 'API to search', onAPIChange, apiOptions);
|
||||
|
||||
contentEl.createDiv({ cls: 'media-db-plugin-spacer' });
|
||||
contentEl.createEl('h3', { text: 'Append note content to Media DB entry?' });
|
||||
|
|
@ -62,33 +59,35 @@ export class MediaDbFolderImportModal extends Modal {
|
|||
appendContentToggleComponentWrapper.appendChild(appendContentToggle.toggleEl);
|
||||
|
||||
contentEl.createDiv({ cls: 'media-db-plugin-spacer' });
|
||||
contentEl.createEl('h3', { text: "Name of 'title' metadata field to use in API query." });
|
||||
|
||||
const placeholder = 'title';
|
||||
const titleFieldNameComponent = new TextComponent(contentEl);
|
||||
titleFieldNameComponent.inputEl.style.width = '100%';
|
||||
titleFieldNameComponent.setPlaceholder(placeholder);
|
||||
titleFieldNameComponent.onChange(value => (this.titleFieldName = value));
|
||||
titleFieldNameComponent.inputEl.addEventListener('keydown', ke => {
|
||||
if (ke.key === 'Enter') {
|
||||
this.submit();
|
||||
}
|
||||
contentEl.createEl('h3', { text: 'Media lookup method' });
|
||||
contentEl.createEl('p', {
|
||||
text: 'Choose whether to search the API by title (can return multiple results) or lookup directly using an ID (returns at most one result), and specify the name of the frontmatter property which contains the title or ID of the media.',
|
||||
});
|
||||
contentEl.appendChild(titleFieldNameComponent.inputEl);
|
||||
|
||||
const onlookupMethodChange = (value: string) => {
|
||||
this.lookupMethod = value;
|
||||
};
|
||||
const lookupMethodOptions = [
|
||||
{ value: 'title', display: 'Title' },
|
||||
{ value: 'id', display: 'ID' },
|
||||
];
|
||||
this.createDropdownEl(contentEl, 'Lookup media by', onlookupMethodChange, lookupMethodOptions);
|
||||
|
||||
contentEl.createDiv({ cls: 'media-db-plugin-spacer' });
|
||||
contentEl.createEl('h3', { text: "Name of 'id' metadata field to use in API query (if present, will be used instead of title)." });
|
||||
|
||||
const idFieldNameComponent = new TextComponent(contentEl);
|
||||
idFieldNameComponent.inputEl.style.width = '100%';
|
||||
idFieldNameComponent.setPlaceholder('id');
|
||||
idFieldNameComponent.onChange(value => (this.idFieldName = value));
|
||||
idFieldNameComponent.inputEl.addEventListener('keydown', ke => {
|
||||
const fieldNameWrapperEl = contentEl.createEl('div', { cls: 'media-db-plugin-list-wrapper' });
|
||||
const fieldNameLabelWrapperEl = fieldNameWrapperEl.createEl('div', { cls: 'media-db-plugin-list-text-wrapper' });
|
||||
fieldNameLabelWrapperEl.createEl('span', { text: 'Using the property named', cls: 'media-db-plugin-list-text' });
|
||||
|
||||
const fieldNameComponent = new TextComponent(fieldNameWrapperEl);
|
||||
fieldNameComponent.setPlaceholder('title / id');
|
||||
fieldNameComponent.onChange(value => (this.fieldName = value));
|
||||
fieldNameComponent.inputEl.addEventListener('keydown', ke => {
|
||||
if (ke.key === 'Enter') {
|
||||
this.submit();
|
||||
}
|
||||
});
|
||||
contentEl.appendChild(idFieldNameComponent.inputEl);
|
||||
contentEl.appendChild(fieldNameWrapperEl);
|
||||
|
||||
contentEl.createDiv({ cls: 'media-db-plugin-spacer' });
|
||||
|
||||
|
|
@ -109,6 +108,19 @@ export class MediaDbFolderImportModal extends Modal {
|
|||
});
|
||||
}
|
||||
|
||||
createDropdownEl(parentEl: HTMLElement, label: string, onChange: { (value: string): void }, options: { value: string; display: string }[]): void {
|
||||
const wrapperEl = parentEl.createEl('div', { cls: 'media-db-plugin-list-wrapper' });
|
||||
const labelWrapperEl = wrapperEl.createEl('div', { cls: 'media-db-plugin-list-text-wrapper' });
|
||||
labelWrapperEl.createEl('span', { text: label, cls: 'media-db-plugin-list-text' });
|
||||
|
||||
const dropDownComponent = new DropdownComponent(wrapperEl);
|
||||
dropDownComponent.onChange(onChange);
|
||||
for (const option of options) {
|
||||
dropDownComponent.addOption(option.value, option.display);
|
||||
}
|
||||
wrapperEl.appendChild(dropDownComponent.selectEl);
|
||||
}
|
||||
|
||||
onClose(): void {
|
||||
const { contentEl } = this;
|
||||
contentEl.empty();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue