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

Commit 98df444

Browse files
committed
Merge branch 'improve_parsing-date'
2 parents 20df1cf + 54c53d0 commit 98df444

File tree

15 files changed

+351
-276
lines changed

15 files changed

+351
-276
lines changed

src/cdm/CheckboxModel.ts

Lines changed: 0 additions & 7 deletions
This file was deleted.

src/cdm/ComponentsModel.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,7 @@ export type RowSelectOption = {
77
label: string,
88
}
99

10-
export type PopperProps = {
11-
defaultCell: CellContext<RowDataType, Literal>;
12-
}
13-
14-
export type TagsProps = {
15-
defaultCell: CellContext<RowDataType, Literal>;
16-
}
17-
18-
export type CalendarProps = {
10+
export type CellComponentProps = {
1911
defaultCell: CellContext<RowDataType, Literal>;
2012
}
2113

src/components/DefaultCell.tsx

Lines changed: 16 additions & 200 deletions
Original file line numberDiff line numberDiff line change
@@ -1,223 +1,42 @@
1-
import React, { useEffect, useRef, useState } from "react";
1+
import React from "react";
22
import { InputType } from "helpers/Constants";
3-
import { c } from "helpers/StylesHelper";
43
import { LOGGER } from "services/Logger";
54
import { RowDataType, TableColumn } from "cdm/FolderModel";
65
import PopperSelectPortal from "components/portals/PopperSelectPortal";
7-
import { TableCellContext } from "components/contexts/CellContext";
86
import CalendarPortal from "components/portals/CalendarPortal";
97
import CalendarTimePortal from "components/portals/CalendarTimePortal";
10-
import { renderMarkdown } from "components/markdown/MarkdownRenderer";
11-
import { CheckboxCell } from "components/Checkbox";
8+
import CheckboxCell from "components/cellTypes/CheckboxCell";
9+
import TaskCell from "components/cellTypes/TaskCell";
10+
import MarkdownCell from "components/cellTypes/MarkdownCell";
1211
import TagsPortal from "components/portals/TagsPortal";
13-
import { DataviewService } from "services/DataviewService";
12+
import NumberCell from "components/cellTypes/NumberCell";
13+
import TextCell from "components/cellTypes/TextCell";
1414
import { CellContext } from "@tanstack/react-table";
1515
import { Literal } from "obsidian-dataview";
16-
import { Grouping } from "obsidian-dataview/lib/data-model/value";
17-
import { SListItem } from "obsidian-dataview/lib/data-model/serialized/markdown";
1816

1917
export default function DefaultCell(
2018
defaultCell: CellContext<RowDataType, Literal>
2119
) {
22-
const { cell, column, row, table } = defaultCell;
23-
/** Initial state of cell */
24-
const cellValue = cell.getValue();
25-
/** Columns information */
26-
const columns = table.options.meta.tableState.columns(
27-
(state) => state.columns
28-
);
29-
const dataActions = table.options.meta.tableState.data(
30-
(state) => state.actions
31-
);
32-
const ddbbConfig = table.options.meta.tableState.configState(
33-
(state) => state.ddbbConfig
34-
);
20+
const { column } = defaultCell;
3521
/** Type of cell */
3622
const input = (column.columnDef as TableColumn).input;
37-
/** Ref to cell container */
38-
const containerCellRef = useRef<HTMLDivElement>();
39-
const editableMdRef = useRef<HTMLInputElement>();
40-
const taskRef = useRef<HTMLDivElement>();
41-
/** state of cell value */
42-
const [contextValue, setContextValue] = useState({
43-
value: cellValue,
44-
update: false,
45-
});
46-
/** state for keeping the timeout to trigger the editior */
47-
const [editNoteTimeout, setEditNoteTimeout] = useState(null);
48-
const [dirtyCell, setDirtyCell] = useState(false);
4923

50-
const meta = table.options.meta;
5124
/** states for selector option */
52-
LOGGER.debug(
53-
`<=> Cell.rendering input: ${input}. value: ${contextValue.value}`
54-
);
55-
// set contextValue when cell is loaded
56-
useEffect(() => {
57-
LOGGER.debug(
58-
`default useEffect. input:${input} - value: ${contextValue.value} cellValue: ${cellValue}`
59-
);
60-
if (dirtyCell) {
61-
// End useEffect
62-
return;
63-
}
64-
switch (input) {
65-
case InputType.TASK:
66-
// Check if there are tasks in the cell
67-
if (contextValue.value === "") break;
68-
taskRef.current.innerHTML = "";
69-
if ((column.columnDef as TableColumn).config.task_hide_completed) {
70-
contextValue.value = (contextValue.value as any).where(
71-
(t: any) => !t.completed
72-
);
73-
}
74-
DataviewService.getDataviewAPI().taskList(
75-
contextValue.value as Grouping<SListItem>,
76-
false,
77-
taskRef.current,
78-
meta.view,
79-
meta.view.file.path
80-
);
81-
82-
break;
83-
case InputType.MARKDOWN:
84-
case InputType.TEXT:
85-
if (containerCellRef.current !== null) {
86-
containerCellRef.current.innerHTML = "";
87-
renderMarkdown(
88-
defaultCell,
89-
cellValue?.toString(),
90-
containerCellRef.current,
91-
5
92-
);
93-
}
94-
break;
95-
default:
96-
// do nothing
97-
}
98-
});
99-
100-
useEffect(() => {
101-
if (editableMdRef.current) {
102-
LOGGER.debug(
103-
`useEffect hooked with editableMdRef. current value & dirtyCell: ${contextValue.value} ${dirtyCell}`
104-
);
105-
editableMdRef.current.focus();
106-
}
107-
}, [editableMdRef, dirtyCell]);
108-
109-
useEffect(() => {
110-
if (
111-
!dirtyCell &&
112-
containerCellRef.current !== undefined &&
113-
input !== InputType.MARKDOWN
114-
) {
115-
LOGGER.debug(
116-
`useEffect hooked with dirtyCell. Value:${contextValue.value}`
117-
);
118-
renderMarkdown(
119-
defaultCell,
120-
contextValue.value?.toString(),
121-
containerCellRef.current,
122-
5
123-
);
124-
}
125-
}, [dirtyCell]);
126-
127-
const handleKeyDown = (event: any) => {
128-
if (event.key === "Enter") {
129-
event.target.blur();
130-
}
131-
};
132-
133-
const handleOnBlur = (event: any) => {
134-
setDirtyCell(false);
135-
};
136-
137-
const handleEditableOnclick = (event: any) => {
138-
setDirtyCell(true);
139-
};
140-
141-
// onChange handler
142-
const handleOnChange = (event: any) => {
143-
setDirtyCell(true);
144-
// cancelling previous timeouts
145-
if (editNoteTimeout) {
146-
clearTimeout(editNoteTimeout);
147-
}
148-
// first update the input text as user type
149-
setContextValue({ value: event.target.value, update: true });
150-
// initialize a setimeout by wrapping in our editNoteTimeout so that we can clear it out using clearTimeout
151-
setEditNoteTimeout(
152-
setTimeout(() => {
153-
onChange(event.target.value);
154-
// timeout until event is triggered after user has stopped typing
155-
}, 1500)
156-
);
157-
};
158-
159-
function onChange(changedValue: string) {
160-
dataActions.updateCell(
161-
row.index,
162-
column.columnDef as TableColumn,
163-
changedValue,
164-
columns,
165-
ddbbConfig
166-
);
167-
}
25+
LOGGER.debug(`<=> Cell.rendering input: ${input}`);
16826

16927
function getCellElement() {
17028
switch (input) {
17129
/** Plain text option */
17230
case InputType.TEXT:
173-
return dirtyCell ? (
174-
<input
175-
value={(contextValue.value && contextValue.value.toString()) || ""}
176-
onChange={handleOnChange}
177-
onKeyDown={handleKeyDown}
178-
onBlur={handleOnBlur}
179-
ref={editableMdRef}
180-
/>
181-
) : (
182-
<span
183-
ref={containerCellRef}
184-
onClick={handleEditableOnclick}
185-
style={{ width: column.getSize() }}
186-
/>
187-
);
31+
return <TextCell defaultCell={defaultCell} />;
18832

18933
/** Number option */
19034
case InputType.NUMBER:
191-
return dirtyCell ? (
192-
<input
193-
value={(contextValue.value && contextValue.value.toString()) || ""}
194-
ref={editableMdRef}
195-
onChange={handleOnChange}
196-
onKeyDown={handleKeyDown}
197-
onBlur={handleOnBlur}
198-
className="text-align-right"
199-
/>
200-
) : (
201-
<span
202-
className="text-align-right"
203-
onClick={handleEditableOnclick}
204-
style={{ width: column.getSize() }}
205-
>
206-
{(contextValue.value && contextValue.value.toString()) || ""}
207-
</span>
208-
);
35+
return <NumberCell defaultCell={defaultCell} />;
20936

21037
/** Markdown option */
21138
case InputType.MARKDOWN:
212-
if (cellValue !== contextValue.value.toString()) {
213-
setContextValue({
214-
value: cellValue,
215-
update: false,
216-
});
217-
}
218-
return (
219-
<span ref={containerCellRef} className={`${c("md_cell")}`}></span>
220-
);
39+
return <MarkdownCell defaultCell={defaultCell} />;
22140

22241
/** Calendar option */
22342
case InputType.CALENDAR:
@@ -230,21 +49,18 @@ export default function DefaultCell(
23049
/** Selector option */
23150
case InputType.SELECT:
23251
return <PopperSelectPortal defaultCell={defaultCell} />;
52+
23353
/** Tags option */
23454
case InputType.TAGS:
23555
return <TagsPortal defaultCell={defaultCell} />;
23656

57+
/** Tasks option */
23758
case InputType.TASK:
238-
if ((column.columnDef as TableColumn).config.task_hide_completed) {
239-
}
240-
return <div ref={taskRef}></div>;
59+
return <TaskCell defaultCell={defaultCell} />;
24160

61+
/** Checkbox option */
24262
case InputType.CHECKBOX:
243-
return (
244-
<TableCellContext.Provider value={{ contextValue, setContextValue }}>
245-
<CheckboxCell defaultCell={defaultCell} />
246-
</TableCellContext.Provider>
247-
);
63+
return <CheckboxCell defaultCell={defaultCell} />;
24864
case InputType.NEW_COLUMN:
24965
// Do nothing
25066
break;
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,27 @@
1-
import React, { useContext, useState } from "react";
2-
import { TableCellContext } from "components/contexts/CellContext";
3-
import { CheckboxProps } from "cdm/CheckboxModel";
1+
import React, { useState } from "react";
42
import { TableColumn } from "cdm/FolderModel";
53
import { c } from "helpers/StylesHelper";
4+
import { CellComponentProps } from "cdm/ComponentsModel";
65

7-
export function CheckboxCell(props: CheckboxProps) {
6+
function CheckboxCell(props: CellComponentProps) {
87
const { defaultCell } = props;
98
const { row, column, table } = defaultCell;
10-
const dataActions = table.options.meta.tableState.data(
11-
(state) => state.actions
12-
);
9+
const tableColumn = column.columnDef as TableColumn;
10+
11+
const [rows, dataActions] = table.options.meta.tableState.data((state) => [
12+
state.rows,
13+
state.actions,
14+
]);
1315
const columns = table.options.meta.tableState.columns(
1416
(state) => state.columns
1517
);
1618
const ddbbConfig = table.options.meta.tableState.configState(
1719
(state) => state.ddbbConfig
1820
);
1921
/** state of cell value */
20-
const { contextValue, setContextValue } = useContext(TableCellContext);
21-
const [checked, setChecked] = useState(contextValue.value as boolean);
22+
const [checked, setChecked] = useState(
23+
Boolean(rows[row.index][tableColumn.key])
24+
);
2225
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
2326
const newValue = event.target.checked ? 1 : 0;
2427
// save on disk
@@ -30,11 +33,13 @@ export function CheckboxCell(props: CheckboxProps) {
3033
ddbbConfig
3134
);
3235
setChecked(event.target.checked);
33-
setContextValue({ value: event.target.checked ? 1 : 0, update: true });
3436
};
37+
3538
return (
3639
<div className={`${c("checkbox")}`}>
3740
<input type="checkbox" checked={checked} onChange={handleChange} />
3841
</div>
3942
);
4043
}
44+
45+
export default CheckboxCell;
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { CellComponentProps } from "cdm/ComponentsModel";
2+
import { renderMarkdown } from "components/markdown/MarkdownRenderer";
3+
import { c } from "helpers/StylesHelper";
4+
import React, { useEffect, useRef } from "react";
5+
6+
const MarkdownCell = (mdProps: CellComponentProps) => {
7+
const { defaultCell } = mdProps;
8+
const { cell } = defaultCell;
9+
const cellValue = cell.getValue();
10+
const mdRef = useRef<HTMLDivElement>();
11+
useEffect(() => {
12+
if (mdRef.current !== null) {
13+
mdRef.current.innerHTML = "";
14+
renderMarkdown(defaultCell, cellValue?.toString(), mdRef.current, 5);
15+
}
16+
});
17+
return <span ref={mdRef} className={`${c("md_cell")}`}></span>;
18+
};
19+
20+
export default MarkdownCell;

0 commit comments

Comments
 (0)