Skip to content

Commit 7a9a4a6

Browse files
authored
Merge pull request #2631 from ilandikov/refactor-TaskLayoutOptions-enum
refactor: convert `TaskLayoutOptions` to `enum`
2 parents ccfc77f + 9018fc6 commit 7a9a4a6

File tree

8 files changed

+116
-117
lines changed

8 files changed

+116
-117
lines changed

src/Layout/TaskLayoutOptions.ts

Lines changed: 22 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,26 @@
1-
export type TaskLayoutComponent =
1+
/**
2+
* {@link Task} fields used for rendering. Use references to this enum ({@link TaskLayoutComponent.Id})
3+
* instead of plain string values (`id`).
4+
*
5+
* The order here determines the order that task fields are rendered and written to markdown.
6+
*/
7+
export enum TaskLayoutComponent {
28
// NEW_TASK_FIELD_EDIT_REQUIRED
3-
| 'description'
4-
| 'priority'
5-
| 'recurrenceRule'
6-
| 'createdDate'
7-
| 'startDate'
8-
| 'scheduledDate'
9-
| 'dueDate'
10-
| 'doneDate'
11-
| 'cancelledDate'
12-
| 'blockedBy'
13-
| 'id'
14-
| 'blockLink';
9+
Description = 'description',
10+
Id = 'id',
11+
BlockedBy = 'blockedBy',
12+
Priority = 'priority',
13+
RecurrenceRule = 'recurrenceRule',
14+
CreatedDate = 'createdDate',
15+
StartDate = 'startDate',
16+
ScheduledDate = 'scheduledDate',
17+
DueDate = 'dueDate',
18+
CancelledDate = 'cancelledDate',
19+
DoneDate = 'doneDate',
20+
BlockLink = 'blockLink',
21+
}
1522

16-
// The order here determines the order that task fields are rendered and written to markdown.
17-
export const taskLayoutComponents: TaskLayoutComponent[] = [
18-
// NEW_TASK_FIELD_EDIT_REQUIRED
19-
'description',
20-
'id',
21-
'blockedBy',
22-
'priority',
23-
'recurrenceRule',
24-
'createdDate',
25-
'startDate',
26-
'scheduledDate',
27-
'dueDate',
28-
'cancelledDate',
29-
'doneDate',
30-
'blockLink',
31-
];
23+
export const taskLayoutComponents = Object.values(TaskLayoutComponent);
3224

