mirror of
https://github.com/gtritchie/bulk-properties.git
synced 2026-07-22 14:10:30 +00:00
Use "notes" instead of "files" in user-visible text (#41)
* Refine manifest description to use 'notes' per Obsidian style guide * Replace user-visible "files" with "notes" per Obsidian style guide Updates command names, UI labels, notices, confirmation messages, settings descriptions, and README copy. Internal identifiers and Obsidian UI names (File menu, file explorer, Settings → Files and links → Deleted files) left unchanged.
This commit is contained in:
parent
e66c0eeea1
commit
3800a5f79d
8 changed files with 46 additions and 46 deletions
28
README.md
28
README.md
|
|
@ -1,40 +1,40 @@
|
|||
# Bulk Properties
|
||||
|
||||
An [Obsidian](https://obsidian.md) plugin that lets you bulk edit properties on, or delete, multiple files in your vault.
|
||||
An [Obsidian](https://obsidian.md) plugin that lets you bulk edit properties on, or delete, multiple notes in your vault.
|
||||
|
||||
This plugin uses a checkbox property (default: `selected`) to track which files are selected. Check the box on the files you want to work with, run the command, then update a property across all of them at once or delete them. Works well with Obsidian Bases, where the selection property can be displayed as a checkbox column.
|
||||
This plugin uses a checkbox property (default: `selected`) to track which notes are selected. Check the box on the notes you want to work with, run the command, then update a property across all of them at once or delete them. Works well with Obsidian Bases, where the selection property can be displayed as a checkbox column.
|
||||
|
||||
**Note:** The plugin operates on all files in the vault that have the selection property checked, not just files visible in a particular Base. Make sure to uncheck the selection property on files you don't want to modify.
|
||||
**Note:** The plugin operates on all notes in the vault that have the selection property checked, not just notes visible in a particular Base. Make sure to uncheck the selection property on notes you don't want to modify.
|
||||
|
||||
## Setup
|
||||
|
||||
Before using the command, configure the plugin in **Settings → Bulk Properties**:
|
||||
|
||||
- **Selection property** — the name of the checkbox property used to mark files as selected (default: `selected`). Autocompletes from existing vault properties.
|
||||
- **Selection property** — the name of the checkbox property used to mark notes as selected (default: `selected`). Autocompletes from existing vault properties.
|
||||
- **Properties** — add the properties you want to be available for bulk editing, specifying the name and type for each. Property names autocomplete from the vault. Supported types: Aliases, Checkbox, Date, Date & time, List, Number, Tags, Text.
|
||||
- **Deselect when finished** — the default value for the deselect toggle in the bulk edit dialog (default: on).
|
||||
- **Show selection count in status bar** — displays the number of selected files in the status bar (default: on). The count updates automatically as you check or uncheck the selection property. Status bar items are not available on mobile.
|
||||
- **Show selection count in status bar** — displays the number of selected notes in the status bar (default: on). The count updates automatically as you check or uncheck the selection property. Status bar items are not available on mobile.
|
||||
|
||||
## Usage
|
||||
|
||||
1. Add the selection property to your notes or Base view.
|
||||
2. Check the box on each file you want to bulk edit.
|
||||
3. Open the bulk edit dialog from the ribbon icon, the **Bulk edit selected files** command, or the editor right-click menu.
|
||||
4. Review the file checklist — uncheck any files you don't want to modify, or re-check files you do.
|
||||
2. Check the box on each note you want to bulk edit.
|
||||
3. Open the bulk edit dialog from the ribbon icon, the **Bulk edit selected notes** command, or the editor right-click menu.
|
||||
4. Review the note checklist — uncheck any notes you don't want to modify, or re-check notes you do.
|
||||
5. Choose a property from the dropdown, enter the new value, and select **Update properties**. For multi-value properties (Aliases, List, Tags), choose an action: **Merge** adds new values to existing ones, **Replace** overwrites the current values, and **Delete** removes matching values.
|
||||
6. To delete the checked files instead, select **Delete selected files**. After a confirmation prompt, the files are deleted following your **Settings → Files and links → Deleted files** preference — they may be moved to the system trash, moved to an Obsidian `.trash` folder, or permanently deleted, depending on how that preference is configured.
|
||||
7. Optionally disable **Deselect when finished** to keep the files selected after the update.
|
||||
6. To delete the checked notes instead, select **Delete selected notes**. After a confirmation prompt, the notes are deleted following your **Settings → Files and links → Deleted files** preference — they may be moved to the system trash, moved to an Obsidian `.trash` folder, or permanently deleted, depending on how that preference is configured.
|
||||
7. Optionally disable **Deselect when finished** to keep the notes selected after the update.
|
||||
|
||||
## Commands
|
||||
|
||||
- **Bulk edit selected files** — opens the bulk edit dialog showing all files with the selection property checked. Also available from the editor right-click menu.
|
||||
- **Deselect all files** — unchecks the selection property on every file in the vault that has it checked.
|
||||
- **Remove selection property from all files** — removes the selection property entirely from every file in the vault that has it.
|
||||
- **Bulk edit selected notes** — opens the bulk edit dialog showing all notes with the selection property checked. Also available from the editor right-click menu.
|
||||
- **Deselect all notes** — unchecks the selection property on every note in the vault that has it checked.
|
||||
- **Remove selection property from all notes** — removes the selection property entirely from every note in the vault that has it.
|
||||
|
||||
## Context menus
|
||||
|
||||
- **Editor menu** — right-click inside an editor to open the bulk edit dialog.
|
||||
- **File menu** — right-click a markdown file in the file explorer or a Base view to toggle its selection. The menu item reads **Select for bulk edit** or **Deselect for bulk edit** based on the file's current state.
|
||||
- **File menu** — right-click a note in the file explorer or a Base view to toggle its selection. The menu item reads **Select for bulk edit** or **Deselect for bulk edit** based on the note's current state.
|
||||
|
||||
## Manual Installation
|
||||
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
"name": "Bulk Properties",
|
||||
"version": "1.0.5",
|
||||
"minAppVersion": "1.4.10",
|
||||
"description": "Edit properties across multiple files at once, using a checkbox property to select which files to update.",
|
||||
"description": "Edit properties across multiple notes at once. Use a checkbox property to mark notes for updating.",
|
||||
"author": "Gary Ritchie",
|
||||
"isDesktopOnly": false,
|
||||
"fundingUrl": "https://github.com/sponsors/gtritchie"
|
||||
|
|
|
|||
|
|
@ -142,11 +142,11 @@ export class BulkEditModal extends Modal {
|
|||
const {settings} = this.plugin;
|
||||
contentEl.addClass("bulk-properties-modal");
|
||||
|
||||
new Setting(contentEl).setName("Bulk edit selected files").setHeading();
|
||||
new Setting(contentEl).setName("Bulk edit selected notes").setHeading();
|
||||
|
||||
if (this.fileSelection.size === 0) {
|
||||
contentEl.createEl("p", {
|
||||
text: `No files have the "${settings.selectionProperty}" property checked. Mark files by setting their "${settings.selectionProperty}" checkbox property to true.`,
|
||||
text: `No notes have the "${settings.selectionProperty}" property checked. Mark notes by setting their "${settings.selectionProperty}" checkbox property to true.`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
|
@ -243,7 +243,7 @@ export class BulkEditModal extends Modal {
|
|||
const footer = new Setting(contentEl)
|
||||
.addButton(btn => {
|
||||
btn
|
||||
.setButtonText("Delete selected files")
|
||||
.setButtonText("Delete selected notes")
|
||||
.setWarning()
|
||||
.onClick(() => {
|
||||
void this.doDelete();
|
||||
|
|
@ -276,7 +276,7 @@ export class BulkEditModal extends Modal {
|
|||
private updateCountText() {
|
||||
const checked = this.getCheckedFiles().length;
|
||||
const total = this.fileSelection.size;
|
||||
this.countEl.setText(`${checked} of ${total} file${total === 1 ? "" : "s"} selected`);
|
||||
this.countEl.setText(`${checked} of ${total} note${total === 1 ? "" : "s"} selected`);
|
||||
if (!this.uiLocked) {
|
||||
if (this.updateBtn) {
|
||||
const hasUncommitted = this.activePillInput !== null
|
||||
|
|
@ -361,7 +361,7 @@ export class BulkEditModal extends Modal {
|
|||
|
||||
this.updateCountText();
|
||||
if (failed.length > 0) {
|
||||
new Notice(`Failed to update selection for ${failed.length} file${failed.length === 1 ? "" : "s"}: ${failed.join(", ")}`);
|
||||
new Notice(`Failed to update selection for ${failed.length} note${failed.length === 1 ? "" : "s"}: ${failed.join(", ")}`);
|
||||
}
|
||||
} finally {
|
||||
this.uiLocked = false;
|
||||
|
|
@ -817,9 +817,9 @@ export class BulkEditModal extends Modal {
|
|||
|
||||
const actualSucceeded = result.succeeded - skippedCount;
|
||||
const {failed, cancelled, total} = result;
|
||||
let msg = `Updated "${property}" in ${actualSucceeded} file${actualSucceeded === 1 ? "" : "s"}`;
|
||||
let msg = `Updated "${property}" in ${actualSucceeded} note${actualSucceeded === 1 ? "" : "s"}`;
|
||||
if (cancelled) {
|
||||
msg = `Updated "${property}" in ${actualSucceeded} of ${total} file${total === 1 ? "" : "s"} (cancelled)`;
|
||||
msg = `Updated "${property}" in ${actualSucceeded} of ${total} note${total === 1 ? "" : "s"} (cancelled)`;
|
||||
}
|
||||
if (skippedCount > 0) {
|
||||
msg += `, skipped ${skippedCount} (non-list values)`;
|
||||
|
|
@ -839,7 +839,7 @@ export class BulkEditModal extends Modal {
|
|||
if (filesToDelete.length === 0) {
|
||||
this.uiLocked = false;
|
||||
this.setUIEnabled(true);
|
||||
new Notice("No files selected");
|
||||
new Notice("No notes selected");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -859,9 +859,9 @@ export class BulkEditModal extends Modal {
|
|||
);
|
||||
|
||||
const {succeeded, failed, cancelled, total} = result;
|
||||
let msg = `Deleted ${succeeded} file${succeeded === 1 ? "" : "s"}`;
|
||||
let msg = `Deleted ${succeeded} note${succeeded === 1 ? "" : "s"}`;
|
||||
if (cancelled) {
|
||||
msg = `Deleted ${succeeded} of ${total} file${total === 1 ? "" : "s"} (cancelled)`;
|
||||
msg = `Deleted ${succeeded} of ${total} note${total === 1 ? "" : "s"} (cancelled)`;
|
||||
}
|
||||
if (failed.length > 0) {
|
||||
msg += `, failed on ${failed.length}: ${failed.join(", ")}`;
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ export function confirmDeselectAll(
|
|||
app: App,
|
||||
fileCount: number,
|
||||
): Promise<boolean> {
|
||||
const noun = fileCount === 1 ? "file" : "files";
|
||||
const noun = fileCount === 1 ? "note" : "notes";
|
||||
const message = `This will deselect ${fileCount} ${noun}. Are you sure?`;
|
||||
return new Promise<boolean>(resolve => {
|
||||
new ConfirmModal(app, message, resolve).open();
|
||||
|
|
@ -75,7 +75,7 @@ export function confirmEmptyValue(
|
|||
property: string,
|
||||
fileCount: number,
|
||||
): Promise<boolean> {
|
||||
const noun = fileCount === 1 ? "file" : "files";
|
||||
const noun = fileCount === 1 ? "note" : "notes";
|
||||
const message = `New value is empty. This will clear "${property}" on ${fileCount} ${noun}.`;
|
||||
return new Promise<boolean>(resolve => {
|
||||
new ConfirmModal(app, message, resolve).open();
|
||||
|
|
@ -87,7 +87,7 @@ export function confirmReplace(
|
|||
property: string,
|
||||
fileCount: number,
|
||||
): Promise<boolean> {
|
||||
const noun = fileCount === 1 ? "file" : "files";
|
||||
const noun = fileCount === 1 ? "note" : "notes";
|
||||
const message = `This will replace all existing "${property}" values on ${fileCount} ${noun}. Existing values will be lost.`;
|
||||
return new Promise<boolean>(resolve => {
|
||||
new ConfirmModal(app, message, resolve).open();
|
||||
|
|
@ -98,7 +98,7 @@ export function confirmDeleteFiles(
|
|||
app: App,
|
||||
fileCount: number,
|
||||
): Promise<boolean> {
|
||||
const noun = fileCount === 1 ? "file" : "files";
|
||||
const noun = fileCount === 1 ? "note" : "notes";
|
||||
const message = `This will delete ${fileCount} ${noun}. Are you sure?`;
|
||||
return new Promise<boolean>(resolve => {
|
||||
new ConfirmModal(app, message, resolve, {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ export async function deselectAll(
|
|||
const files = getSelectedFiles(app, selectionProperty);
|
||||
|
||||
if (files.length === 0) {
|
||||
new Notice("No files are selected");
|
||||
new Notice("No notes are selected");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -33,15 +33,15 @@ export async function deselectAll(
|
|||
const {succeeded, failed, cancelled, total} = result;
|
||||
if (cancelled) {
|
||||
new Notice(
|
||||
`Deselected ${succeeded} of ${total} file${total === 1 ? "" : "s"} (cancelled)`,
|
||||
`Deselected ${succeeded} of ${total} note${total === 1 ? "" : "s"} (cancelled)`,
|
||||
);
|
||||
} else if (failed.length === 0) {
|
||||
new Notice(
|
||||
`Deselected ${succeeded} file${succeeded === 1 ? "" : "s"}`,
|
||||
`Deselected ${succeeded} note${succeeded === 1 ? "" : "s"}`,
|
||||
);
|
||||
} else {
|
||||
new Notice(
|
||||
`Deselected ${succeeded} file${succeeded === 1 ? "" : "s"}, failed on ${failed.length}: ${failed.join(", ")}`,
|
||||
`Deselected ${succeeded} note${succeeded === 1 ? "" : "s"}, failed on ${failed.length}: ${failed.join(", ")}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
12
src/main.ts
12
src/main.ts
|
|
@ -17,13 +17,13 @@ export default class BulkPropertiesPlugin extends Plugin {
|
|||
|
||||
this.statusBarEl = this.addStatusBarItem();
|
||||
|
||||
this.addRibbonIcon("list-checks", "Bulk edit selected files", () => {
|
||||
this.addRibbonIcon("list-checks", "Bulk edit selected notes", () => {
|
||||
new BulkEditModal(this.app, this).open();
|
||||
});
|
||||
|
||||
this.addCommand({
|
||||
id: "bulk-edit-selected",
|
||||
name: "Bulk edit selected files",
|
||||
name: "Bulk edit selected notes",
|
||||
callback: () => {
|
||||
new BulkEditModal(this.app, this).open();
|
||||
},
|
||||
|
|
@ -31,7 +31,7 @@ export default class BulkPropertiesPlugin extends Plugin {
|
|||
|
||||
this.addCommand({
|
||||
id: "deselect-all",
|
||||
name: "Deselect all files",
|
||||
name: "Deselect all notes",
|
||||
callback: () => {
|
||||
void deselectAll(this.app, this.settings.selectionProperty);
|
||||
},
|
||||
|
|
@ -39,7 +39,7 @@ export default class BulkPropertiesPlugin extends Plugin {
|
|||
|
||||
this.addCommand({
|
||||
id: "remove-selection-property",
|
||||
name: "Remove selection property from all files",
|
||||
name: "Remove selection property from all notes",
|
||||
callback: () => {
|
||||
removeSelectionProperty(
|
||||
this.app,
|
||||
|
|
@ -65,7 +65,7 @@ export default class BulkPropertiesPlugin extends Plugin {
|
|||
this.registerEvent(
|
||||
this.app.workspace.on("editor-menu", (menu) => {
|
||||
menu.addItem((item) => {
|
||||
item.setTitle("Bulk edit selected files")
|
||||
item.setTitle("Bulk edit selected notes")
|
||||
.setIcon("list-checks")
|
||||
.onClick(() => {
|
||||
new BulkEditModal(this.app, this).open();
|
||||
|
|
@ -129,7 +129,7 @@ export default class BulkPropertiesPlugin extends Plugin {
|
|||
).length;
|
||||
if (count > 0) {
|
||||
this.statusBarEl.setText(
|
||||
`${count} file${count === 1 ? "" : "s"} selected`,
|
||||
`${count} note${count === 1 ? "" : "s"} selected`,
|
||||
);
|
||||
} else {
|
||||
this.statusBarEl.empty();
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ class ConfirmRemoveModal extends Modal {
|
|||
|
||||
const n = this.fileCount;
|
||||
contentEl.createEl("p", {
|
||||
text: `This will modify ${n} file${n === 1 ? "" : "s"} in your vault by removing the "${this.property}" property from them. Are you sure?`,
|
||||
text: `This will modify ${n} note${n === 1 ? "" : "s"} in your vault by removing the "${this.property}" property from them. Are you sure?`,
|
||||
});
|
||||
|
||||
new Setting(contentEl)
|
||||
|
|
@ -66,7 +66,7 @@ export function removeSelectionProperty(
|
|||
|
||||
if (files.length === 0) {
|
||||
new Notice(
|
||||
`No files have the "${selectionProperty}" property`,
|
||||
`No notes have the "${selectionProperty}" property`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
|
@ -107,15 +107,15 @@ async function doRemove(
|
|||
const {succeeded, failed, cancelled, total} = result;
|
||||
if (cancelled) {
|
||||
new Notice(
|
||||
`Removed "${selectionProperty}" from ${succeeded} of ${total} file${total === 1 ? "" : "s"} (cancelled)`,
|
||||
`Removed "${selectionProperty}" from ${succeeded} of ${total} note${total === 1 ? "" : "s"} (cancelled)`,
|
||||
);
|
||||
} else if (failed.length === 0) {
|
||||
new Notice(
|
||||
`Removed "${selectionProperty}" from ${succeeded} file${succeeded === 1 ? "" : "s"}`,
|
||||
`Removed "${selectionProperty}" from ${succeeded} note${succeeded === 1 ? "" : "s"}`,
|
||||
);
|
||||
} else {
|
||||
new Notice(
|
||||
`Removed from ${succeeded} file${succeeded === 1 ? "" : "s"}, failed on ${failed.length}: ${failed.join(", ")}`,
|
||||
`Removed from ${succeeded} note${succeeded === 1 ? "" : "s"}, failed on ${failed.length}: ${failed.join(", ")}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -149,7 +149,7 @@ export class BulkPropertiesSettingTab extends PluginSettingTab {
|
|||
|
||||
const selectionSetting = new Setting(containerEl)
|
||||
.setName("Selection property")
|
||||
.setDesc("The checkbox property used to mark files as selected")
|
||||
.setDesc("The checkbox property used to mark notes as selected")
|
||||
.addSearch(search => {
|
||||
const isConflicting = (name: string) =>
|
||||
this.plugin.settings.properties.some(p => p.name === name);
|
||||
|
|
@ -253,7 +253,7 @@ export class BulkPropertiesSettingTab extends PluginSettingTab {
|
|||
|
||||
new Setting(containerEl)
|
||||
.setName("Show selection count in status bar")
|
||||
.setDesc("Display the number of selected files in the status bar")
|
||||
.setDesc("Display the number of selected notes in the status bar")
|
||||
.addToggle(toggle => {
|
||||
makeToggleAccessible(toggle, "Show selection count in status bar", this.plugin.settings.showStatusBarCount);
|
||||
toggle
|
||||
|
|
|
|||
Loading…
Reference in a new issue