diff --git a/docs/docs/changelog.md b/docs/docs/changelog.md index 39b830d..3e62b1b 100644 --- a/docs/docs/changelog.md +++ b/docs/docs/changelog.md @@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - You can now sort tasks alphabetically by name using `alphabetical` or `alphabeticalDescending` in the sorting field - You can now provide 'time' to the show field on a query. This will only render the time of the task (unless the end of the task is on a different day than the start). +- You can now provide 'section' to the show field on a query to display only the section name for tasks in sections. ### 🐛 Bug Fixes diff --git a/docs/docs/query-blocks.md b/docs/docs/query-blocks.md index 7d34be5..d5e04f4 100644 --- a/docs/docs/query-blocks.md +++ b/docs/docs/query-blocks.md @@ -125,8 +125,15 @@ The possible values are: - `deadline`: render the deadline of the task - `description`: render the description of the task - `project`: render the project (and section, if applicable) of the task +- `section`: render only the section name of the task (if the task has a section) - `labels`: render the labels of the task +:::note + +If both `project` and `section` are specified, only `project` will be shown to avoid redundancy. The `project` option already includes section information when available. + +::: + For example: ```` diff --git a/docs/docs/translation-status.json b/docs/docs/translation-status.json index e3c8604..36d43ed 100644 --- a/docs/docs/translation-status.json +++ b/docs/docs/translation-status.json @@ -2,7 +2,7 @@ { "name": "English", "code": "en", - "completed": 206, + "completed": 207, "missing": 0, "percent": 100 }, @@ -10,7 +10,7 @@ "name": "Nederlands", "code": "nl", "completed": 146, - "missing": 60, + "missing": 61, "percent": 71 } ] \ No newline at end of file diff --git a/plugin/src/i18n/langs/en.ts b/plugin/src/i18n/langs/en.ts index 7f34347..4b83d40 100644 --- a/plugin/src/i18n/langs/en.ts +++ b/plugin/src/i18n/langs/en.ts @@ -253,6 +253,8 @@ export const en: Translations = { unknownKey: (key: string) => `Found unexpected query key '${key}'. Is this a typo?`, dueAndTime: "Both 'due' and 'time' show options are set. The 'time' option will be ignored when 'due' is present.", + projectAndSection: + "Both 'project' and 'section' show options are set. The 'section' option will be ignored when 'project' is present.", }, groupedHeaders: { noDueDate: "No due date", diff --git a/plugin/src/i18n/translation.ts b/plugin/src/i18n/translation.ts index 0af80cc..f57efa2 100644 --- a/plugin/src/i18n/translation.ts +++ b/plugin/src/i18n/translation.ts @@ -227,6 +227,7 @@ export type Translations = { jsonQuery: string; unknownKey: (key: string) => string; dueAndTime: string; + projectAndSection: string; }; groupedHeaders: { noDueDate: string; diff --git a/plugin/src/query/__snapshots__/parser.test.ts.snap b/plugin/src/query/__snapshots__/parser.test.ts.snap index 38162fc..e777909 100644 --- a/plugin/src/query/__snapshots__/parser.test.ts.snap +++ b/plugin/src/query/__snapshots__/parser.test.ts.snap @@ -66,9 +66,9 @@ exports[`parseQuery - error message snapshots > show array must contain strings [Error: Field 'show' has the following issues: Invalid input: expected "none" Field 'show' elements have the following issues: - Item 'show[0]': Invalid option: expected one of "due"|"date"|"description"|"labels"|"project"|"deadline"|"time" - Item 'show[1]': Invalid option: expected one of "due"|"date"|"description"|"labels"|"project"|"deadline"|"time" - Item 'show[2]': Invalid option: expected one of "due"|"date"|"description"|"labels"|"project"|"deadline"|"time"] + Item 'show[0]': Invalid option: expected one of "due"|"date"|"description"|"labels"|"project"|"deadline"|"time"|"section" + Item 'show[1]': Invalid option: expected one of "due"|"date"|"description"|"labels"|"project"|"deadline"|"time"|"section" + Item 'show[2]': Invalid option: expected one of "due"|"date"|"description"|"labels"|"project"|"deadline"|"time"|"section"] `; exports[`parseQuery - error message snapshots > show field - invalid literal (not 'none') 1`] = ` @@ -81,8 +81,8 @@ exports[`parseQuery - error message snapshots > show must have valid enum values [Error: Field 'show' has the following issues: Invalid input: expected "none" Field 'show' elements have the following issues: - Item 'show[0]': Invalid option: expected one of "due"|"date"|"description"|"labels"|"project"|"deadline"|"time" - Item 'show[1]': Invalid option: expected one of "due"|"date"|"description"|"labels"|"project"|"deadline"|"time"] + Item 'show[0]': Invalid option: expected one of "due"|"date"|"description"|"labels"|"project"|"deadline"|"time"|"section" + Item 'show[1]': Invalid option: expected one of "due"|"date"|"description"|"labels"|"project"|"deadline"|"time"|"section"] `; exports[`parseQuery - error message snapshots > sorting array must contain strings 1`] = ` diff --git a/plugin/src/query/parser.test.ts b/plugin/src/query/parser.test.ts index e03aa79..c840dda 100644 --- a/plugin/src/query/parser.test.ts +++ b/plugin/src/query/parser.test.ts @@ -269,6 +269,28 @@ describe("parseQuery", () => { show: new Set([ShowMetadataVariant.Due, ShowMetadataVariant.Time]), }), }, + { + description: "with show including section", + input: { + filter: "bar", + show: ["section"], + }, + expectedOutput: makeQuery({ + filter: "bar", + show: new Set([ShowMetadataVariant.Section]), + }), + }, + { + description: "with show including section and project", + input: { + filter: "bar", + show: ["section", "project"], + }, + expectedOutput: makeQuery({ + filter: "bar", + show: new Set([ShowMetadataVariant.Section, ShowMetadataVariant.Project]), + }), + }, ]; for (const tc of testcases) { @@ -319,6 +341,17 @@ describe("parseQuery - warnings", () => { "Both 'due' and 'time' show options are set. The 'time' option will be ignored when 'due' is present.", ], }, + { + description: "Both project and section in show options", + input: { + filter: "bar", + show: ["project", "section"], + }, + expectedWarnings: [ + "This query is written using JSON. This is deprecated and will be removed in a future version. Please use YAML instead.", + "Both 'project' and 'section' show options are set. The 'section' option will be ignored when 'project' is present.", + ], + }, ]; for (const tc of testcases) { diff --git a/plugin/src/query/parser.ts b/plugin/src/query/parser.ts index fa0f9ac..1c5f199 100644 --- a/plugin/src/query/parser.ts +++ b/plugin/src/query/parser.ts @@ -108,6 +108,7 @@ const showSchema = lookupToEnum({ project: ShowMetadataVariant.Project, deadline: ShowMetadataVariant.Deadline, time: ShowMetadataVariant.Time, + section: ShowMetadataVariant.Section, }); const groupBySchema = lookupToEnum({ @@ -171,6 +172,10 @@ function parseObjectZod(query: Record): [Query, QueryWarning[]] warnings.push(t().query.warning.dueAndTime); } + if (show.has(ShowMetadataVariant.Project) && show.has(ShowMetadataVariant.Section)) { + warnings.push(t().query.warning.projectAndSection); + } + return [ { name: out.data.name, diff --git a/plugin/src/query/query.ts b/plugin/src/query/query.ts index e2b919d..1e4a095 100644 --- a/plugin/src/query/query.ts +++ b/plugin/src/query/query.ts @@ -17,6 +17,7 @@ export enum ShowMetadataVariant { Description = 3, Deadline = 4, Time = 5, + Section = 6, } export enum GroupVariant { diff --git a/plugin/src/ui/query/task/TaskMetadata.tsx b/plugin/src/ui/query/task/TaskMetadata.tsx index 070fd49..22a9598 100644 --- a/plugin/src/ui/query/task/TaskMetadata.tsx +++ b/plugin/src/ui/query/task/TaskMetadata.tsx @@ -51,6 +51,27 @@ const projectMeta: MetadataDefinition = { side: "right", }; +const sectionMeta: MetadataDefinition = { + name: "section", + isShown: (query, task) => + query.show.has(ShowMetadataVariant.Section) && + !query.show.has(ShowMetadataVariant.Project) && + task.section !== undefined, + content: (task) => [ + { + // biome-ignore lint/style/noNonNullAssertion: We enforce this above in 'isShown'. + content: task.section!.name, + }, + ], + icons: { + after: { + id: "gallery-vertical", + shouldRender: (settings) => settings.renderProjectIcon, + }, + }, + side: "right", +}; + const dueDateMeta: MetadataDefinition = { name: "due", isShown: (query, task) => query.show.has(ShowMetadataVariant.Due) && task.due !== undefined, @@ -128,6 +149,7 @@ const timeOnlyMeta: MetadataDefinition = { const metadata: MetadataDefinition[] = [ projectMeta, + sectionMeta, dueDateMeta, deadlineMeta, labelsMeta,