Skip to content
This repository was archived by the owner on Jul 28, 2025. It is now read-only.

Commit 502b1d5

Browse files
committed
Merge branch '111-task-filter-hide-done-tasks'
2 parents a954854 + 4366df1 commit 502b1d5

File tree

11 files changed

+156
-104
lines changed

11 files changed

+156
-104
lines changed

docs/docs/changelog.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
- New source option: query. Use your own dataview query as source of the database. Start the query with the `FROM` term, since the plugin will autocomplete the beginning with `TABLE` and the column fields[ISSUE#156](https://github.com/RafaelGB/obsidian-db-folder/issues/156)
44
- Templates for new rows added! now you can choose a template folder on settings menu, then you can choose your template file easily near of the add row button[ISSUE#48](https://github.com/RafaelGB/obsidian-db-folder/issues/48)
55
### Improved
6-
- Inline fields now supports render embed images with ![[note]] syntax. [ISSUE#136](https://github.com/RafaelGB/obsidian-db-folder/issues/136)
6+
- Inline fields now supports render embed images with `![[note]]` syntax. [ISSUE#136](https://github.com/RafaelGB/obsidian-db-folder/issues/136)
7+
- Now you can hide completed task on task column type [ISSUE#111](https://github.com/RafaelGB/obsidian-db-folder/issues/111)
78
### No longer broken
89
- If you modify the label of a column, now exist an onMouseLeave event to blur the input and be more frieldly to the user interact with the next action without a double click (once for onBlur label edition and another for your next interaction) [ISSUE#114](https://github.com/RafaelGB/obsidian-db-folder/issues/114)
910
## 1.7.2

src/cdm/FolderModel.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export interface ConfigColumn {
3838
media_width: number;
3939
media_height: number;
4040
isInline: boolean;
41+
task_hide_completed?: boolean;
4142
[key: string]: Literal;
4243
}
4344

src/components/Cell.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ export default function DefaultCell(cellProperties: Cell) {
5454
case DataTypes.TASK:
5555
// Check if there are tasks in the cell
5656
if (contextValue.value === "") break;
57+
taskRef.current.innerHTML = "";
58+
if (column.config.task_hide_completed) {
59+
contextValue.value = contextValue.value.where(
60+
(t: any) => !t.completed
61+
);
62+
}
5763
DataviewService.getDataviewAPI().taskList(
5864
contextValue.value,
5965
false,
@@ -244,6 +250,8 @@ export default function DefaultCell(cellProperties: Cell) {
244250
);
245251

246252
case DataTypes.TASK:
253+
if (column.config.task_hide_completed) {
254+
}
247255
return <div ref={taskRef} className="data-input"></div>;
248256

249257
case DataTypes.CHECKBOX:

src/components/Columns.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export async function obtainMetadataColumns(
5151
}
5252

5353
if (localSetting.show_metadata_tasks) {
54-
// If Modified is not already in the table, add it
54+
// If TASKS is not already in the table, add it
5555
yamlColumns[MetadataColumns.TASKS] = {
5656
...MetadataDatabaseColumns.TASKS,
5757
...(yamlColumns[MetadataColumns.TASKS] ?? {}),

src/components/HeaderMenu.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ActionTypes, StyleVariables } from "helpers/Constants";
1+
import { ActionTypes, DataTypes, StyleVariables } from "helpers/Constants";
22
import { dbTrim, c, getLabelHeader } from "helpers/StylesHelper";
33
import AdjustmentsIcon from "components/img/AdjustmentsIcon";
44
import React, { useContext, useEffect, useState } from "react";
@@ -278,7 +278,7 @@ const HeaderMenu = (headerMenuProps: HeaderMenuProps) => {
278278
</div>
279279
))}
280280
</div>
281-
{!column.isMetadata && (
281+
{(!column.isMetadata || column.dataType === DataTypes.TASK) && (
282282
<div
283283
style={{
284284
borderTop: `1px solid ${StyleVariables.BACKGROUND_DIVIDER}`,

src/components/modals/ColumnModal.ts

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,9 +63,9 @@ export class ColumnSettingsManager {
6363

6464
constructBody(settingHandlerResponse: ColumnHandlerResponse) {
6565
/** behavior section */
66-
behavior_settings_section(settingHandlerResponse);
66+
behavior_settings_section.run(settingHandlerResponse);
6767
/** Particular settings section */
68-
particular_settings_section(settingHandlerResponse);
68+
particular_settings_section.run(settingHandlerResponse);
6969
}
7070

7171
reset(response: ColumnHandlerResponse) {
@@ -76,11 +76,3 @@ export class ColumnSettingsManager {
7676
this.constructBody(response);
7777
}
7878
}
79-
80-
function handleColumnChanges(dispatch: Dispatch<any>, column: TableColumn) {
81-
dispatch({
82-
type: ActionTypes.MODIFY_COLUMN_CONFIG,
83-
columnId: column.id,
84-
columnConfig: column.config,
85-
});
86-
}

src/components/modals/ColumnSections.ts

Lines changed: 57 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -3,70 +3,72 @@ import { add_setting_header } from "settings/SettingsComponents";
33
import { MediaDimensionsHandler } from "components/modals/handlers/MediaDimensionsHandler";
44
import { MediaToggleHandler } from "components/modals/handlers/MediaToggleHandler";
55
import { InlineToggleHandler } from "components/modals/handlers/InlineToggleHandler";
6-
import { ColumnHandler } from "./handlers/AbstractColumnHandler";
6+
import { ColumnHandler } from "components/modals/handlers/AbstractColumnHandler";
7+
import { SelectedColumnOptionsHandler } from "components/modals/handlers/SelectedColumnOptionsHandler";
8+
import { HideCompletedTaskToggleHandler } from "components/modals/handlers/tasks/HideCompletedTaskToggleHandler";
79
import { DataTypes } from "helpers/Constants";
8-
import { SelectedColumnOptionsHandler } from "./handlers/SelectedColumnOptionsHandler";
10+
import { AbstractChain, AbstractHandler } from "patterns/AbstractFactoryChain";
911

10-
export function behavior_settings_section(settingHandlerResponse: ColumnHandlerResponse) {
11-
const behavior_section = settingHandlerResponse.containerEl.createDiv("column-section-container-behavior");
12-
add_setting_header(behavior_section, "Behavior", "h3");
13-
/**
14-
* Obtain all classes than extends from AbstractHandler
15-
*/
16-
const handlers = [
17-
new InlineToggleHandler()
18-
]
19-
let i = 1;
20-
while (i < handlers.length) {
21-
handlers[i - 1].setNext(handlers[i]);
22-
i++;
12+
class BehaviorSetttingsSection extends AbstractChain<ColumnHandlerResponse> {
13+
private dataType: string = DataTypes.TEXT;
14+
protected runBefore(columnHandlerResponse: ColumnHandlerResponse): ColumnHandlerResponse {
15+
this.dataType = columnHandlerResponse.column.dataType;
16+
return columnHandlerResponse;
17+
}
18+
protected customHandle(columnHandlerResponse: ColumnHandlerResponse): ColumnHandlerResponse {
19+
const behavior_section = columnHandlerResponse.containerEl.createDiv("column-section-container-behavior");
20+
add_setting_header(behavior_section, "Behavior", "h3");
21+
columnHandlerResponse.containerEl = behavior_section;
22+
return columnHandlerResponse;
23+
}
24+
protected getHandlers(): AbstractHandler<ColumnHandlerResponse>[] {
25+
const particularHandlers: ColumnHandler[] = [];
26+
switch (this.dataType) {
27+
case DataTypes.TASK:
28+
// do nothing
29+
break;
30+
default:
31+
particularHandlers.push(new InlineToggleHandler());
32+
}
33+
return particularHandlers;
2334
}
24-
25-
settingHandlerResponse.containerEl = behavior_section;
26-
return handlers[0]?.handle(settingHandlerResponse);
2735
}
36+
export const behavior_settings_section = new BehaviorSetttingsSection();
2837

2938
/**
3039
* Every column type has a different behavior section
31-
* @param settingHandlerResponse
32-
* @returns
3340
*/
34-
export function particular_settings_section(settingHandlerResponse: ColumnHandlerResponse): ColumnHandlerResponse {
35-
const handlers = [
36-
...addParticularInputSettings(settingHandlerResponse.column.dataType)
37-
]
38-
if (handlers.length > 0) {
39-
const particular_section = settingHandlerResponse.containerEl.createDiv("column-section-container-particular");
40-
// title of the section
41-
add_setting_header(particular_section, `Particular properties of "${settingHandlerResponse.column.dataType
42-
}" column type`, 'h3');
41+
class ParticularSetttingsSection extends AbstractChain<ColumnHandlerResponse> {
42+
private dataType: string = DataTypes.TEXT;
43+
protected runBefore(columnHandlerResponse: ColumnHandlerResponse): ColumnHandlerResponse {
44+
this.dataType = columnHandlerResponse.column.dataType;
45+
return columnHandlerResponse;
46+
}
4347

44-
let i = 1;
45-
while (i < handlers.length) {
46-
handlers[i - 1].setNext(handlers[i]);
47-
i++;
48+
protected customHandle(columnHandlerResponse: ColumnHandlerResponse): ColumnHandlerResponse {
49+
const particular_section = columnHandlerResponse.containerEl.createDiv("column-section-container-particular");
50+
// title of the section
51+
add_setting_header(particular_section, `Particular properties of "${columnHandlerResponse.column.dataType}" column type`, 'h3');
52+
columnHandlerResponse.containerEl = particular_section;
53+
return columnHandlerResponse;
54+
}
55+
protected getHandlers(): AbstractHandler<ColumnHandlerResponse>[] {
56+
const particularHandlers: ColumnHandler[] = [];
57+
switch (this.dataType) {
58+
case DataTypes.TEXT:
59+
particularHandlers.push(new MediaToggleHandler());
60+
particularHandlers.push(new MediaDimensionsHandler());
61+
break;
62+
case DataTypes.SELECT:
63+
case DataTypes.TAGS:
64+
particularHandlers.push(new SelectedColumnOptionsHandler());
65+
break;
66+
case DataTypes.TASK:
67+
particularHandlers.push(new HideCompletedTaskToggleHandler());
68+
default:
69+
break;
4870
}
49-
50-
settingHandlerResponse.containerEl = particular_section;
51-
return handlers[0]?.handle(settingHandlerResponse);
52-
} else {
53-
return settingHandlerResponse;
71+
return particularHandlers;
5472
}
5573
}
56-
57-
function addParticularInputSettings(dataType: string): ColumnHandler[] {
58-
const particularHandlers: ColumnHandler[] = [];
59-
switch (dataType) {
60-
case DataTypes.TEXT:
61-
particularHandlers.push(new MediaToggleHandler());
62-
particularHandlers.push(new MediaDimensionsHandler());
63-
break;
64-
case DataTypes.SELECT:
65-
case DataTypes.TAGS:
66-
particularHandlers.push(new SelectedColumnOptionsHandler());
67-
break;
68-
default:
69-
break;
70-
}
71-
return particularHandlers;
72-
}
74+
export const particular_settings_section = new ParticularSetttingsSection();
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { add_toggle } from "settings/SettingsComponents";
2+
import { AbstractColumnHandler } from "components/modals/handlers/AbstractColumnHandler";
3+
import { ColumnHandlerResponse } from "cdm/ModalSettingsModel";
4+
export class HideCompletedTaskToggleHandler extends AbstractColumnHandler {
5+
settingTitle: string = 'Hide completed tasks';
6+
handle(columnHandlerResponse: ColumnHandlerResponse): ColumnHandlerResponse {
7+
const { column, containerEl, view } = columnHandlerResponse;
8+
const inline_togle_promise = async (value: boolean): Promise<void> => {
9+
column.config.isInline = value;
10+
// Persist value
11+
await view.diskConfig.updateColumnConfig(column.key, {
12+
task_hide_completed: value
13+
});
14+
}
15+
add_toggle(
16+
containerEl,
17+
this.settingTitle,
18+
"Hide the completed tasks shown in the task column",
19+
column.config.task_hide_completed,
20+
inline_togle_promise
21+
);
22+
return this.goNext(columnHandlerResponse);
23+
}
24+
}

src/helpers/Constants.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { MetadataColumnsModel } from "cdm/DatabaseModel";
2-
import { TableColumn } from "cdm/FolderModel";
2+
import { ConfigColumn, TableColumn } from "cdm/FolderModel";
33
import { DatabaseSettings } from "cdm/SettingsModel";
44

55
/** Table Actions */
@@ -58,12 +58,13 @@ export const MetadataLabels = Object.freeze({
5858
TASK: 'Task',
5959
});
6060

61-
export const DEFAULT_COLUMN_CONFIG = Object.freeze({
61+
export const DEFAULT_COLUMN_CONFIG: ConfigColumn = Object.freeze({
6262
enable_media_view: true,
6363
media_width: 100,
6464
media_height: 100,
6565
isInline: false,
6666
source_data: 'current_folder',
67+
task_hide_completed: true,
6768
});
6869

6970
export const MetadataDatabaseColumns: MetadataColumnsModel = Object.freeze({
@@ -122,7 +123,7 @@ export const MetadataDatabaseColumns: MetadataColumnsModel = Object.freeze({
122123
accessor: MetadataColumns.TASKS,
123124
isMetadata: true,
124125
isDragDisabled: false,
125-
skipPersist: true,
126+
skipPersist: false,
126127
csvCandidate: false,
127128
config: DEFAULT_COLUMN_CONFIG
128129
},

src/parsers/handlers/marshall/MarshallColumnsHandler.ts

Lines changed: 36 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -19,61 +19,50 @@ export class MarshallColumnsHandler extends AbstractYamlHandler {
1919
key: 'Column1',
2020
label: 'Column 1',
2121
position: 1,
22-
config: {
23-
enable_media_view: true,
24-
media_width: 100,
25-
media_height: 100,
26-
isInline: false
27-
}
22+
config: DEFAULT_COLUMN_CONFIG
2823
}
2924
};
3025
}
3126
// Check every column
3227
Object.keys(yaml.columns)
3328
.forEach((key) => {
34-
const column = yaml.columns[key];
29+
let column = yaml.columns[key];
3530
/** BASE COLUMN INFO */
3631
if (!column.input) {
3732
this.addError(`There was not input in column ${key}`);
38-
yaml.columns[key].input = DataTypes.TEXT;
33+
column.input = DataTypes.TEXT;
3934
} else {
40-
yaml.columns[key] = marshallParticularInputInfo(column);
35+
column = marshallParticularInputInfo(column);
4136
// PARTICULAR INPUT INFO
4237
}
4338
if (!column.accessor) {
4439
this.addError(`There was not accessor in column ${key}`);
45-
yaml.columns[key].accessor = key;
40+
column.accessor = key;
4641
}
4742
if (!column.key) {
4843
this.addError(`There was not key in column ${key}`);
49-
yaml.columns[key].key = key;
44+
column.key = key;
5045
}
5146
if (!column.label) {
5247
this.addError(`There was not label in column ${key}`);
53-
yaml.columns[key].label = key;
48+
column.label = key;
49+
}
50+
if (column.skipPersist === undefined) {
51+
column.skipPersist = false;
5452
}
53+
5554
/** CONFIG COLUMN INFO */
5655
if (!column.config && !(column.config instanceof Object)) {
5756
column.config = DEFAULT_COLUMN_CONFIG;
58-
yaml.columns[key] = column;
5957
} else {
60-
if (column.config.enable_media_view === undefined) {
61-
column.config.enable_media_view = DEFAULT_COLUMN_CONFIG.enable_media_view;
62-
yaml.columns[key] = column;
63-
}
64-
if (column.config.media_width === undefined) {
65-
column.config.media_width = DEFAULT_COLUMN_CONFIG.media_width;
66-
yaml.columns[key] = column;
67-
}
68-
if (column.config.media_height === undefined) {
69-
column.config.media_height = DEFAULT_COLUMN_CONFIG.media_height;
70-
yaml.columns[key] = column;
71-
}
58+
// General config
7259
if (column.config.isInline === undefined) {
7360
column.config.isInline = DEFAULT_COLUMN_CONFIG.isInline;
74-
yaml.columns[key] = column;
7561
}
62+
column = marshallParticularConfigInfo(column);
7663
}
64+
// Update mashaller response
65+
yaml.columns[key] = column;
7766
});
7867
handlerResponse.yaml = yaml;
7968
return this.goNext(handlerResponse);
@@ -104,4 +93,25 @@ function marshallParticularInputInfo(column: DatabaseColumn): DatabaseColumn {
10493
break;
10594
}
10695
return column;
96+
}
97+
98+
function marshallParticularConfigInfo(column: DatabaseColumn): DatabaseColumn {
99+
switch (column.input) {
100+
case DataTypes.TEXT:
101+
if (column.config.enable_media_view === undefined) {
102+
column.config.enable_media_view = DEFAULT_COLUMN_CONFIG.enable_media_view;
103+
}
104+
if (column.config.media_width === undefined) {
105+
column.config.media_width = DEFAULT_COLUMN_CONFIG.media_width;
106+
}
107+
if (column.config.media_height === undefined) {
108+
column.config.media_height = DEFAULT_COLUMN_CONFIG.media_height;
109+
}
110+
case DataTypes.TASK:
111+
if (column.config.task_hide_completed === undefined) {
112+
column.config.task_hide_completed = DEFAULT_COLUMN_CONFIG.task_hide_completed;
113+
break;
114+
}
115+
}
116+
return column;
107117
}

0 commit comments

Comments
 (0)