3325
/**
3426
* Various rendering options of tasks in a query.
@@ -88,7 +80,7 @@ export class TaskLayoutOptions {
8880
public get toggleableComponents() {
8981
return taskLayoutComponents.filter((component) => {
9082
// Description and blockLink are always shown
91-
return component !== 'description' && component !== 'blockLink';
83+
return component !== TaskLayoutComponent.Description && component !== TaskLayoutComponent.BlockLink;
9284
});
9385
}
9486

src/Query/Query.ts

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,22 @@
1-
import { TaskLayoutOptions } from '../Layout/TaskLayoutOptions';
1+
import { getSettings } from '../Config/Settings';
2+
import type { IQuery } from '../IQuery';
23
import { QueryLayoutOptions } from '../Layout/QueryLayoutOptions';
4+
import { TaskLayoutComponent, TaskLayoutOptions } from '../Layout/TaskLayoutOptions';
5+
import { errorMessageForException } from '../lib/ExceptionTools';
6+
import { logging } from '../lib/logging';
37
import { expandPlaceholders } from '../Scripting/ExpandPlaceholders';
48
import { makeQueryContext } from '../Scripting/QueryContext';
59
import type { Task } from '../Task/Task';
6-
import type { IQuery } from '../IQuery';
7-
import { getSettings } from '../Config/Settings';
8-
import { errorMessageForException } from '../lib/ExceptionTools';
9-
import { logging } from '../lib/logging';
10-
import { Sort } from './Sort/Sort';
11-
import type { Sorter } from './Sort/Sorter';
12-
import { TaskGroups } from './Group/TaskGroups';
10+
import { Explainer } from './Explain/Explainer';
11+
import type { Filter } from './Filter/Filter';
1312
import * as FilterParser from './FilterParser';
1413
import type { Grouper } from './Group/Grouper';
15-
import type { Filter } from './Filter/Filter';
14+
import { TaskGroups } from './Group/TaskGroups';
1615
import { QueryResult } from './QueryResult';
1716
import { scan } from './Scanner';
1817
import { SearchInfo } from './SearchInfo';
19-
import { Explainer } from './Explain/Explainer';
18+
import { Sort } from './Sort/Sort';
19+
import type { Sorter } from './Sort/Sorter';
2020

2121
export class Query implements IQuery {
2222
/** Note: source is the raw source, before expanding any placeholders */
@@ -283,28 +283,28 @@ Problem line: "${line}"`;
283283
this._queryLayoutOptions.hidePostponeButton = hide;
284284
break;
285285
case 'priority':
286-
this._taskLayoutOptions.setVisibility('priority', !hide);
286+
this._taskLayoutOptions.setVisibility(TaskLayoutComponent.Priority, !hide);
287287
break;
288288
case 'cancelled date':
289-
this._taskLayoutOptions.setVisibility('cancelledDate', !hide);
289+
this._taskLayoutOptions.setVisibility(TaskLayoutComponent.CancelledDate, !hide);
290290
break;
291291
case 'created date':
292-
this._taskLayoutOptions.setVisibility('createdDate', !hide);
292+
this._taskLayoutOptions.setVisibility(TaskLayoutComponent.CreatedDate, !hide);
293293
break;
294294
case 'start date':
295-
this._taskLayoutOptions.setVisibility('startDate', !hide);
295+
this._taskLayoutOptions.setVisibility(TaskLayoutComponent.StartDate, !hide);
296296
break;
297297
case 'scheduled date':
298-
this._taskLayoutOptions.setVisibility('scheduledDate', !hide);
298+
this._taskLayoutOptions.setVisibility(TaskLayoutComponent.ScheduledDate, !hide);
299299
break;
300300
case 'due date':
301-
this._taskLayoutOptions.setVisibility('dueDate', !hide);
301+
this._taskLayoutOptions.setVisibility(TaskLayoutComponent.DueDate, !hide);
302302
break;
303303
case 'done date':
304-
this._taskLayoutOptions.setVisibility('doneDate', !hide);
304+
this._taskLayoutOptions.setVisibility(TaskLayoutComponent.DoneDate, !hide);
305305
break;
306306
case 'recurrence rule':
307-
this._taskLayoutOptions.setVisibility('recurrenceRule', !hide);
307+
this._taskLayoutOptions.setVisibility(TaskLayoutComponent.RecurrenceRule, !hide);
308308
break;
309309
case 'edit button':
310310
this._queryLayoutOptions.hideEditButton = hide;
@@ -316,10 +316,10 @@ Problem line: "${line}"`;
316316
this._taskLayoutOptions.setTagsVisibility(!hide);
317317
break;
318318
case 'id':
319-
this._taskLayoutOptions.setVisibility('id', !hide);
319+
this._taskLayoutOptions.setVisibility(TaskLayoutComponent.Id, !hide);
320320
break;
321321
case 'depends on':
322-
this._taskLayoutOptions.setVisibility('blockedBy', !hide);
322+
this._taskLayoutOptions.setVisibility(TaskLayoutComponent.BlockedBy, !hide);
323323
break;
324324
default:
325325
this.setError('do not understand hide/show option', line);

