-
Notifications
You must be signed in to change notification settings - Fork 2
feat: Allow localization of the "Next actions" and "Milestones" headers #24
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
5f121ce
d0d1f80
e299600
7167ad9
74423c4
05d1950
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,10 @@ | ||
| import type { App } from "obsidian"; | ||
| import { TFile, normalizePath } from "obsidian"; | ||
| import { FlowProject, GTDProcessingResult, PluginSettings, PersonNote } from "./types"; | ||
| import { FlowProject, GTDProcessingResult, PluginSettings, PersonNote, nextActionsHeaderText } from "./types"; | ||
| import { GTDResponseValidationError, FileNotFoundError, ValidationError } from "./errors"; | ||
| import { EditableItem } from "./inbox-types"; | ||
| import { sanitizeFileName } from "./validation"; | ||
| import escapeRegex from "regex-escape"; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🌐 Web query:
💡 Result: Short answer: regex-escape is a CommonJS module that exports a single function (module.exports = RegexEscape). The DefinitelyTyped types use export = RegexEscape (not an ES named export). Import as CommonJS (require) or with TypeScript import-equals; default-style ESM imports rely on CJS/ESM interop. Examples:
Sources: Use TypeScript import-equals syntax for the The 🤖 Prompt for AI Agents |
||
|
|
||
| export class FileWriter { | ||
| constructor( | ||
|
|
@@ -244,7 +245,7 @@ export class FileWriter { | |
| const isDone = markAsDone[i] || false; | ||
| content = this.addActionToSection( | ||
| content, | ||
| "## Next actions", | ||
| `## ${nextActionsHeaderText(this.settings)}`, | ||
| action, | ||
| isWaiting, | ||
| isDone, | ||
|
|
@@ -413,62 +414,64 @@ export class FileWriter { | |
| } | ||
|
|
||
| // Add next actions to the template | ||
| let content = templateContent; | ||
| let actionsText = ""; | ||
| const dueDateSuffix = dueDate ? ` 📅 ${dueDate}` : ""; | ||
|
|
||
| // Find the "## Next actions" section and add the actions | ||
| const nextActionsRegex = /(## Next actions\s*\n)(\s*)/; | ||
| const match = content.match(nextActionsRegex); | ||
| if (result.nextActions && result.nextActions.length > 0) { | ||
| actionsText = | ||
| result.nextActions | ||
| .map((action, i) => { | ||
| const isDone = markAsDone[i] || false; | ||
| const isWaiting = waitingFor[i] || false; | ||
|
|
||
| if (match) { | ||
| let actionsText = ""; | ||
| const dueDateSuffix = dueDate ? ` 📅 ${dueDate}` : ""; | ||
|
|
||
| if (result.nextActions && result.nextActions.length > 0) { | ||
| actionsText = | ||
| result.nextActions | ||
| .map((action, i) => { | ||
| const isDone = markAsDone[i] || false; | ||
| const isWaiting = waitingFor[i] || false; | ||
|
|
||
| let checkbox: string; | ||
| let actionText = action; | ||
|
|
||
| if (isDone) { | ||
| checkbox = "- [x]"; | ||
| const completionDate = new Date().toISOString().split("T")[0]; | ||
| actionText = `${action} ✅ ${completionDate}`; | ||
| } else if (isWaiting) { | ||
| checkbox = "- [w]"; | ||
| } else { | ||
| checkbox = "- [ ]"; | ||
| } | ||
|
|
||
| return `${checkbox} ${actionText}${dueDateSuffix}`; | ||
| }) | ||
| .join("\n") + "\n"; | ||
| } else if (result.nextAction) { | ||
| const isDone = markAsDone[0] || false; | ||
| const isWaiting = waitingFor[0] || false; | ||
|
|
||
| let checkbox: string; | ||
| let actionText = result.nextAction; | ||
|
|
||
| if (isDone) { | ||
| checkbox = "- [x]"; | ||
| const completionDate = new Date().toISOString().split("T")[0]; | ||
| actionText = `${result.nextAction} ✅ ${completionDate}`; | ||
| } else if (isWaiting) { | ||
| checkbox = "- [w]"; | ||
| } else { | ||
| checkbox = "- [ ]"; | ||
| } | ||
| let checkbox: string; | ||
| let actionText = action; | ||
|
|
||
| if (isDone) { | ||
| checkbox = "- [x]"; | ||
| const completionDate = new Date().toISOString().split("T")[0]; | ||
| actionText = `${action} ✅ ${completionDate}`; | ||
| } else if (isWaiting) { | ||
| checkbox = "- [w]"; | ||
| } else { | ||
| checkbox = "- [ ]"; | ||
| } | ||
|
|
||
| return `${checkbox} ${actionText}${dueDateSuffix}`; | ||
| }) | ||
| .join("\n") + "\n"; | ||
| } else if (result.nextAction) { | ||
| const isDone = markAsDone[0] || false; | ||
| const isWaiting = waitingFor[0] || false; | ||
|
|
||
| let checkbox: string; | ||
| let actionText = result.nextAction; | ||
|
|
||
| actionsText = `${checkbox} ${actionText}${dueDateSuffix}\n`; | ||
| if (isDone) { | ||
| checkbox = "- [x]"; | ||
| const completionDate = new Date().toISOString().split("T")[0]; | ||
| actionText = `${result.nextAction} ✅ ${completionDate}`; | ||
| } else if (isWaiting) { | ||
| checkbox = "- [w]"; | ||
| } else { | ||
| checkbox = "- [ ]"; | ||
| } | ||
|
|
||
| actionsText = `${checkbox} ${actionText}${dueDateSuffix}\n`; | ||
| } | ||
|
|
||
| // Find the "## Next actions" section and add the actions | ||
| let content = templateContent; | ||
| const nextActionsRegex = new RegExp(`(##\\s*${escapeRegex(nextActionsHeaderText(this.settings))}\\s*(?:\\n|$))(\\s*)`); | ||
| const match = content.match(nextActionsRegex); | ||
|
|
||
| if (match) { | ||
| // Replace "## Next actions\n<any whitespace>" with "## Next actions\n<actions>\n" | ||
| // This ensures proper spacing regardless of template whitespace | ||
| content = content.replace(nextActionsRegex, `$1${actionsText}\n`); | ||
| } else { | ||
| // Fallback: Append at the end if the section is not found | ||
| content += `\n## ${nextActionsHeaderText(this.settings)}\n${actionsText}\n`; | ||
| } | ||
|
|
||
| return content; | ||
|
|
@@ -490,6 +493,7 @@ export class FileWriter { | |
| const date = this.formatDate(new Date()); | ||
| const title = result.projectOutcome || originalItem; | ||
| const originalItemDescription = this.formatOriginalInboxItem(originalItem, sourceNoteLink); | ||
| const nextActionsHeader = nextActionsHeaderText(this.settings); | ||
|
|
||
| // Format sphere tags for YAML list format | ||
| const sphereTagsList = | ||
|
|
@@ -524,7 +528,7 @@ status: ${this.settings.defaultStatus}`; | |
|
|
||
| ${originalItemDescription} | ||
|
|
||
| ## Next actions | ||
| ## ${nextActionsHeader} | ||
| `; | ||
|
|
||
| // Handle multiple next actions or single next action | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.