Skip to content
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

refactor: extract QueryLayoutOptions from LayoutOptions #2521

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
e509b58
refactor: . add QueryLayoutOptions base class
ilandikov Dec 19, 2023
e3aa49d
refactor: . add _queryLayoutOptions field to Query.ts
ilandikov Dec 19, 2023
fe668c2
refactor: . add queryLayoutOptions getter
ilandikov Dec 19, 2023
bc705d5
refactor: . add queryLayoutOptions field to TaskLineRenderer
ilandikov Dec 19, 2023
ac4495f
refactor: . initialize queryLayoutOptions from layoutOptions
ilandikov Dec 19, 2023
d27008b
refactor: ! use queryLayoutOptions
ilandikov Dec 19, 2023
f1f41de
refactor: ! use queryLayoutOptions in Query
ilandikov Dec 19, 2023
6c06202
refactor: . add queryLayoutOptions in IQuery
ilandikov Dec 19, 2023
cc04f00
refactor: ! use queryLayoutOptions in QueryRenderer
ilandikov Dec 19, 2023
b1bc736
refactor: . add queryLayoutOptions field to TaskLayout
ilandikov Dec 19, 2023
ace70b7
refactor: ! use queryLayoutOptions in TaskLayout
ilandikov Dec 19, 2023
3d8c36f
refactor: . add shortMode1 parameter to componentToString()
ilandikov Dec 19, 2023
d818f5a
refactor: . add shortMode1 parameter to DataviewTaskSerializer.compon…
ilandikov Dec 19, 2023
22baa34
refactor: . simplify parameters of componentToString()
ilandikov Dec 19, 2023
2085f42
refactor: ! use queryLayoutOptions in TaskLineRenderer & DefaultTaskS…
ilandikov Dec 19, 2023
0749ce9
refactor: ! Query now stores its own QueryLayoutOptions
ilandikov Dec 19, 2023
b2a394a
test: - prepare to add QueryLayoutOptions to TaskLineRenderer constru…
ilandikov Dec 19, 2023
d0643ce
refactor: - add QueryLayoutOptions parameter to TaskLineRenderer cons…
ilandikov Dec 19, 2023
72b3541
refactor: - add QueryLayoutOptions to TaskLayout constructor
ilandikov Dec 19, 2023
f717b5e
refactor: - remove inheritance between QueryLayoutOptions & LayoutOpt…
ilandikov Dec 19, 2023
d35bc6e
jsdoc: document LayoutOptions & QueryLayoutOptions
ilandikov Dec 19, 2023
7bbe236
test: ! reorder renderListItem() parameters for consistency
ilandikov Dec 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
10 changes: 10 additions & 0 deletions src/IQuery.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { QueryLayoutOptions } from './QueryLayoutOptions';
import type { LayoutOptions } from './TaskLayout';
import type { Task } from './Task';
import type { Grouper } from './Query/Grouper';
Expand Down Expand Up @@ -48,6 +49,15 @@ export interface IQuery {
*/
layoutOptions: LayoutOptions;

/**
* Any layout options the query engine should be aware of or
* used in the query.
*
* @type {QueryLayoutOptions}
* @memberof IQuery
*/
queryLayoutOptions: QueryLayoutOptions;

/**
* Main method for executing the query. This will be called by the
* code block processor registered in Obsidian. It takes the Task collection
Expand Down
2 changes: 2 additions & 0 deletions src/InlineRenderer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { MarkdownPostProcessorContext, Plugin } from 'obsidian';
import { MarkdownRenderChild } from 'obsidian';
import { GlobalFilter } from './Config/GlobalFilter';
import { QueryLayoutOptions } from './QueryLayoutOptions';
import { Task } from './Task';
import { LayoutOptions } from './TaskLayout';
import { TaskLineRenderer } from './TaskLineRenderer';
Expand Down Expand Up @@ -91,6 +92,7 @@ export class InlineRenderer {
obsidianComponent: childComponent,
parentUlElement: element,
layoutOptions: new LayoutOptions(),
queryLayoutOptions: new QueryLayoutOptions(),
});

// The section index is the nth task within this section.
Expand Down
20 changes: 13 additions & 7 deletions src/Query/Query.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { QueryLayoutOptions } from '../QueryLayoutOptions';
import { expandPlaceholders } from '../Scripting/ExpandPlaceholders';
import { makeQueryContext } from '../Scripting/QueryContext';
import { LayoutOptions } from '../TaskLayout';
Expand All @@ -24,6 +25,7 @@ export class Query implements IQuery {
private _limit: number | undefined = undefined;
private _taskGroupLimit: number | undefined = undefined;
private _layoutOptions: LayoutOptions = new LayoutOptions();
private _queryLayoutOptions: QueryLayoutOptions = new QueryLayoutOptions();
private _filters: Filter[] = [];
private _error: string | undefined = undefined;
private _sorting: Sorter[] = [];
Expand Down Expand Up @@ -61,10 +63,10 @@ export class Query implements IQuery {

switch (true) {
case this.shortModeRegexp.test(line):
this._layoutOptions.shortMode = true;
this._queryLayoutOptions.shortMode = true;
break;
case this.explainQueryRegexp.test(line):
this._layoutOptions.explainQuery = true;
this._queryLayoutOptions.explainQuery = true;
break;
case this.ignoreGlobalQueryRegexp.test(line):
this._ignoreGlobalQuery = true;
Expand Down Expand Up @@ -217,6 +219,10 @@ ${source}`;
return this._layoutOptions;
}

public get queryLayoutOptions(): QueryLayoutOptions {
return this._queryLayoutOptions;
}

public get filters(): Filter[] {
return this._filters;
}
Expand Down Expand Up @@ -290,13 +296,13 @@ Problem line: "${line}"`;

switch (option) {
case 'task count':
this._layoutOptions.hideTaskCount = hide;
this._queryLayoutOptions.hideTaskCount = hide;
break;
case 'backlink':
this._layoutOptions.hideBacklinks = hide;
this._queryLayoutOptions.hideBacklinks = hide;
break;
case 'postpone button':
this._layoutOptions.hidePostponeButton = hide;
this._queryLayoutOptions.hidePostponeButton = hide;
break;
case 'priority':
this._layoutOptions.hidePriority = hide;
Expand All @@ -320,10 +326,10 @@ Problem line: "${line}"`;
this._layoutOptions.hideRecurrenceRule = hide;
break;
case 'edit button':
this._layoutOptions.hideEditButton = hide;
this._queryLayoutOptions.hideEditButton = hide;
break;
case 'urgency':
this._layoutOptions.hideUrgency = hide;
this._queryLayoutOptions.hideUrgency = hide;
break;
case 'tags':
this._layoutOptions.hideTags = hide;
Expand Down
14 changes: 14 additions & 0 deletions src/QueryLayoutOptions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* Options to control {@link QueryRenderer} behaviour.
*
* @see LayoutOptions
*/
export class QueryLayoutOptions {
hidePostponeButton: boolean = false;
hideTaskCount: boolean = false;
hideBacklinks: boolean = false;
hideEditButton: boolean = false;
hideUrgency: boolean = true;
shortMode: boolean = false;
explainQuery: boolean = false;
}
17 changes: 9 additions & 8 deletions src/QueryRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ class QueryRenderChild extends MarkdownRenderChild {
// See https://github.com/obsidian-tasks-group/obsidian-tasks/issues/2160
this.query.debug(`[render] Render called: plugin state: ${state}; searching ${tasks.length} tasks`);

if (this.query.layoutOptions.explainQuery) {
if (this.query.queryLayoutOptions.explainQuery) {
this.createExplanation(content);
}

Expand Down Expand Up @@ -221,7 +221,7 @@ class QueryRenderChild extends MarkdownRenderChild {
}

private async createTaskList(tasks: Task[], content: HTMLDivElement): Promise<void> {
const layout = new TaskLayout(this.query.layoutOptions);
const layout = new TaskLayout(this.query.layoutOptions, this.query.queryLayoutOptions);
const taskList = content.createEl('ul');
taskList.addClasses(['contains-task-list', 'plugin-tasks-query-result']);
taskList.addClasses(layout.taskListHiddenClasses);
Expand All @@ -232,6 +232,7 @@ class QueryRenderChild extends MarkdownRenderChild {
obsidianComponent: this,
parentUlElement: taskList,
layoutOptions: this.query.layoutOptions,
queryLayoutOptions: this.query.queryLayoutOptions,
});

for (const [taskIndex, task] of tasks.entries()) {
Expand All @@ -244,21 +245,21 @@ class QueryRenderChild extends MarkdownRenderChild {

const extrasSpan = listItem.createSpan('task-extras');

if (!this.query.layoutOptions.hideUrgency) {
if (!this.query.queryLayoutOptions.hideUrgency) {
this.addUrgency(extrasSpan, task);
}

const shortMode = this.query.layoutOptions.shortMode;
const shortMode = this.query.queryLayoutOptions.shortMode;

if (!this.query.layoutOptions.hideBacklinks) {
if (!this.query.queryLayoutOptions.hideBacklinks) {
this.addBacklinks(extrasSpan, task, shortMode, isFilenameUnique);
}

if (!this.query.layoutOptions.hideEditButton) {
if (!this.query.queryLayoutOptions.hideEditButton) {
this.addEditButton(extrasSpan, task);
}

if (!this.query.layoutOptions.hidePostponeButton && shouldShowPostponeButton(task)) {
if (!this.query.queryLayoutOptions.hidePostponeButton && shouldShowPostponeButton(task)) {
this.addPostponeButton(extrasSpan, task, shortMode);
}

Expand Down Expand Up @@ -454,7 +455,7 @@ class QueryRenderChild extends MarkdownRenderChild {
}

private addTaskCount(content: HTMLDivElement, queryResult: QueryResult) {
if (!this.query.layoutOptions.hideTaskCount) {
if (!this.query.queryLayoutOptions.hideTaskCount) {
content.createDiv({
text: queryResult.totalTasksCountDisplayText(),
cls: 'tasks-count',
Expand Down
32 changes: 18 additions & 14 deletions src/TaskLayout.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
import { QueryLayoutOptions } from './QueryLayoutOptions';

/**
* Various rendering options for a query.
* Various rendering options of tasks in a query.
* See applyOptions below when adding options here.
*
* @see QueryLayoutOptions
*/
export class LayoutOptions {
hidePostponeButton: boolean = false;
hideTaskCount: boolean = false;
hideBacklinks: boolean = false;
hidePriority: boolean = false;
hideCreatedDate: boolean = false;
hideStartDate: boolean = false;
hideScheduledDate: boolean = false;
hideDoneDate: boolean = false;
hideDueDate: boolean = false;
hideRecurrenceRule: boolean = false;
hideEditButton: boolean = false;
hideUrgency: boolean = true;
hideTags: boolean = false;
shortMode: boolean = false;
explainQuery: boolean = false;
}

export type TaskLayoutComponent =
Expand Down Expand Up @@ -53,14 +50,21 @@ export class TaskLayout {
public shownTaskLayoutComponents: TaskLayoutComponent[];
public hiddenTaskLayoutComponents: TaskLayoutComponent[] = [];
public options: LayoutOptions;
public queryLayoutOptions: QueryLayoutOptions;
public taskListHiddenClasses: string[] = [];

constructor(options?: LayoutOptions) {
constructor(options?: LayoutOptions, queryLayoutOptions?: QueryLayoutOptions) {
if (options) {
this.options = options;
} else {
this.options = new LayoutOptions();
}
if (queryLayoutOptions) {
this.queryLayoutOptions = queryLayoutOptions;
} else {
this.queryLayoutOptions = new QueryLayoutOptions();
}

this.shownTaskLayoutComponents = this.defaultLayout;
this.applyOptions();
}
Expand Down Expand Up @@ -92,16 +96,16 @@ export class TaskLayout {
// (see https://github.com/obsidian-tasks-group/obsidian-tasks/issues/1866).
// This can benefit from some refactoring, i.e. render these components in a similar flow rather than
// separately.
[this.options.hideUrgency, 'urgency'],
[this.options.hideBacklinks, 'backlinks'],
[this.options.hideEditButton, 'edit-button'],
[this.options.hidePostponeButton, 'postpone-button'],
[this.queryLayoutOptions.hideUrgency, 'urgency'],
[this.queryLayoutOptions.hideBacklinks, 'backlinks'],
[this.queryLayoutOptions.hideEditButton, 'edit-button'],
[this.queryLayoutOptions.hidePostponeButton, 'postpone-button'],
];
for (const [hide, component] of componentsToGenerateClassesOnly) {
this.generateHiddenClassForTaskList(hide, component);
}

if (this.options.shortMode) this.taskListHiddenClasses.push('tasks-layout-short-mode');
if (this.queryLayoutOptions.shortMode) this.taskListHiddenClasses.push('tasks-layout-short-mode');
}

private generateHiddenClassForTaskList(hide: boolean, component: string) {
Expand Down
17 changes: 14 additions & 3 deletions src/TaskLineRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { Component, MarkdownRenderer } from 'obsidian';
import { GlobalFilter } from './Config/GlobalFilter';
import { TASK_FORMATS, getSettings } from './Config/Settings';
import { replaceTaskWithTasks } from './File';
import type { QueryLayoutOptions } from './QueryLayoutOptions';
import type { Task } from './Task';
import * as taskModule from './Task';
import { TaskFieldRenderer } from './TaskFieldRenderer';
Expand All @@ -28,6 +29,7 @@ export class TaskLineRenderer {
private readonly obsidianComponent: Component | null;
private readonly parentUlElement: HTMLElement;
private readonly layoutOptions: LayoutOptions;
private readonly queryLayoutOptions: QueryLayoutOptions;

private static async obsidianMarkdownRenderer(
text: string,
Expand All @@ -51,22 +53,27 @@ export class TaskLineRenderer {
* @param parentUlElement HTML element where the task shall be rendered.
*
* @param layoutOptions See {@link LayoutOptions}.
*
* @param queryLayoutOptions See {@link QueryLayoutOptions}.
*/
constructor({
textRenderer = TaskLineRenderer.obsidianMarkdownRenderer,
obsidianComponent,
parentUlElement,
layoutOptions,
queryLayoutOptions,
}: {
textRenderer?: TextRenderer;
obsidianComponent: Component | null;
parentUlElement: HTMLElement;
layoutOptions: LayoutOptions;
queryLayoutOptions: QueryLayoutOptions;
}) {
this.textRenderer = textRenderer;
this.obsidianComponent = obsidianComponent;
this.parentUlElement = parentUlElement;
this.layoutOptions = layoutOptions;
this.queryLayoutOptions = queryLayoutOptions;
}

/**
Expand Down Expand Up @@ -140,19 +147,23 @@ export class TaskLineRenderer {
li.setAttribute('data-task-status-type', task.status.type);
checkbox.setAttribute('data-line', taskIndex.toString());

if (this.layoutOptions.shortMode) {
if (this.queryLayoutOptions.shortMode) {
this.addTooltip(task, textSpan, isFilenameUnique);
}

return li;
}

private async taskToHtml(task: Task, parentElement: HTMLElement, li: HTMLLIElement): Promise<void> {
const taskLayout = new TaskLayout(this.layoutOptions);
const taskLayout = new TaskLayout(this.layoutOptions, this.queryLayoutOptions);
const emojiSerializer = TASK_FORMATS.tasksPluginEmoji.taskSerializer;
// Render and build classes for all the task's visible components
for (const component of taskLayout.shownTaskLayoutComponents) {
const componentString = emojiSerializer.componentToString(task, taskLayout, component);
const componentString = emojiSerializer.componentToString(
task,
taskLayout.queryLayoutOptions.shortMode,
component,
);
if (componentString) {
// Create the text span that will hold the rendered component
const span = document.createElement('span');
Expand Down
6 changes: 3 additions & 3 deletions src/TaskSerializer/DataviewTaskSerializer.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { TaskLayout, TaskLayoutComponent } from '../TaskLayout';
import type { TaskLayoutComponent } from '../TaskLayout';
import type { Task } from '../Task';
import { Priority } from '../Task';
import { DefaultTaskSerializer } from './DefaultTaskSerializer';
Expand Down Expand Up @@ -111,8 +111,8 @@ export class DataviewTaskSerializer extends DefaultTaskSerializer {
}
}

public componentToString(task: Task, layout: TaskLayout, component: TaskLayoutComponent) {
const stringComponent = super.componentToString(task, layout, component);
public componentToString(task: Task, shortMode: boolean, component: TaskLayoutComponent) {
const stringComponent = super.componentToString(task, shortMode, component);
const notInlineFieldComponents: TaskLayoutComponent[] = ['blockLink', 'description'];
const shouldMakeInlineField = stringComponent !== '' && !notInlineFieldComponents.includes(component);
return shouldMakeInlineField
Expand Down