mirror of
https://github.com/taskgenius/taskgenius-plugin.git
synced 2026-07-22 06:40:25 +00:00
Merge 3f38bb54a8 into ee821b0625
This commit is contained in:
commit
bdae4ded9b
6 changed files with 98 additions and 16 deletions
|
|
@ -124,6 +124,22 @@ describe("File Metadata Inheritance", () => {
|
|||
// tags应该被继承,但不会覆盖非继承字段
|
||||
});
|
||||
|
||||
test("should use filename when inherited frontmatter project is true", () => {
|
||||
const content = "- [ ] Task without explicit project";
|
||||
const fileMetadata = {
|
||||
project: true,
|
||||
};
|
||||
|
||||
const tasks = parser.parseLegacy(
|
||||
content,
|
||||
"Projects/My Awesome Project.md",
|
||||
fileMetadata
|
||||
);
|
||||
|
||||
expect(tasks).toHaveLength(1);
|
||||
expect(tasks[0].metadata.project).toBe("My Awesome Project");
|
||||
});
|
||||
|
||||
test("should work independently of project configuration", () => {
|
||||
// 项目配置为null,验证不会崩溃
|
||||
mockPlugin.settings.projectConfig = null;
|
||||
|
|
@ -515,4 +531,4 @@ describe("File Metadata Inheritance", () => {
|
|||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -199,6 +199,29 @@ describe("FileMetadataTaskParser", () => {
|
|||
expect(dueDateTask?.status).toBe(" "); // Due dates are typically incomplete
|
||||
});
|
||||
|
||||
it("should use filename as project name when frontmatter project is true", () => {
|
||||
const filePath = "Projects/My Awesome Project.md";
|
||||
const fileContent = "# Test File";
|
||||
const fileCache = {
|
||||
frontmatter: {
|
||||
title: "Test Task",
|
||||
todo: true,
|
||||
project: true,
|
||||
},
|
||||
tags: [],
|
||||
};
|
||||
|
||||
const result = parser.parseFileForTasks(
|
||||
filePath,
|
||||
fileContent,
|
||||
fileCache as any
|
||||
);
|
||||
|
||||
expect(result.errors).toHaveLength(0);
|
||||
expect(result.tasks).toHaveLength(1);
|
||||
expect(result.tasks[0].metadata.project).toBe("My Awesome Project");
|
||||
});
|
||||
|
||||
it("should not create tasks when parsing is disabled", () => {
|
||||
const disabledConfig: FileParsingConfiguration = {
|
||||
enableFileMetadataParsing: false,
|
||||
|
|
|
|||
|
|
@ -331,6 +331,21 @@ describe('FileSource', () => {
|
|||
expect(task!.metadata.project).toBe('Test Project');
|
||||
});
|
||||
|
||||
it('should use filename as project name when frontmatter project is true', async () => {
|
||||
const fileCache = {
|
||||
frontmatter: {
|
||||
dueDate: '2024-01-01',
|
||||
project: true
|
||||
}
|
||||
};
|
||||
mockApp.metadataCache.getFileCache.mockReturnValue(fileCache);
|
||||
|
||||
const task = await fileSource.createFileTask('Projects/My Awesome Project.md');
|
||||
|
||||
expect(task).toBeTruthy();
|
||||
expect(task!.metadata.project).toBe('My Awesome Project');
|
||||
});
|
||||
|
||||
it('should use default status when not specified', async () => {
|
||||
const fileCache = {
|
||||
frontmatter: {
|
||||
|
|
@ -436,4 +451,4 @@ describe('FileSource', () => {
|
|||
await expect(fileSource.refresh()).resolves.not.toThrow();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -143,6 +143,7 @@ export class MarkdownTaskParser {
|
|||
const inheritedMetadata = this.inheritFileMetadata(
|
||||
metadata,
|
||||
isSubtask,
|
||||
filePath,
|
||||
);
|
||||
|
||||
// Extract time components from task content using enhanced time parsing
|
||||
|
|
@ -1736,6 +1737,7 @@ export class MarkdownTaskParser {
|
|||
private inheritFileMetadata(
|
||||
taskMetadata: Record<string, string>,
|
||||
isSubtask: boolean = false,
|
||||
filePath: string = "",
|
||||
): Record<string, string> {
|
||||
// Helper function to convert priority values to numbers
|
||||
const convertPriorityValue = (value: any): string => {
|
||||
|
|
@ -1861,22 +1863,34 @@ export class MarkdownTaskParser {
|
|||
try {
|
||||
const configuredProjectKey =
|
||||
this.config.projectConfig?.metadataConfig?.metadataKey;
|
||||
const configuredProjectValue =
|
||||
configuredProjectKey !== undefined
|
||||
? this.fileMetadata[configuredProjectKey]
|
||||
: undefined;
|
||||
if (
|
||||
configuredProjectKey &&
|
||||
this.fileMetadata[configuredProjectKey] !== undefined &&
|
||||
this.fileMetadata[configuredProjectKey] !== null &&
|
||||
String(
|
||||
this.fileMetadata[configuredProjectKey],
|
||||
).trim() !== ""
|
||||
configuredProjectValue !== undefined &&
|
||||
configuredProjectValue !== null
|
||||
) {
|
||||
if (
|
||||
inherited.project === undefined ||
|
||||
inherited.project === null ||
|
||||
inherited.project === ""
|
||||
) {
|
||||
inherited.project = String(
|
||||
this.fileMetadata[configuredProjectKey],
|
||||
).trim();
|
||||
if (configuredProjectValue === true) {
|
||||
const fileName =
|
||||
filePath.split("/").pop() || filePath;
|
||||
inherited.project = fileName.replace(
|
||||
/\.md$/i,
|
||||
"",
|
||||
);
|
||||
} else if (
|
||||
typeof configuredProjectValue === "string" &&
|
||||
configuredProjectValue.trim() !== ""
|
||||
) {
|
||||
inherited.project =
|
||||
configuredProjectValue.trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {}
|
||||
|
|
@ -1939,6 +1953,10 @@ export class MarkdownTaskParser {
|
|||
// Convert priority values to numbers before inheritance
|
||||
if (key === "priority") {
|
||||
inherited[key] = convertPriorityValue(value);
|
||||
} else if (key === "project" && value === true) {
|
||||
const fileName =
|
||||
filePath.split("/").pop() || filePath;
|
||||
inherited[key] = fileName.replace(/\.md$/i, "");
|
||||
} else {
|
||||
inherited[key] = String(value);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -907,10 +907,13 @@ export class FileSource {
|
|||
// 2. Metadata mapping (e.g., custom_project mapped to project via metadataMappings)
|
||||
// 3. Tag extraction (#project/xxx) - lowest priority, only if frontmatter has nothing
|
||||
const projectVal = resolvedFrontmatter.project ?? projectFromTags;
|
||||
const projectValue: string | undefined =
|
||||
projectVal !== undefined && projectVal !== null
|
||||
? String(projectVal)
|
||||
: undefined;
|
||||
let projectValue: string | undefined;
|
||||
if (projectVal === true) {
|
||||
const fileName = filePath.split("/").pop() || filePath;
|
||||
projectValue = fileName.replace(/\.md$/i, "");
|
||||
} else if (typeof projectVal === "string" && projectVal.trim()) {
|
||||
projectValue = projectVal.trim();
|
||||
}
|
||||
|
||||
const shouldStripProjectTags =
|
||||
!resolvedFrontmatter.project &&
|
||||
|
|
|
|||
|
|
@ -336,9 +336,16 @@ export class FileMetadataTaskParser {
|
|||
const detectedProject = this.detectProjectFromFile(filePath, frontmatter, fileCache);
|
||||
if (detectedProject) {
|
||||
metadata.project = detectedProject;
|
||||
} else if (frontmatter.project) {
|
||||
} else if (frontmatter.project === true) {
|
||||
// Legacy boolean semantics: `project: true` means use filename
|
||||
const fileName = filePath.split("/").pop() || filePath;
|
||||
metadata.project = fileName.replace(/\.md$/i, "");
|
||||
} else if (
|
||||
typeof frontmatter.project === "string" &&
|
||||
frontmatter.project.trim()
|
||||
) {
|
||||
// Fallback to legacy project field
|
||||
metadata.project = String(frontmatter.project);
|
||||
metadata.project = frontmatter.project.trim();
|
||||
}
|
||||
if (frontmatter.context) {
|
||||
metadata.context = String(frontmatter.context);
|
||||
|
|
|
|||
Loading…
Reference in a new issue