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

Commit 29c0fb0

Browse files
authored
fix: rows not updated in ui state after organizing files
1 parent c43bfa0 commit 29c0fb0

File tree

11 files changed

+162
-216
lines changed

11 files changed

+162
-216
lines changed

src/cdm/TableStateInterface.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export interface DataState {
4747
dataviewRefresh: (column: TableColumn[], ddbbConfig: LocalSettings, filterConfig: FilterSettings) => void;
4848
renameFile: (rowIndex: number) => Promise<void>;
4949
saveDataFromFile: (file: File, columns: TableColumn[], config: LocalSettings) => Promise<void>;
50+
groupFiles: () => Promise<void>;
5051
}
5152
}
5253

@@ -102,4 +103,4 @@ export interface TableStateInterface {
102103
data: UseBoundStore<StoreApi<DataState>>;
103104
sorting: UseBoundStore<StoreApi<ColumnSortingState>>;
104105
columns: UseBoundStore<StoreApi<ColumnsState>>;
105-
}
106+
}

src/components/HeaderMenu.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,7 @@ const HeaderMenu = (headerMenuProps: HeaderMenuProps) => {
154154
.join(",");
155155
configActions.alterConfig({ group_folder_column: newGroupFolderColumn });
156156
// Reorganize files and remove empty folders
157-
const folderPath = destination_folder(view, view.diskConfig.yaml.config);
158-
FileGroupingService.organizeNotesIntoSubfolders( folderPath, view.rows, view.diskConfig.yaml.config )
159-
.then(()=>{ FileGroupingService.removeEmptyFolders(folderPath, view.diskConfig.yaml.config); })
157+
dataActions.groupFiles()
160158
}
161159
}
162160

src/components/headerActions/handlers/buttons/RemoveColumnHandlerAction.tsx

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,7 @@ function removeButton(headerActionResponse: HeaderActionResponse) {
7676
.join(",");
7777
configActions.alterConfig({ group_folder_column: newGroupFolderColumn });
7878
// Reorganize files and remove empty folders
79-
const folderPath = destination_folder(view, view.diskConfig.yaml.config);
80-
FileGroupingService.organizeNotesIntoSubfolders( folderPath, view.rows, view.diskConfig.yaml.config )
81-
.then(()=>{ FileGroupingService.removeEmptyFolders(folderPath,view.diskConfig.yaml.config); })
79+
dataActions.groupFiles();
8280
}
8381
};
8482

src/helpers/VaultManagement.ts

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,13 @@ import { RowDataType, NormalizedPath, TableColumn } from 'cdm/FolderModel';
22
import { Notice, TFile } from 'obsidian';
33
import { LOGGER } from "services/Logger";
44
import NoteInfo from 'services/NoteInfo';
5-
import { DatabaseCore, MetadataColumns, SourceDataTypes } from "helpers/Constants";
5+
import { DatabaseCore, SourceDataTypes } from "helpers/Constants";
66
import { generateDataviewTableQuery } from 'helpers/QueryHelper';
77
import { DataviewService } from 'services/DataviewService';
88
import { Literal } from 'obsidian-dataview/lib/data-model/value';
99
import { DataArray } from 'obsidian-dataview/lib/api/data-array';
1010
import { FilterSettings, LocalSettings } from 'cdm/SettingsModel';
1111
import { NoteInfoPage } from 'cdm/DatabaseModel';
12-
import { EditEngineService } from 'services/EditEngineService';
1312
import tableFilter from 'helpers/TableFiltersHelper';
1413

1514
const noBreakSpace = /\u00A0/g;
@@ -164,17 +163,3 @@ async function obtainQueryResult(query: string, folderPath: string): Promise<Dat
164163

165164

166165

167-
168-
export const postMoveFile = ({ file, row, newFilePath, }: { row: RowDataType; file: TFile; newFilePath: string }) => {
169-
// Update row file
170-
row[ MetadataColumns.FILE ] = `${file.basename}|${newFilePath}/${file.name}`;
171-
172-
const recordRow: Record<string, Literal> = {};
173-
Object.entries(row).forEach(([key, value]) => {
174-
recordRow[key] = value as Literal;
175-
});
176-
177-
row.__note__.filepath = `${newFilePath}/${file.name}`;
178-
};
179-
180-
Lines changed: 81 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,158 +1,120 @@
1-
import { Notice, TFile } from "obsidian";
1+
import { Notice } from "obsidian";
22
import { LOGGER } from "./Logger";
33
import pLimit from "p-limit";
44
import { RowDataType } from "cdm/FolderModel";
55
import { LocalSettings } from "cdm/SettingsModel";
66
import { resolveNewFilePath } from "helpers/FileManagement";
7-
import { postMoveFile } from "helpers/VaultManagement";
7+
import { MetadataColumns } from "helpers/Constants";
88

99
const limitMovingFiles = pLimit(1);
1010
const limitCreatingFolders = pLimit(1);
1111
const limitBatchDeletionAndOrganization = pLimit(1);
1212

