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

Commit 58afcd4

Browse files
committed
control inline fields with new rows
1 parent 498c7fb commit 58afcd4

File tree

6 files changed

+62
-29
lines changed

6 files changed

+62
-29
lines changed

src/components/Header.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ export default function Header(headerProps: DatabaseHeaderProps) {
5757
const [domReady, setDomReady] = useState(false);
5858
const [referenceElement, setReferenceElement] = useState(null);
5959
const [isMetadata, setIsMetadata] = useState(headerProps.column.isMetadata);
60+
const [isInline, setIsInline] = useState(headerProps.column.isInline);
6061
const [labelState, setLabelState] = useState(headerProps.column.label);
6162
React.useEffect(() => {
6263
setDomReady(true);
@@ -119,6 +120,7 @@ export default function Header(headerProps: DatabaseHeaderProps) {
119120
>
120121
<span className="svg-icon svg-gray icon-margin">{propertyIcon}</span>
121122
{labelState}
123+
{isInline && <span>*</span>}
122124
</div>
123125
{!isMetadata && domReady
124126
? ReactDOM.createPortal(
@@ -134,6 +136,8 @@ export default function Header(headerProps: DatabaseHeaderProps) {
134136
referenceElement={referenceElement}
135137
labelState={labelState}
136138
setLabelState={setLabelState}
139+
isInline={isInline}
140+
setIsInline={setIsInline}
137141
initialState={initialState}
138142
/>,
139143
document.getElementById("popper-container")

src/components/HeaderMenu.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import React, { useContext, useEffect, useState } from "react";
1919
import { ActionType } from "react-table";
2020
import { usePopper } from "react-popper";
2121
import { HeaderContext } from "components/contexts/HeaderContext";
22-
import { Checkbox, FormControlLabel, FormGroup } from "@material-ui/core";
22+
import { FormControlLabel, FormGroup, Switch } from "@material-ui/core";
2323
type HeaderMenuProps = {
2424
dispatch: (action: ActionType) => void;
2525
setSortBy: any;
@@ -33,6 +33,8 @@ type HeaderMenuProps = {
3333
labelState: string;
3434
setLabelState: (label: string) => void;
3535
initialState: TableDataType;
36+
isInline: boolean;
37+
setIsInline: (isInline: boolean) => void;
3638
};
3739
const HeaderMenu = (headerMenuProps: HeaderMenuProps) => {
3840
const {
@@ -46,6 +48,8 @@ const HeaderMenu = (headerMenuProps: HeaderMenuProps) => {
4648
labelState,
4749
setLabelState,
4850
initialState,
51+
isInline,
52+
setIsInline,
4953
} = headerMenuProps;
5054
/** state of width columns */
5155
const { columnWidthState, setColumnWidthState } = useContext(HeaderContext);
@@ -68,9 +72,6 @@ const HeaderMenu = (headerMenuProps: HeaderMenuProps) => {
6872
useState(null);
6973
const [settingsPopperElement, setSettingsPopperElement] = useState(null);
7074
const [showSettings, setShowSettings] = useState(false);
71-
const [toggleInlineFrontmatter, setToggleInlineFrontmatter] = useState(
72-
headerMenuProps.column.isInline
73-
);
7475

7576
useEffect(() => {
7677
if (created) {
@@ -261,7 +262,7 @@ const HeaderMenu = (headerMenuProps: HeaderMenuProps) => {
261262
}
262263

263264
function handleChangeToggleInlineFrontmatter(e: any) {
264-
setToggleInlineFrontmatter(e.target.checked);
265+
setIsInline(e.target.checked);
265266
dispatch({
266267
type: ActionTypes.TOGGLE_INLINE_FRONTMATTER,
267268
columnId: id,
@@ -418,8 +419,8 @@ const HeaderMenu = (headerMenuProps: HeaderMenuProps) => {
418419
<FormGroup>
419420
<FormControlLabel
420421
control={
421-
<Checkbox
422-
checked={toggleInlineFrontmatter}
422+
<Switch
423+
checked={isInline}
423424
onChange={(event) => {
424425
handleChangeToggleInlineFrontmatter(event);
425426
}}

src/components/reducers/DatabaseDispatch.tsx

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { ActionType } from "react-table";
1212
import { VaultManagerDB } from "services/FileManagerService";
1313
import { moveFile, updateRowFile } from "helpers/VaultManagement";
1414
import { randomColor } from "helpers/Colors";
15-
import { DatabaseColumn } from "cdm/DatabaseModel";
15+
import { DatabaseColumn, RowDatabaseFields } from "cdm/DatabaseModel";
1616
import NoteInfo from "services/NoteInfo";
1717
import { dbTrim } from "helpers/StylesHelper";
1818
import { parseFrontmatterFieldsToString } from "parsers/RowDatabaseFieldsToFile";
@@ -54,24 +54,33 @@ export function databaseReducer(state: TableDataType, action: ActionType) {
5454
*/
5555
case ActionTypes.ADD_ROW:
5656
const filename = `${state.view.file.parent.path}/${action.filename}.md`;
57-
const rowRecord: Record<string, any> = {};
57+
const rowRecord: RowDatabaseFields = { inline: {}, frontmatter: {} };
5858
state.columns
5959
.filter((column: TableColumn) => !column.isMetadata)
6060
.forEach((column: TableColumn) => {
61-
rowRecord[column.key] = "";
61+
if (column.isInline) {
62+
rowRecord.inline[column.key] = "";
63+
} else {
64+
rowRecord.frontmatter[column.key] = "";
65+
}
6266
});
6367
// Add note to persist row
6468
VaultManagerDB.create_markdown_file(
6569
state.view.file.parent,
6670
action.filename,
67-
parseFrontmatterFieldsToString(rowRecord)
71+
rowRecord
6872
);
6973

7074
const row: RowDataType = {
71-
...rowRecord,
75+
...rowRecord.frontmatter,
76+
...rowRecord.inline,
7277
id: state.data.length + 1,
7378
note: new NoteInfo(
74-
{ ...rowRecord, file: { path: filename } },
79+
{
80+
...rowRecord.frontmatter,
81+
...rowRecord.inline,
82+
file: { path: filename },
83+
},
7584
state.data.length + 1
7685
),
7786
[MetadataColumns.FILE]: `[[${filename}|${action.filename}]]`,
@@ -408,7 +417,7 @@ export function databaseReducer(state: TableDataType, action: ActionType) {
408417
return update(state, { skipReset: { $set: false } });
409418

410419
case ActionTypes.TOGGLE_INLINE_FRONTMATTER:
411-
// Update configuration & row files on disk
420+
// Altern between inline & frontmatter mode
412421
state.view.diskConfig.updateColumnProperties(action.columnId, {
413422
isInline: action.isInline,
414423
});

src/helpers/VaultManagement.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ export async function updateRowFile(file: TFile, columnId: string, newValue: str
145145
action: 'replace',
146146
file: file,
147147
regexp: frontmatterGroupRegex,
148-
newValue: parseFrontmatterFieldsToString(rowFields.frontmatter, content, deletedColumn)
148+
newValue: parseFrontmatterFieldsToString(rowFields, content, deletedColumn)
149149
};
150150
await VaultManagerDB.editNoteContent(noteObject);
151151
}
Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,37 @@
1+
import { RowDatabaseFields } from "cdm/DatabaseModel";
12
import { parseYaml } from "obsidian";
2-
export const parseFrontmatterFieldsToString = (frontmatterFields: Record<string, any>, original?: string, deletedColumn?: string): string => {
3-
const match = original.match(/^---\s+([\w\W]+?)\s+---/);
4-
3+
export const parseFrontmatterFieldsToString = (databaseFields: RowDatabaseFields, original?: string, deletedColumn?: string): string => {
4+
const frontmatterFields = databaseFields.frontmatter;
5+
const inlineFields = databaseFields.inline;
56
const array: string[] = [];
67
array.push(`---`);
78
Object.keys(frontmatterFields).forEach(key => {
8-
array.push(`${key}: ${frontmatterFields[key]}`);
9+
// check if frontmatter field is inside inline fields
10+
if (!inlineFields.hasOwnProperty(key)) {
11+
array.push(`${key}: ${frontmatterFields[key]}`);
12+
}
913
});
10-
if (match) {
11-
const frontmatterRaw = match[1];
12-
const yaml = parseYaml(frontmatterRaw);
13-
Object.keys(yaml).forEach(key => {
14-
if (!frontmatterFields[key] && key !== deletedColumn) {
15-
array.push(`${key}: ${yaml[key]}`);
16-
}
17-
});
14+
if (original !== undefined) {
15+
const match = original.match(/^---\s+([\w\W]+?)\s+---/);
16+
if (match) {
17+
const frontmatterRaw = match[1];
18+
const yaml = parseYaml(frontmatterRaw);
19+
Object.keys(yaml).forEach(key => {
20+
// add frontmatter fields that are not specified as database fields
21+
if (!frontmatterFields[key] && key !== deletedColumn) {
22+
array.push(`${key}: ${yaml[key]}`);
23+
}
24+
});
25+
}
1826
}
1927
array.push(`---`);
2028
return array.join('\n');
29+
}
30+
31+
export const parseInlineFieldsToString = (inlineFields: RowDatabaseFields): string => {
32+
const array: string[] = [];
33+
Object.keys(inlineFields.inline).forEach(key => {
34+
array.push(`${key}:: ${inlineFields.inline[key]}`);
35+
});
36+
return array.join('\n');
2137
}

src/services/FileManagerService.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
import { RowDatabaseFields } from "cdm/DatabaseModel";
12
import { NoteContentAction } from "cdm/FolderModel";
23
import { FileContent } from "helpers/FileContent";
34
import { TFile, TFolder } from "obsidian";
5+
import { parseFrontmatterFieldsToString, parseInlineFieldsToString } from "parsers/RowDatabaseFieldsToFile";
46
import { LOGGER } from "services/Logger";
57
export class VaultManager {
68
private static instance: VaultManager;
@@ -11,20 +13,21 @@ export class VaultManager {
1113
* @param filename
1214
* @param content
1315
*/
14-
async create_markdown_file(targetFolder: TFolder, filename: string, content?: string): Promise<TFile> {
16+
async create_markdown_file(targetFolder: TFolder, filename: string, databasefields: RowDatabaseFields): Promise<TFile> {
1517
LOGGER.debug(`=> create_markdown_file. name:${targetFolder.path}/${filename})`);
1618
const created_note = await app.fileManager.createNewMarkdownFile(
1719
targetFolder,
1820
filename ?? "Untitled"
1921
);
22+
const content = parseFrontmatterFieldsToString(databasefields).concat("\n").concat(parseInlineFieldsToString(databasefields));
2023
await app.vault.modify(created_note, content ?? "");
2124
LOGGER.debug(`<= create_markdown_file`);
2225
return created_note;
2326
}
2427

2528
/**
2629
* Edit file content
27-
* @param note
30+
* @param note
2831
*/
2932
async editNoteContent(note: NoteContentAction): Promise<string> {
3033
LOGGER.debug(`=> editNoteContent. action:${note.action} filePath:${note.file.path}`);

0 commit comments

Comments
 (0)