src/Renderer/TaskLineRenderer.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@ import type { Moment } from 'moment';
22
import { Component, MarkdownRenderer } from 'obsidian';
33
import { GlobalFilter } from '../Config/GlobalFilter';
44
import { TASK_FORMATS, getSettings } from '../Config/Settings';
5-
import { replaceTaskWithTasks } from '../Obsidian/File';
6-
import type { TaskLayoutComponent, TaskLayoutOptions } from '../Layout/TaskLayoutOptions';
75
import type { QueryLayoutOptions } from '../Layout/QueryLayoutOptions';
8-
import type { Task } from '../Task/Task';
9-
import { StatusMenu } from '../ui/Menus/StatusMenu';
6+
import { TaskLayoutComponent, type TaskLayoutOptions } from '../Layout/TaskLayoutOptions';
7+
import { replaceTaskWithTasks } from '../Obsidian/File';
108
import { StatusRegistry } from '../Statuses/StatusRegistry';
9+
import type { Task } from '../Task/Task';
1110
import { TaskRegularExpressions } from '../Task/TaskRegularExpressions';
11+
import { StatusMenu } from '../ui/Menus/StatusMenu';
1212
import { TaskFieldRenderer } from './TaskFieldRenderer';
1313

1414
/**
@@ -195,7 +195,7 @@ export class TaskLineRenderer {
195195
// So if the priority was not rendered, force it through the pipe of getting the component data for the
196196
// priority field.
197197
if (li.dataset.taskPriority === undefined) {
198-
fieldRenderer.addDataAttribute(li, task, 'priority');
198+
fieldRenderer.addDataAttribute(li, task, TaskLayoutComponent.Priority);
199199
}
200200
}
201201

@@ -208,7 +208,7 @@ export class TaskLineRenderer {
208208
component: TaskLayoutComponent,
209209
task: Task,
210210
) {
211-
if (component === 'description') {
211+
if (component === TaskLayoutComponent.Description) {
212212
componentString = GlobalFilter.getInstance().removeAsWordFromDependingOnSettings(componentString);
213213

214214
const { debugSettings } = getSettings();
@@ -270,7 +270,7 @@ export class TaskLineRenderer {
270270
else return null;
271271
}
272272

273-
if (component === 'description') {
273+
if (component === TaskLayoutComponent.Description) {
274274
const tags = internalSpan.getElementsByClassName('tag');
275275
for (let i = 0; i < tags.length; i++) {
276276
const tagName = tags[i].textContent;

src/TaskSerializer/DataviewTaskSerializer.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import type { TaskLayoutComponent } from '../Layout/TaskLayoutOptions';
2-
import type { Task } from '../Task/Task';
1+
import { TaskLayoutComponent } from '../Layout/TaskLayoutOptions';
32
import { Priority } from '../Task/Priority';
3+
import type { Task } from '../Task/Task';
44
import { DefaultTaskSerializer } from './DefaultTaskSerializer';
55

66
/**
@@ -119,7 +119,10 @@ export class DataviewTaskSerializer extends DefaultTaskSerializer {
119119

120120
public componentToString(task: Task, shortMode: boolean, component: TaskLayoutComponent) {
121121
const stringComponent = super.componentToString(task, shortMode, component);
122-
const notInlineFieldComponents: TaskLayoutComponent[] = ['blockLink', 'description'];
122+
const notInlineFieldComponents: TaskLayoutComponent[] = [
123+
TaskLayoutComponent.BlockLink,
124+
TaskLayoutComponent.Description,
125+
];
123126
const shouldMakeInlineField = stringComponent !== '' && !notInlineFieldComponents.includes(component);
124127
return shouldMakeInlineField
125128
? // Having 2 (TWO) leading spaces avoids a rendering issues that makes every other

src/TaskSerializer/DefaultTaskSerializer.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { Moment } from 'moment';
2-
import { type TaskLayoutComponent, TaskLayoutOptions } from '../Layout/TaskLayoutOptions';
2+
import { TaskLayoutComponent, TaskLayoutOptions } from '../Layout/TaskLayoutOptions';
33
import { Recurrence } from '../Task/Recurrence';
44
import { Task } from '../Task/Task';
55
import { Priority } from '../Task/Priority';
@@ -136,9 +136,9 @@ export class DefaultTaskSerializer implements TaskSerializer {
136136

137137
switch (component) {
138138
// NEW_TASK_FIELD_EDIT_REQUIRED
139-
case 'description':
139+
case TaskLayoutComponent.Description:
140140
return task.description;
141-
case 'priority': {
141+
case TaskLayoutComponent.Priority: {
142142
let priority: string = '';
143143

144144
if (task.priority === Priority.Highest) {
@@ -154,29 +154,29 @@ export class DefaultTaskSerializer implements TaskSerializer {
154154
}
155155
return priority;
156156
}
157-
case 'startDate':
157+
case TaskLayoutComponent.StartDate:
158158
return symbolAndDateValue(shortMode, startDateSymbol, task.startDate);
159-
case 'createdDate':
159+
case TaskLayoutComponent.CreatedDate:
160160
return symbolAndDateValue(shortMode, createdDateSymbol, task.createdDate);
161-
case 'scheduledDate':
161+
case TaskLayoutComponent.ScheduledDate:
162162
if (task.scheduledDateIsInferred) return '';
163163
return symbolAndDateValue(shortMode, scheduledDateSymbol, task.scheduledDate);
164-
case 'doneDate':
164+
case TaskLayoutComponent.DoneDate:
165165
return symbolAndDateValue(shortMode, doneDateSymbol, task.doneDate);
166-
case 'cancelledDate':
166+
case TaskLayoutComponent.CancelledDate:
167167
return symbolAndDateValue(shortMode, cancelledDateSymbol, task.cancelledDate);
168-
case 'dueDate':
168+
case TaskLayoutComponent.DueDate:
169169
return symbolAndDateValue(shortMode, dueDateSymbol, task.dueDate);
170-
case 'recurrenceRule':
170+
case TaskLayoutComponent.RecurrenceRule:
171171
if (!task.recurrence) return '';
172172
return symbolAndStringValue(shortMode, recurrenceSymbol, task.recurrence.toText());
173-
case 'blockedBy': {
173+
case TaskLayoutComponent.BlockedBy: {
174174
if (task.blockedBy.length === 0) return '';
175175
return symbolAndStringValue(shortMode, blockedBySymbol, task.blockedBy.join(','));
176176
}
177-
case 'id':
177+
case TaskLayoutComponent.Id:
178178
return symbolAndStringValue(shortMode, idSymbol, task.id);
179-
case 'blockLink':
179+
case TaskLayoutComponent.BlockLink:
180180
return task.blockLink ?? '';
181181
default:
182182
throw new Error(`Don't know how to render task component of type '${component}'`);

tests/Layout/TaskLayoutOptions.test.ts

Lines changed: 21 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { TaskLayoutOptions } from '../../src/Layout/TaskLayoutOptions';
1+
import { TaskLayoutComponent, TaskLayoutOptions } from '../../src/Layout/TaskLayoutOptions';
22

33
describe('TaskLayoutOptions', () => {
44
it('should be constructable', () => {
@@ -26,25 +26,25 @@ describe('TaskLayoutOptions', () => {
2626
it('should show fields by default', () => {
2727
const options = new TaskLayoutOptions();
2828

29-
expect(options.isShown('priority')).toEqual(true);
30-
expect(options.isShown('createdDate')).toEqual(true);
29+
expect(options.isShown(TaskLayoutComponent.Priority)).toEqual(true);
30+
expect(options.isShown(TaskLayoutComponent.CreatedDate)).toEqual(true);
3131
});
3232

3333
it('should be able to hide a field', () => {
3434
const options = new TaskLayoutOptions();
35-
options.hide('createdDate');
35+
options.hide(TaskLayoutComponent.CreatedDate);
3636

37-
expect(options.isShown('createdDate')).toEqual(false);
37+
expect(options.isShown(TaskLayoutComponent.CreatedDate)).toEqual(false);
3838
});
3939

4040
it('should be settable via a boolean', () => {
4141
const options = new TaskLayoutOptions();
4242

43-
options.setVisibility('scheduledDate', false);
44-
expect(options.isShown('scheduledDate')).toEqual(false);
43+
options.setVisibility(TaskLayoutComponent.ScheduledDate, false);
44+
expect(options.isShown(TaskLayoutComponent.ScheduledDate)).toEqual(false);
4545

46-
options.setVisibility('scheduledDate', true);
47-
expect(options.isShown('scheduledDate')).toEqual(true);
46+
options.setVisibility(TaskLayoutComponent.ScheduledDate, true);
47+
expect(options.isShown(TaskLayoutComponent.ScheduledDate)).toEqual(true);
4848
});
4949

5050
it('should set tag visibility', () => {
@@ -75,8 +75,8 @@ describe('TaskLayoutOptions', () => {
7575
blockLink"
7676
`);
7777

78-
options.setVisibility('dueDate', false);
79-
options.setVisibility('blockLink', false);
78+
options.setVisibility(TaskLayoutComponent.DueDate, false);
79+
options.setVisibility(TaskLayoutComponent.BlockLink, false);
8080

8181
expect(options.shownComponents.join('\n')).toMatchInlineSnapshot(`
8282
"description
@@ -96,8 +96,8 @@ describe('TaskLayoutOptions', () => {
9696
const options = new TaskLayoutOptions();
9797
expect(options.hiddenComponents.join('\n')).toMatchInlineSnapshot('""');
9898

99-
options.setVisibility('startDate', false);
100-
options.setVisibility('doneDate', false);
99+
options.setVisibility(TaskLayoutComponent.StartDate, false);
100+
options.setVisibility(TaskLayoutComponent.DoneDate, false);
101101

102102
expect(options.hiddenComponents.join('\n')).toMatchInlineSnapshot(`
103103
"startDate
@@ -108,26 +108,26 @@ describe('TaskLayoutOptions', () => {
108108
it('should toggle visibility', () => {
109109
const options = new TaskLayoutOptions();
110110

111-
options.setVisibility('cancelledDate', false);
112-
options.setVisibility('priority', true);
111+
options.setVisibility(TaskLayoutComponent.CancelledDate, false);
112+
options.setVisibility(TaskLayoutComponent.Priority, true);
113113
options.setTagsVisibility(true);
114114

115115
options.toggleVisibilityExceptDescriptionAndBlockLink();
116116

117-
expect(options.isShown('cancelledDate')).toEqual(true);
118-
expect(options.isShown('priority')).toEqual(false);
117+
expect(options.isShown(TaskLayoutComponent.CancelledDate)).toEqual(true);
118+
expect(options.isShown(TaskLayoutComponent.Priority)).toEqual(false);
119119
expect(options.areTagsShown()).toEqual(false);
120120
});
121121

122122
it('should not toggle visibility of description and blockLink', () => {
123123
const options = new TaskLayoutOptions();
124-
options.setVisibility('description', true);
125-
options.setVisibility('blockLink', true);
124+
options.setVisibility(TaskLayoutComponent.Description, true);
125+
options.setVisibility(TaskLayoutComponent.BlockLink, true);
126126

127127
options.toggleVisibilityExceptDescriptionAndBlockLink();
128128

129-
expect(options.isShown('description')).toEqual(true);
130-
expect(options.isShown('blockLink')).toEqual(true);
129+
expect(options.isShown(TaskLayoutComponent.Description)).toEqual(true);
130+
expect(options.isShown(TaskLayoutComponent.BlockLink)).toEqual(true);
131131
});
132132

133133
it('should provide toggleable components', () => {

0 commit comments

Comments
 (0)