refactor: centralize frontmatter key handling and expose per-key status reads

This commit is contained in:
Aleix Soler 2025-11-21 18:42:55 +01:00
parent b222295109
commit d3f358bc96
9 changed files with 66 additions and 1829 deletions

View file

@ -5,8 +5,7 @@ import {
BaseNoteStatusService,
NoteStatusService,
} from "@/core/noteStatusService";
import settingsService from "@/core/settingsService";
import { getKnownFrontmatterKeys } from "@/utils/frontmatterMappings";
import { getAllFrontmatterKeys } from "@/core/statusKeyHelpers";
interface CurrentNoteInfo {
file: TFile | null;
@ -32,9 +31,7 @@ export const useCurrentNote = () => {
const noteStatusService = new NoteStatusService(activeFile);
noteStatusService.populateStatuses();
const statusMetadataKeys = getKnownFrontmatterKeys(
settingsService.settings,
);
const statusMetadataKeys = getAllFrontmatterKeys();
const statusesByKey: Record<string, NoteStatus[]> = {};
statusMetadataKeys.forEach((key) => {
const statuses = noteStatusService.getStatusesForKey(key);

View file

@ -5,8 +5,7 @@ import {
BaseNoteStatusService,
NoteStatusService,
} from "@/core/noteStatusService";
import settingsService from "@/core/settingsService";
import { getKnownFrontmatterKeys } from "@/utils/frontmatterMappings";
import { getAllFrontmatterKeys } from "@/core/statusKeyHelpers";
export interface VaultStats {
totalNotes: number;
@ -34,9 +33,7 @@ export const useVaultStats = () => {
const files = BaseNoteStatusService.app.vault.getFiles();
const availableStatuses =
BaseNoteStatusService.getAllAvailableStatuses();
const statusMetadataKeys = getKnownFrontmatterKeys(
settingsService.settings,
);
const statusMetadataKeys = getAllFrontmatterKeys();
let notesWithStatus = 0;
const statusDistribution: Record<string, number> = {};

View file

@ -5,7 +5,7 @@ import eventBus from "./eventBus";
import { VIEW_TYPE_EXAMPLE } from "../integrations/views/grouped-status-view";
import { isExperimentalFeatureEnabled } from "@/utils/experimentalFeatures";
import { GroupedStatuses, NoteStatus } from "@/types/noteStatus";
import { getKnownFrontmatterKeys } from "@/utils/frontmatterMappings";
import { getAllFrontmatterKeys } from "./statusKeyHelpers";
export class CommandsService {
private plugin: Plugin;
@ -213,9 +213,7 @@ export class CommandsService {
if (!statuses || statuses.length === 0) return false;
const keys = getKnownFrontmatterKeys(
settingsService.settings,
);
const keys = getAllFrontmatterKeys();
const queries = Array.from(
new Set(
statuses.flatMap((status) =>

View file

@ -10,10 +10,8 @@ import settingsService from "@/core/settingsService";
import eventBus from "./eventBus";
import statusStoreManager from "./statusStoreManager";
import type { StatusStore } from "./statusStores/types";
import {
getKnownFrontmatterKeys,
resolveFrontmatterKeysForStatus,
} from "@/utils/frontmatterMappings";
import { resolveFrontmatterKeysForStatus } from "@/utils/frontmatterMappings";
import { getFrontmatterKeysForFile } from "./statusKeyHelpers";
export abstract class BaseNoteStatusService {
static app: App;
@ -137,17 +135,8 @@ export class NoteStatusService extends BaseNoteStatusService {
return this.file.extension === "md";
}
private getKeysForReading(): string[] {
const defaultKey = settingsService.settings.tagPrefix;
if (!this.isMarkdownFile()) {
return [defaultKey];
}
const knownKeys = getKnownFrontmatterKeys(settingsService.settings);
return [defaultKey, ...knownKeys.filter((key) => key !== defaultKey)];
}
private collectIdentifiersForFile(): string[] {
const keysToRead = this.getKeysForReading();
const keysToRead = getFrontmatterKeysForFile(this.file);
const seen = new Set<string>();
const identifiers: string[] = [];
@ -263,6 +252,16 @@ export class NoteStatusService extends BaseNoteStatusService {
}
public getStatusesForKey(frontmatterTagName: string): NoteStatusType[] {
const isValidKey =
!this.isMarkdownFile() &&
frontmatterTagName !== settingsService.settings.tagPrefix
? false
: true;
if (!isValidKey) {
return [];
}
const identifiers = this.statusStore
.getStatuses(this.file, frontmatterTagName)
.map((identifier) => identifier?.toString())
@ -334,7 +333,9 @@ export class NoteStatusService extends BaseNoteStatusService {
async clearStatus(frontmatterTagName: string): Promise<boolean> {
const keys = new Set<string>([frontmatterTagName]);
if (this.isMarkdownFile()) {
this.getKeysForReading().forEach((key) => keys.add(key));
getFrontmatterKeysForFile(this.file).forEach((key) =>
keys.add(key),
);
}
const cleared = await this.runAcrossKeys([...keys], (key) =>
@ -392,9 +393,9 @@ export class NoteStatusService extends BaseNoteStatusService {
});
});
const knownKeys = new Set([
const knownKeys = new Set<string>([
frontmatterTagName,
...this.getStatusMetadataKeys(),
...getFrontmatterKeysForFile(this.file),
]);
knownKeys.forEach((key) => {
if (!keyMap.has(key)) {
@ -530,15 +531,6 @@ export class MultipleNoteStatusService extends BaseNoteStatusService {
return this.files.length;
}
private getKeysForReading(file: TFile): string[] {
const defaultKey = settingsService.settings.tagPrefix;
if (file.extension !== "md") {
return [defaultKey];
}
const knownKeys = getKnownFrontmatterKeys(settingsService.settings);
return [defaultKey, ...knownKeys.filter((key) => key !== defaultKey)];
}
public populateStatuses(): void {
const defaultKey = settingsService.settings.tagPrefix;
this.statuses = { [defaultKey]: [] };
@ -553,7 +545,7 @@ export class MultipleNoteStatusService extends BaseNoteStatusService {
return;
}
const keys = this.getKeysForReading(file);
const keys = getFrontmatterKeysForFile(file);
keys.forEach((key) => {
const identifiers = store.getStatuses(file, key);
identifiers.forEach((identifier) => {

31
core/statusKeyHelpers.ts Normal file
View file

@ -0,0 +1,31 @@
import { TFile } from "obsidian";
import settingsService from "./settingsService";
import { getKnownFrontmatterKeys } from "@/utils/frontmatterMappings";
const ensureOrderedKeys = (keys: string[]): string[] => {
const defaultKey = settingsService.settings.tagPrefix;
const seen = new Set<string>();
const ordered: string[] = [];
[defaultKey, ...keys].forEach((key) => {
const trimmed = key?.trim();
if (!trimmed || seen.has(trimmed)) return;
seen.add(trimmed);
ordered.push(trimmed);
});
return ordered;
};
export const getAllFrontmatterKeys = (): string[] => {
const keys = getKnownFrontmatterKeys(settingsService.settings);
return ensureOrderedKeys(keys);
};
export const getFrontmatterKeysForFile = (file: TFile): string[] => {
if (file.extension !== "md") {
return [settingsService.settings.tagPrefix];
}
return getAllFrontmatterKeys();
};

View file

@ -6,9 +6,8 @@ import {
NoteStatusService,
} from "@/core/noteStatusService";
import eventBus from "@/core/eventBus";
import settingsService from "@/core/settingsService";
import { NoteStatus } from "@/types/noteStatus";
import { getKnownFrontmatterKeys } from "@/utils/frontmatterMappings";
import { getAllFrontmatterKeys } from "@/core/statusKeyHelpers";
export const VIEW_TYPE_GROUPED_DASHBOARD = "grouped-dashboard-view";
@ -72,9 +71,7 @@ export class GroupedDashboardView extends ItemView {
private processFiles = (files: FileItem[]): GroupedByStatus => {
const result: GroupedByStatus = {};
const statusMetadataKeys = getKnownFrontmatterKeys(
settingsService.settings,
);
const statusMetadataKeys = getAllFrontmatterKeys();
const availableStatuses =
BaseNoteStatusService.getAllAvailableStatuses();

View file

@ -13,7 +13,7 @@ import {
import eventBus from "@/core/eventBus";
import settingsService from "@/core/settingsService";
import { NoteStatus } from "@/types/noteStatus";
import { getKnownFrontmatterKeys } from "@/utils/frontmatterMappings";
import { getAllFrontmatterKeys } from "@/core/statusKeyHelpers";
export const VIEW_TYPE_EXAMPLE = "grouped-status-view";
@ -56,9 +56,7 @@ export class GroupedStatusView extends ItemView {
private processFiles = (files: FileItem[]): GroupedByStatus => {
const result: GroupedByStatus = {};
const statusMetadataKeys = getKnownFrontmatterKeys(
settingsService.settings,
);
const statusMetadataKeys = getAllFrontmatterKeys();
const availableStatuses =
BaseNoteStatusService.getAllAvailableStatuses();

View file

@ -10,7 +10,7 @@ import settingsService from "@/core/settingsService";
import eventBus from "@/core/eventBus";
import { VaultStats } from "@/components/StatusDashboard/useVaultStats";
import { NoteStatus } from "@/types/noteStatus";
import { getKnownFrontmatterKeys } from "@/utils/frontmatterMappings";
import { getAllFrontmatterKeys } from "@/core/statusKeyHelpers";
interface AppWithCommands extends App {
commands: {
@ -62,9 +62,7 @@ export class StatusDashboardView extends ItemView {
const files = this.app.vault.getFiles();
const availableStatuses =
BaseNoteStatusService.getAllAvailableStatuses();
const statusMetadataKeys = getKnownFrontmatterKeys(
settingsService.settings,
);
const statusMetadataKeys = getAllFrontmatterKeys();
let notesWithStatus = 0;
const statusDistribution: Record<string, number> = {};
@ -130,9 +128,7 @@ export class StatusDashboardView extends ItemView {
const noteStatusService = new NoteStatusService(activeFile);
noteStatusService.populateStatuses();
const statusMetadataKeys = getKnownFrontmatterKeys(
settingsService.settings,
);
const statusMetadataKeys = getAllFrontmatterKeys();
const statusesByKey: Record<string, NoteStatus[]> = {};
statusMetadataKeys.forEach((key) => {
@ -238,7 +234,7 @@ export class StatusDashboardView extends ItemView {
private findUnassignedNotes() {
const files = this.app.vault.getMarkdownFiles();
const statusKeys = getKnownFrontmatterKeys(settingsService.settings);
const statusKeys = getAllFrontmatterKeys();
const filesWithoutStatus = files.filter((file) => {
const cachedMetadata = this.app.metadataCache.getFileCache(file);
const frontmatter = cachedMetadata?.frontmatter;
@ -272,7 +268,7 @@ export class StatusDashboardView extends ItemView {
}
private searchBySpecificStatus(statusName: string) {
const keys = getKnownFrontmatterKeys(settingsService.settings);
const keys = getAllFrontmatterKeys();
const query = keys
.map((key) => `[${key}:"${statusName}"]`)
.join(" OR ");

1771
styles.css

File diff suppressed because one or more lines are too long