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

Commit 757f41a

Browse files
committed
Merge branch '49-fr-formula-column-type'
2 parents 4115e70 + b7133ad commit 757f41a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+513
-22
lines changed

src/DatabaseView.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { obtainFormulasFromFolder } from "automations/AutomationsHelper";
12
import { DatabaseColumn } from "cdm/DatabaseModel";
23
import { ViewEvents } from "cdm/EmitterModel";
34
import {
@@ -44,6 +45,7 @@ export class DatabaseView extends TextFileView implements HoverParent {
4445
columns: Array<TableColumn>;
4546
shadowColumns: Array<TableColumn>;
4647
initial: InitialType;
48+
formulas: Record<string, unknown>;
4749

4850
constructor(leaf: WorkspaceLeaf, plugin: DBFolderPlugin) {
4951
super(leaf);
@@ -151,7 +153,6 @@ export class DatabaseView extends TextFileView implements HoverParent {
151153
);
152154
let yamlColumns: Record<string, DatabaseColumn> =
153155
this.diskConfig.yaml.columns;
154-
this.diskConfig.yaml.config;
155156
// Complete the columns with the metadata columns
156157
yamlColumns = await obtainMetadataColumns(
157158
yamlColumns,
@@ -167,6 +168,10 @@ export class DatabaseView extends TextFileView implements HoverParent {
167168
);
168169

169170
this.initial = obtainInitialType(this.columns);
171+
172+
this.formulas = await obtainFormulasFromFolder(
173+
this.diskConfig.yaml.config
174+
);
170175
// Define table properties
171176
this.shadowColumns = this.columns.filter((col) => col.skipPersist);
172177
const tableProps: TableDataType = {

src/Settings.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { DatabaseSettings } from "cdm/SettingsModel";
1414
import editing_engine_settings_section from "settings/EditingEngineSection";
1515
import rows_settings_section from "settings/RowsSection";
1616
import csv_settings_section from "settings/CSVSection";
17+
import automation_settings_section from "settings/AutomationSection";
1718

1819
export type SettingRetriever = <K extends keyof DatabaseSettings>(
1920
key: K,
@@ -91,6 +92,8 @@ export class SettingsManager {
9192
rows_settings_section.run(settingHandlerResponse);
9293
/** Editing engine section */
9394
editing_engine_settings_section.run(settingHandlerResponse);
95+
/** Automation section */
96+
automation_settings_section.run(settingHandlerResponse);
9497
if (!settingHandlerResponse.local) {
9598
/** Media section */
9699
media_settings_section(settingHandlerResponse);
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { LocalSettings } from "cdm/SettingsModel";
2+
import { FormulaGenerator } from "automations/FormulaGenerator";
3+
4+
export async function obtainFormulasFromFolder(config: LocalSettings) {
5+
const generator = new FormulaGenerator(config);
6+
return await generator.generate_object();
7+
}
8+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { FormulaFunctions } from "automations/formula_functions/FormulaFunctions";
2+
import { IGenerateObject } from "automations/IGenerateObject";
3+
import { LocalSettings } from "cdm/SettingsModel";
4+
import { RowDataType } from "cdm/FolderModel";
5+
import { Literal } from "obsidian-dataview";
6+
export class FormulaGenerator implements IGenerateObject {
7+
public formula_functions: FormulaFunctions;
8+
9+
constructor(private config: LocalSettings) {
10+
this.formula_functions = new FormulaFunctions(config);
11+
}
12+
13+
private async generate_formula_functions(): Promise<Record<string, unknown>> {
14+
15+
return await this.formula_functions.generate_object(this.config);
16+
}
17+
18+
async generate_object(): Promise<Record<string, unknown>> {
19+
const final_object: Record<string, any> = {};
20+
Object.assign(final_object, {
21+
js: await this.generate_formula_functions(),
22+
});
23+
console.log("sasdinal_object");
24+
return final_object;
25+
}
26+
}

src/automations/IGenerateObject.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import { LocalSettings } from "cdm/SettingsModel";
2+
3+
export interface IGenerateObject {
4+
generate_object(config: LocalSettings): Promise<Record<string, unknown>>;
5+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { IGenerateObject } from "automations/IGenerateObject";
2+
import { UserScriptFunctions } from "automations/formula_functions/ScriptFunctions";
3+
import { LocalSettings } from "cdm/SettingsModel";
4+
5+
export class FormulaFunctions implements IGenerateObject {
6+
private js_script_functions: UserScriptFunctions;
7+
8+
constructor(private config: LocalSettings) {
9+
this.js_script_functions = new UserScriptFunctions(config);
10+
}
11+
12+
async generate_object(
13+
config: LocalSettings
14+
): Promise<Record<string, unknown>> {
15+
let user_script_functions = {};
16+
17+
if (config.formula_folder_path) {
18+
user_script_functions =
19+
await this.js_script_functions.generate_object();
20+
}
21+
22+
return {
23+
...user_script_functions,
24+
};
25+
}
26+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { Notice, TFile } from "obsidian";
2+
import { IGenerateObject } from "automations/IGenerateObject";
3+
import { get_tfiles_from_folder } from "helpers/FileManagement";
4+
import { LocalSettings } from "cdm/SettingsModel";
5+
import { LOGGER } from "services/Logger";
6+
7+
export class UserScriptFunctions implements IGenerateObject {
8+
constructor(private config: LocalSettings) { }
9+
10+
async generate_user_script_functions(
11+
): Promise<Map<string, Function>> {
12+
const user_script_functions: Map<string, Function> = new Map();
13+
const files =
14+
get_tfiles_from_folder(
15+
this.config.formula_folder_path,
16+
);
17+
18+
if (!files) {
19+
return new Map();
20+
}
21+
22+
for (const file of files) {
23+
if (file.extension.toLowerCase() === "js") {
24+
await this.load_user_script_function(
25+
file,
26+
user_script_functions
27+
);
28+
}
29+
}
30+
return user_script_functions;
31+
}
32+
33+
async load_user_script_function(
34+
file: TFile,
35+
user_script_functions: Map<string, Function>
36+
): Promise<void> {
37+
let req = (s: string) => {
38+
return window.require && window.require(s);
39+
};
40+
let exp: Record<string, unknown> = {};
41+
let mod = {
42+
exports: exp
43+
};
44+
45+
const file_content = await app.vault.read(file);
46+
const wrapping_fn = window.eval("(function anonymous(require, module, exports){" + file_content + "\n})");
47+
wrapping_fn(req, mod, exp);
48+
const formula_function = exp['default'] || mod.exports;
49+
50+
if (!formula_function) {
51+
const msg = `Failed to load user script ${file.path}. No exports detected.`;
52+
LOGGER.error(msg);
53+
new Notice(
54+
msg
55+
, 3000);
56+
throw new Error(msg);
57+
}
58+
if (!(formula_function instanceof Function)) {
59+
const msg = `Failed to load user script ${file.path}. Default export is not a function.`
60+
LOGGER.error(msg);
61+
new Notice(
62+
msg
63+
, 3000);
64+
throw new Error(msg);
65+
}
66+
user_script_functions.set(`${file.basename}`, formula_function);
67+
}
68+
69+
async generate_object(): Promise<Record<string, unknown>> {
70+
const user_script_functions = await this.generate_user_script_functions();
71+
return Object.fromEntries(user_script_functions);
72+
}
73+
}

src/cdm/FolderModel.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ export interface ConfigColumn {
4040
media_height: number;
4141
isInline: boolean;
4242
task_hide_completed?: boolean;
43+
formula_query?: string;
4344
[key: string]: Literal;
4445
}
4546

src/cdm/SettingsModel.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export interface LocalSettings {
3838
source_data: string;
3939
sticky_first_column: boolean;
4040
row_templates_folder: string;
41+
formula_folder_path: string;
4142
}
4243

4344
export interface FilterSettings {

src/cdm/TableStateInterface.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,19 @@ export interface RowTemplateState {
8484
update: (template: string) => void;
8585
}
8686

87+
export interface AutomationState {
88+
formula: { [key: string]: unknown };
89+
info: {
90+
getFormula: (name: string) => unknown;
91+
runFormula: (input: string, row: RowDataType, dbbConfig: LocalSettings) => Literal;
92+
},
93+
actions: {
94+
loadFormulas: (ddbbConfig: LocalSettings) => Promise<void>;
95+
}
96+
}
97+
8798
export interface TableStateInterface {
99+
automations: UseBoundStore<StoreApi<AutomationState>>;
88100
configState: UseBoundStore<StoreApi<ConfigState>>;
89101
rowTemplate: UseBoundStore<StoreApi<RowTemplateState>>;
90102
data: UseBoundStore<StoreApi<DataState>>;

0 commit comments

Comments
 (0)