1313
export class FileGroupingService {
14-
private static instance: FileGroupingService;
15-
private constructor() { }
16-
public static getInstance(): FileGroupingService {
17-
if (!this.instance) {
18-
this.instance = new FileGroupingService();
14+
private static async removeEmptyFoldersRecursively(
15+
directory: string,
16+
deletedFolders: Set<string>
17+
) {
18+
let list = await app.vault.adapter.list(directory);
19+
for (const folder of list.folders) {
20+
deletedFolders = await FileGroupingService.removeEmptyFoldersRecursively(
21+
folder,
22+
deletedFolders
23+
);
1924
}
20-
return this.instance;
21-
}
2225

23-
static moveFile = async (folderPath: string, file: TFile): Promise<void> =>
24-
limitMovingFiles(() => FileGroupingService._moveFile(folderPath, file));
25-
private static async _moveFile(
26-
folderPath: string,
27-
file: TFile,
28-
): Promise<void> {
29-
try {
30-
await FileGroupingService.createFolder(folderPath);
31-
} catch (error) {
32-
LOGGER.error(` moveFile Error: ${error.message} `);
33-
throw error;
26+
list = await app.vault.adapter.list(directory);
27+
if (list.files.length === 0 && list.folders.length === 0) {
28+
await app.vault.adapter.rmdir(directory, false);
29+
deletedFolders.add(directory);
3430
}
35-
const filePath = `${folderPath}/${file.name}`;
36-
await app.fileManager.renameFile(file, filePath);
31+
32+
return deletedFolders;
3733
}
3834

39-
static createFolder = async (folderPath: string): Promise<void> =>
40-
limitCreatingFolders(() => FileGroupingService._createFolder(folderPath));
41-
private static async _createFolder(folderPath: string): Promise<void> {
42-
await app.vault.adapter.exists(folderPath).then(async (exists) => {
43-
if (!exists) {
44-
await app.vault.createFolder(`${folderPath}/`);
35+
static moveFile = async (folderPath: string, row: RowDataType): Promise<boolean> =>
36+
limitMovingFiles(async () => {
37+
let file = row.__note__.getFile();
38+
const filePath = `${folderPath}/${file.name}`;
39+
const fileIsAlreadyInCorrectFolder = row.__note__.filepath === filePath;
40+
if (fileIsAlreadyInCorrectFolder) return false;
41+
try {
42+
await FileGroupingService.createFolder(folderPath);
43+
} catch (error) {
44+
LOGGER.error(` moveFile Error: ${error.message} `);
45+
throw error;
4546
}
47+
48+
await app.fileManager.renameFile(file, filePath);
49+
row[MetadataColumns.FILE] = `${file.basename}|${folderPath}/${file.name}`;
50+
row.__note__.filepath = `${folderPath}/${file.name}`;
51+
return true;
52+
});
53+
54+
static createFolder = async (folderPath: string): Promise<void> =>
55+
limitCreatingFolders(async () => {
56+
await app.vault.adapter.exists(folderPath).then(async (exists) => {
57+
if (!exists) {
58+
await app.vault.createFolder(`${folderPath}/`);
59+
}
60+
});
4661
});
47-
}
4862

4963
static organizeNotesIntoSubfolders = async (
5064
folderPath: string,
5165
rows: Array<RowDataType>,
5266
ddbbConfig: LocalSettings,
53-
): Promise<number> =>
54-
limitBatchDeletionAndOrganization(() =>
55-
FileGroupingService._organizeNotesIntoSubfolders(
56-
folderPath,
57-
rows,
58-
ddbbConfig,
59-
),
60-
);
61-
private static async _organizeNotesIntoSubfolders(
62-
folderPath: string,
63-
rows: Array<RowDataType>,
64-
ddbbConfig: LocalSettings,
65-
): Promise<number> {
66-
try {
67-
if (!ddbbConfig.automatically_group_files) return 0;
68-
let numberOfMovedFiles = 0;
69-
const pathColumns: string[] = (ddbbConfig.group_folder_column || '')
67+
): Promise<RowDataType[]> =>
68+
limitBatchDeletionAndOrganization(async () => {
69+
if (!ddbbConfig.automatically_group_files) return [];
70+
const movedRows: RowDataType[] = [];
71+
const pathColumns: string[] = (ddbbConfig.group_folder_column || "")
7072
.split(",")
7173
.filter(Boolean);
7274
for (const row of rows) {
73-
let rowTFile = row.__note__.getFile();
74-
7575
const newFilePath = resolveNewFilePath({
7676
pathColumns,
7777
row,
7878
ddbbConfig,
79-
folderPath,
79+
folderPath
8080
});
81-
// Check if file is already in the correct folder
82-
const auxPath = `${newFilePath}/${rowTFile.name}`;
83-
const fileIsAlreadyInCorrectFolder = row.__note__.filepath === auxPath;
84-
if (fileIsAlreadyInCorrectFolder) continue;
8581

86-
await FileGroupingService.moveFile(newFilePath, rowTFile);
87-
await postMoveFile({ file: rowTFile, row, newFilePath });
88-
numberOfMovedFiles++;
82+
try {
83+
const fileWasMoved = await FileGroupingService.moveFile(newFilePath, row);
84+
if (fileWasMoved) {
85+
movedRows.push(row);
86+
}
87+
} catch (error) {
88+
new Notice(`Error while moving files into subfolders: ${error.message}`, 5000);
89+
throw error;
90+
}
8991
}
90-
if (numberOfMovedFiles > 0)
92+
if (movedRows.length > 0) {
9193
new Notice(
92-
`Moved ${numberOfMovedFiles} file${numberOfMovedFiles > 1 ? "s" : ""
94+
`Moved ${movedRows.length} file${
95+
movedRows.length > 1 ? "s" : ""
9396
} into subfolders`,
94-
1500,
97+
1500
9598
);
99+
}
100+
return movedRows;
101+
});
96102

97-
return numberOfMovedFiles;
98-
} catch (error) {
99-
new Notice(
100-
`Error while moving files into subfolders: ${error.message}`,
101-
5000,
102-
);
103-
throw error;
104-
}
105-
}
106-
107-
private static async removeEmptyFoldersRecursively(
108-
directory: string,
109-
deletedFolders: Set<string>,
110-
) {
111-
let list = await app.vault.adapter.list(directory);
112-
for (const folder of list.folders) {
113-
deletedFolders = await FileGroupingService.removeEmptyFoldersRecursively(
114-
folder,
115-
deletedFolders,
116-
);
117-
}
118-
119-
list = await app.vault.adapter.list(directory);
120-
if (list.files.length === 0 && list.folders.length === 0) {
121-
await app.vault.adapter.rmdir(directory, false);
122-
deletedFolders.add(directory);
123-
}
124-
125-
return deletedFolders;
126-
}
127-
128-
static removeEmptyFolders = async (
129-
directory: string,
130-
ddbbConfig: LocalSettings,
131-
) =>
132-
limitBatchDeletionAndOrganization(() =>
133-
FileGroupingService._removeEmptyFolders(directory, ddbbConfig),
134-
);
135-
private static async _removeEmptyFolders(
136-
directory: string,
137-
ddbbConfig: LocalSettings,
138-
) {
139-
if(!ddbbConfig.automatically_group_files) return;
140-
if (!ddbbConfig.remove_empty_folders) return;
141-
try {
142-
const removedDirectories =
143-
await FileGroupingService.removeEmptyFoldersRecursively(
144-
directory,
145-
new Set(),
146-
);
147-
const n = removedDirectories.size;
148-
if (n > 0) {
149-
const message = `Removed ${n} empty director${n === 0 || n > 1 ? "ies" : "y"
150-
}`;
151-
new Notice(message, 1500);
103+
static removeEmptyFolders = async (directory: string, ddbbConfig: LocalSettings) =>
104+
limitBatchDeletionAndOrganization(async () => {
105+
if (!ddbbConfig.automatically_group_files) return;
106+
if (!ddbbConfig.remove_empty_folders) return;
107+
try {
108+
const removedDirectories =
109+
await FileGroupingService.removeEmptyFoldersRecursively(directory, new Set());
110+
const n = removedDirectories.size;
111+
if (n > 0) {
112+
const message = `Removed ${n} empty director${n === 0 || n > 1 ? "ies" : "y"}`;
113+
new Notice(message, 1500);
114+
}
115+
} catch (error) {
116+
new Notice(`Error while removing empty folders: ${error.message}`, 5000);
117+
throw error;
152118
}
153-
} catch (error) {
154-
new Notice(`Error while removing empty folders: ${error.message}`, 5000);
155-
throw error;
156-
}
157-
}
119+
});
158120
}

src/settings/handlers/columns/FileGroupingColumnsSetting.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ export class FileGroupingColumnsSetting {
1212
constructor(
1313
private view: DatabaseView,
1414
private allowedColumns: Set<string>,
15-
private organize: () => Promise<void>,
1615
) {}
1716

1817
init = (containerEl: HTMLElement) => {
@@ -53,7 +52,6 @@ export class FileGroupingColumnsSetting {
5352
group_folder_column: [...newSeting].join(","),
5453
});
5554

56-
this.organize();
5755
this.searchComponent.clearButtonEl.click();
5856
this.searchComponent.inputEl.blur();
5957
this.fileAttributeSuggester.options = [...this.allowedColumns].filter(
@@ -66,7 +64,7 @@ export class FileGroupingColumnsSetting {
6664
if (values.filter(Boolean).length) {
6765
this.label.innerHTML =
6866
values
69-
.map((v) => `<span style='color: #ccc;'>${v}</span>`)
67+
.map((v) => `<span style='color: #999;'>${v}</span>`)
7068
.join("<span style='color: #666;'> / </span>") || "None";
7169
this.labelContainer.style.display = "flex";
7270
} else {

0 commit comments

Comments
 (0)