diff --git a/resources/sample_vaults/Tasks-Demo/.gitignore b/resources/sample_vaults/Tasks-Demo/.gitignore new file mode 100644 index 0000000000..3688c1a792 --- /dev/null +++ b/resources/sample_vaults/Tasks-Demo/.gitignore @@ -0,0 +1 @@ +Tasks Plugin - Review and check your Statuses* diff --git a/src/Config/SettingsTab.ts b/src/Config/SettingsTab.ts index c9e917651b..781e20ee5d 100644 --- a/src/Config/SettingsTab.ts +++ b/src/Config/SettingsTab.ts @@ -4,6 +4,7 @@ import type TasksPlugin from '../main'; import { StatusRegistry } from '../StatusRegistry'; import { Status } from '../Status'; import type { StatusCollection } from '../StatusCollection'; +import { createStatusRegistryReport } from '../StatusRegistryReport'; import * as Themes from './Themes'; import { type HeadingState, TASK_FORMATS } from './Settings'; import { getSettings, isFeatureEnabled, updateGeneralSetting, updateSettings } from './Settings'; @@ -569,6 +570,36 @@ export class SettingsTab extends PluginSettingTab { }); addAllUnknownStatuses.infoEl.remove(); + /* -------------------- 'Review and check your Statuses' button -------------------- */ + const createMermaidDiagram = new Setting(containerEl).addButton((button) => { + const buttonName = 'Review and check your Statuses'; + button + .setButtonText(buttonName) + .setCta() + .onClick(async () => { + // Generate a new file unique file name, in the root of the vault + const now = window.moment(); + const formattedDateTime = now.format('YYYY-MM-DD HH-mm-ss'); + const filename = `Tasks Plugin - ${buttonName} ${formattedDateTime}.md`; + + // Create the report + const version = this.plugin.manifest.version; + const statusRegistry = StatusRegistry.getInstance(); + const fileContent = createStatusRegistryReport(statusRegistry, buttonName, version); + + // Save the file + const file = await app.vault.create(filename, fileContent); + + // And open the new file + const leaf = this.app.workspace.getLeaf(true); + await leaf.openFile(file); + }); + button.setTooltip( + 'Create a new file in the root of the vault, containing a Mermaid diagram of the current status settings.', + ); + }); + createMermaidDiagram.infoEl.remove(); + /* -------------------- 'Reset Custom Status Types to Defaults' button -------------------- */ const clearCustomStatuses = new Setting(containerEl).addButton((button) => { button diff --git a/src/StatusRegistryReport.ts b/src/StatusRegistryReport.ts new file mode 100644 index 0000000000..d421d9c4cc --- /dev/null +++ b/src/StatusRegistryReport.ts @@ -0,0 +1,19 @@ +import type { StatusRegistry } from './StatusRegistry'; + +export function createStatusRegistryReport(statusRegistry: StatusRegistry, buttonName: string, versionString: string) { + // Ideas for further improvement + // - Actually make it an informative report, that shows any issues in settings with duplicate symbols. + // - Show any 'next status symbols' that are not known to the plugin. + // - Show any status transitions that won't work with recurring tasks currently, as DONE not followed by TODO. + + const detailed = true; + const mermaidText = statusRegistry.mermaidDiagram(detailed); + return `# ${buttonName} + +This file was created by the Obsidian Tasks plugin (version ${versionString}) to help visualise the task statuses in this vault. + +You can delete this file any time. + + +${mermaidText}`; +} diff --git a/tests/StatusRegistryReport.test.StatusRegistryReport_should_create_a_report.approved.md b/tests/StatusRegistryReport.test.StatusRegistryReport_should_create_a_report.approved.md new file mode 100644 index 0000000000..e6afd77da7 --- /dev/null +++ b/tests/StatusRegistryReport.test.StatusRegistryReport_should_create_a_report.approved.md @@ -0,0 +1,23 @@ +# Review and check your Statuses + +This file was created by the Obsidian Tasks plugin (version x.y.z) to help visualise the task statuses in this vault. + +You can delete this file any time. + + + +```mermaid +flowchart LR +1["'Todo'
[ ] -> [x]
(TODO)"] +2["'In Progress'
[/] -> [x]
(IN_PROGRESS)"] +3["'Done'
[x] -> [ ]
(DONE)"] +4["'Cancelled'
[-] -> [ ]
(CANCELLED)"] +5["'Question'
[Q] -> [A]
(NON_TASK)"] +6["'Answer'
[A] -> [Q]
(NON_TASK)"] +1 --> 3 +2 --> 3 +3 --> 1 +4 --> 1 +5 --> 6 +6 --> 5 +``` diff --git a/tests/StatusRegistryReport.test.ts b/tests/StatusRegistryReport.test.ts new file mode 100644 index 0000000000..08521620ce --- /dev/null +++ b/tests/StatusRegistryReport.test.ts @@ -0,0 +1,21 @@ +import { StatusRegistry } from '../src/StatusRegistry'; +import { StatusConfiguration, StatusType } from '../src/StatusConfiguration'; +import { createStatusRegistryReport } from '../src/StatusRegistryReport'; +import { verifyWithFileExtension } from './TestingTools/ApprovalTestHelpers'; + +describe('StatusRegistryReport', function () { + it('should create a report', () => { + // Arrange + const statusRegistry = new StatusRegistry(); + statusRegistry.add(new StatusConfiguration('Q', 'Question', 'A', false, StatusType.NON_TASK)); + statusRegistry.add(new StatusConfiguration('A', 'Answer', 'Q', false, StatusType.NON_TASK)); + const reportName = 'Review and check your Statuses'; + + // Act + const version = 'x.y.z'; // lower-case, as the capitalised version would get edited at the next release. + const report = createStatusRegistryReport(statusRegistry, reportName, version); + + // Assert + verifyWithFileExtension(report, '.md'); + }); +});