Allow batch / folder import by id as well as title
This commit is contained in:
parent
9fa7348ae9
commit
a10f9ec609
2 changed files with 93 additions and 51 deletions
118
src/main.ts
118
src/main.ts
|
|
@ -621,9 +621,14 @@ export default class MediaDbPlugin extends Plugin {
|
||||||
const erroredFiles: { filePath: string; error: string }[] = [];
|
const erroredFiles: { filePath: string; error: string }[] = [];
|
||||||
let canceled: boolean = false;
|
let canceled: boolean = false;
|
||||||
|
|
||||||
const { selectedAPI, titleFieldName, appendContent } = await new Promise<{ selectedAPI: string; titleFieldName: string; appendContent: boolean }>(resolve => {
|
const { selectedAPI, titleFieldName, idFieldName, appendContent } = await new Promise<{
|
||||||
new MediaDbFolderImportModal(this.app, this, (selectedAPI: string, titleFieldName: string, appendContent: boolean) => {
|
selectedAPI: string;
|
||||||
resolve({ selectedAPI, titleFieldName, appendContent });
|
titleFieldName: string;
|
||||||
|
idFieldName: string;
|
||||||
|
appendContent: boolean;
|
||||||
|
}>(resolve => {
|
||||||
|
new MediaDbFolderImportModal(this.app, this, (selectedAPI: string, titleFieldName: string, idFieldName: string, appendContent: boolean) => {
|
||||||
|
resolve({ selectedAPI, titleFieldName, idFieldName, appendContent });
|
||||||
}).open();
|
}).open();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -637,54 +642,75 @@ export default class MediaDbPlugin extends Plugin {
|
||||||
|
|
||||||
const metadata = this.getMetadataFromFileCache(file);
|
const metadata = this.getMetadataFromFileCache(file);
|
||||||
|
|
||||||
const title = metadata[titleFieldName];
|
// Querying by ID takes priority, doesn't require user to select from multiple matches
|
||||||
if (!title || typeof title !== 'string') {
|
const id = metadata[idFieldName];
|
||||||
erroredFiles.push({ filePath: file.path, error: `metadata field '${titleFieldName}' not found, empty, or not a string` });
|
if (id && typeof id === 'string') {
|
||||||
continue;
|
try {
|
||||||
}
|
const model = await this.apiManager.queryDetailedInfoById(id, selectedAPI);
|
||||||
|
if (model) {
|
||||||
|
await this.createMediaDbNotes([model], appendContent ? file : undefined);
|
||||||
|
} else {
|
||||||
|
erroredFiles.push({ filePath: file.path, error: `Failed to query API with id: ${id}` });
|
||||||
|
}
|
||||||
|
} 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;
|
||||||
|
}
|
||||||
|
|
||||||
let results: MediaTypeModel[] = [];
|
let results: MediaTypeModel[] = [];
|
||||||
try {
|
try {
|
||||||
results = await this.apiManager.query(title, [selectedAPI]);
|
results = await this.apiManager.query(title, [selectedAPI]);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
erroredFiles.push({ filePath: file.path, error: `${e}` });
|
erroredFiles.push({ filePath: file.path, error: `${e}` });
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!results || results.length === 0) {
|
if (!results || results.length === 0) {
|
||||||
erroredFiles.push({ filePath: file.path, error: `no search results` });
|
erroredFiles.push({ filePath: file.path, error: `no search results` });
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { selectModalResult, selectModal } = await this.modalHelper.createSelectModal({ elements: results, skipButton: true, modalTitle: `Results for '${title}'` });
|
const { selectModalResult, selectModal } = await this.modalHelper.createSelectModal({
|
||||||
|
elements: results,
|
||||||
|
skipButton: true,
|
||||||
|
modalTitle: `Results for '${title}'`,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (selectModalResult.code === ModalResultCode.ERROR) {
|
||||||
|
erroredFiles.push({ filePath: file.path, error: selectModalResult.error.message });
|
||||||
|
selectModal.close();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectModalResult.code === ModalResultCode.CLOSE) {
|
||||||
|
erroredFiles.push({ filePath: file.path, error: 'user canceled' });
|
||||||
|
selectModal.close();
|
||||||
|
canceled = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectModalResult.code === ModalResultCode.SKIP) {
|
||||||
|
erroredFiles.push({ filePath: file.path, error: 'user skipped' });
|
||||||
|
selectModal.close();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectModalResult.data.selected.length === 0) {
|
||||||
|
erroredFiles.push({ filePath: file.path, error: `no search results selected` });
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const detailedResults = await this.queryDetails(selectModalResult.data.selected);
|
||||||
|
await this.createMediaDbNotes(detailedResults, appendContent ? file : undefined);
|
||||||
|
|
||||||
if (selectModalResult.code === ModalResultCode.ERROR) {
|
|
||||||
erroredFiles.push({ filePath: file.path, error: selectModalResult.error.message });
|
|
||||||
selectModal.close();
|
selectModal.close();
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectModalResult.code === ModalResultCode.CLOSE) {
|
|
||||||
erroredFiles.push({ filePath: file.path, error: 'user canceled' });
|
|
||||||
selectModal.close();
|
|
||||||
canceled = true;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectModalResult.code === ModalResultCode.SKIP) {
|
|
||||||
erroredFiles.push({ filePath: file.path, error: 'user skipped' });
|
|
||||||
selectModal.close();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectModalResult.data.selected.length === 0) {
|
|
||||||
erroredFiles.push({ filePath: file.path, error: `no search results selected` });
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const detailedResults = await this.queryDetails(selectModalResult.data.selected);
|
|
||||||
await this.createMediaDbNotes(detailedResults, appendContent ? file : undefined);
|
|
||||||
|
|
||||||
selectModal.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,23 +4,25 @@ import type MediaDbPlugin from '../main';
|
||||||
|
|
||||||
export class MediaDbFolderImportModal extends Modal {
|
export class MediaDbFolderImportModal extends Modal {
|
||||||
plugin: MediaDbPlugin;
|
plugin: MediaDbPlugin;
|
||||||
onSubmit: (selectedAPI: string, titleFieldName: string, appendContent: boolean) => void;
|
onSubmit: (selectedAPI: string, titleFieldName: string, idFieldName: string, appendContent: boolean) => void;
|
||||||
selectedApi: string;
|
selectedApi: string;
|
||||||
searchBtn?: ButtonComponent;
|
searchBtn?: ButtonComponent;
|
||||||
titleFieldName: string;
|
titleFieldName: string;
|
||||||
|
idFieldName: string;
|
||||||
appendContent: boolean;
|
appendContent: boolean;
|
||||||
|
|
||||||
constructor(app: App, plugin: MediaDbPlugin, onSubmit: (selectedAPI: string, titleFieldName: string, appendContent: boolean) => void) {
|
constructor(app: App, plugin: MediaDbPlugin, onSubmit: (selectedAPI: string, titleFieldName: string, idFieldName: string, appendContent: boolean) => void) {
|
||||||
super(app);
|
super(app);
|
||||||
this.plugin = plugin;
|
this.plugin = plugin;
|
||||||
this.onSubmit = onSubmit;
|
this.onSubmit = onSubmit;
|
||||||
this.selectedApi = plugin.apiManager.apis[0].apiName;
|
this.selectedApi = plugin.apiManager.apis[0].apiName;
|
||||||
this.titleFieldName = '';
|
this.titleFieldName = '';
|
||||||
|
this.idFieldName = '';
|
||||||
this.appendContent = false;
|
this.appendContent = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
submit(): void {
|
submit(): void {
|
||||||
this.onSubmit(this.selectedApi, this.titleFieldName, this.appendContent);
|
this.onSubmit(this.selectedApi, this.titleFieldName, this.idFieldName, this.appendContent);
|
||||||
this.close();
|
this.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -43,7 +45,7 @@ export class MediaDbFolderImportModal extends Modal {
|
||||||
apiSelectorWrapper.appendChild(apiSelectorComponent.selectEl);
|
apiSelectorWrapper.appendChild(apiSelectorComponent.selectEl);
|
||||||
|
|
||||||
contentEl.createDiv({ cls: 'media-db-plugin-spacer' });
|
contentEl.createDiv({ cls: 'media-db-plugin-spacer' });
|
||||||
contentEl.createEl('h3', { text: 'Append note content to Media DB entry.' });
|
contentEl.createEl('h3', { text: 'Append note content to Media DB entry?' });
|
||||||
|
|
||||||
const appendContentToggleElementWrapper = contentEl.createEl('div', { cls: 'media-db-plugin-list-wrapper' });
|
const appendContentToggleElementWrapper = contentEl.createEl('div', { cls: 'media-db-plugin-list-wrapper' });
|
||||||
const appendContentToggleTextWrapper = appendContentToggleElementWrapper.createEl('div', { cls: 'media-db-plugin-list-text-wrapper' });
|
const appendContentToggleTextWrapper = appendContentToggleElementWrapper.createEl('div', { cls: 'media-db-plugin-list-text-wrapper' });
|
||||||
|
|
@ -60,7 +62,7 @@ export class MediaDbFolderImportModal extends Modal {
|
||||||
appendContentToggleComponentWrapper.appendChild(appendContentToggle.toggleEl);
|
appendContentToggleComponentWrapper.appendChild(appendContentToggle.toggleEl);
|
||||||
|
|
||||||
contentEl.createDiv({ cls: 'media-db-plugin-spacer' });
|
contentEl.createDiv({ cls: 'media-db-plugin-spacer' });
|
||||||
contentEl.createEl('h3', { text: 'The name of the metadata field that should be used as the title to query.' });
|
contentEl.createEl('h3', { text: "Name of 'title' metadata field to use in API query." });
|
||||||
|
|
||||||
const placeholder = 'title';
|
const placeholder = 'title';
|
||||||
const titleFieldNameComponent = new TextComponent(contentEl);
|
const titleFieldNameComponent = new TextComponent(contentEl);
|
||||||
|
|
@ -74,6 +76,20 @@ export class MediaDbFolderImportModal extends Modal {
|
||||||
});
|
});
|
||||||
contentEl.appendChild(titleFieldNameComponent.inputEl);
|
contentEl.appendChild(titleFieldNameComponent.inputEl);
|
||||||
|
|
||||||
|
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 => {
|
||||||
|
if (ke.key === 'Enter') {
|
||||||
|
this.submit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
contentEl.appendChild(idFieldNameComponent.inputEl);
|
||||||
|
|
||||||
contentEl.createDiv({ cls: 'media-db-plugin-spacer' });
|
contentEl.createDiv({ cls: 'media-db-plugin-spacer' });
|
||||||
|
|
||||||
new Setting(contentEl)
|
new Setting(contentEl)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue