Add created file opening in CreateEffortUnderAreaExoCommand

This commit is contained in:
kitelev 2025-01-03 13:54:04 +05:00
parent 6d5a4c1266
commit 2f0a745248
12 changed files with 7266 additions and 161 deletions

View File

@ -16,6 +16,8 @@ export default class CreateEffortUnderAreaExoCommand implements ExoCommand {
throw new Error("Active file is not an Area");
}
this.ctx.createEffortUseCase.taskUnderArea(activeKo);
let effort = await this.ctx.createEffortUseCase.taskUnderArea(activeKo);
await this.ctx.appUtils.openKObject(effort);
}
}

View File

@ -1,30 +1,48 @@
import EffortRepository from "../../../../core/src/ports/output/EffortRepository";
import Effort from "../../../../core/src/domain/effort/Effort";
import ExoContext from "../../../../common/ExoContext";
import Area from "../../../../core/src/domain/Area";
export default class EffortPersistenceAdapter implements EffortRepository {
constructor(private ctx: ExoContext) {
}
async save(effort: Effort): Promise<void> {
const folderPath: string = this.getPathForCreate(effort)
const folderPath: string = this.ctx.effortPathRulesHelper.getEffortPath(effort)
const filePath = folderPath + "/" + effort.title + ".md";
const data: string = "---\ntags:\n - EMS/Effort\n---\n\nThis is effort created with Exo!";
await this.ctx.app.vault.create(filePath, data);
const data = this.serializeData(effort);
await this.ctx.appUtils.createFile(filePath, data);
}
// TODO should be in EffortPathRulesHelper in app module
getPathForCreate(effort: Effort): string {
if (effort.area !== null) {
const areaFile = this.ctx.appUtils.getObjectFileOrThrow(effort.area);
const areaFolder = areaFile.parent;
if (!areaFolder) {
throw new Error("Area file has no parent folder");
async update(effort: Effort): Promise<void> {
const file = this.ctx.appUtils.getObjectFileOrThrow(effort);
const data = this.serializeData(effort);
await this.ctx.app.vault.modify(file, data);
}
return areaFolder.path;
private serializeData(effort: Effort) {
let result = "";
result += "---\n"; // frontmatter start
result += "tags:\n";
result += " - EMS/Effort\n";
result += "uid: " + effort.id + "\n";
result += "e-status: " + effort.status + "\n";
if (effort.started) {
result += "started: " + effort.started + "\n";
}
if (effort.ended) {
result += "ended: " + effort.ended + "\n";
}
if (effort.area) {
result += "area: \"" + this.getLinkToArea(effort.area) + "\"\n";
}
result += "---\n"; // frontmatter end
result += effort.body;
return result;
}
return "/0 Inbox/";
private getLinkToArea(area: Area): string {
return `[[${area.name}]]`;
}
}

View File

@ -0,0 +1,31 @@
import ExoContext from "../../../common/ExoContext";
import Effort from "../../../core/src/domain/effort/Effort";
export default class EffortPathRulesHelper {
constructor(private ctx: ExoContext) {
}
getEffortPath(effort: Effort) {
if (effort.area !== null) {
const areaFile = this.ctx.appUtils.getObjectFileOrThrow(effort.area);
const areaFolder = areaFile.parent;
if (!areaFolder) {
throw new Error("Area file has no parent folder");
}
return areaFolder.path;
}
if (effort.parent !== null) {
const parentFile = this.ctx.appUtils.getObjectFileOrThrow(effort.parent);
const parentFolder = parentFile.parent;
if (!parentFolder) {
throw new Error("Effort parent file has no parent folder");
}
return parentFolder.path;
}
return "/0 Inbox/";
}
}

View File

@ -6,7 +6,24 @@ export default class AppUtils {
}
async createFile(path: string, textContent: string) {
await this.app.vault.create(path, textContent);
let file = await this.app.vault.create(path, textContent);
await this.waitCacheUpdate(file);
}
private async waitCacheUpdate(file: TFile) {
const fileCachePromise = new Promise<CachedMetadata | null>((resolve) => {
const onCacheUpdate = (updatedFile: TFile) => {
if (updatedFile.path === file.path) {
const fileCache = this.app.metadataCache.getFileCache(file);
this.app.metadataCache.off("changed", onCacheUpdate); // Убираем подписку
resolve(fileCache || null); // Обрабатываем случай с null
}
};
this.app.metadataCache.on("changed", onCacheUpdate);
});
await fileCachePromise;
}
async openKObject(ko: KObject) {

View File

@ -14,6 +14,7 @@ import CreateEffortService from "../core/src/service/CreateEffortService";
import EffortRepository from "../core/src/ports/output/EffortRepository";
import EffortPersistenceAdapter from "../app/src/adapters/output/EffortPersistenceAdapter";
import KObjectUtility from "../app/src/utils/KObjectUtility";
import EffortPathRulesHelper from "../app/src/helpers/EffortPathRulesHelper";
export default class ExoContext {
public readonly utils: Utils;
@ -28,6 +29,7 @@ export default class ExoContext {
public readonly getCurrentDNUseCase: GetCurrentDailyNoteUseCase;
public readonly createEffortUseCase: CreateEffortUseCase;
public readonly effortRepository: EffortRepository;
public readonly effortPathRulesHelper: EffortPathRulesHelper;
constructor(public app: App) {
this.utils = new Utils(this.app);
@ -41,5 +43,6 @@ export default class ExoContext {
this.getCurrentDNUseCase = new GetCurrentDailyNoteService(this.dailyNoteRepository);
this.effortRepository = new EffortPersistenceAdapter(this);
this.createEffortUseCase = new CreateEffortService(this.effortRepository);
this.effortPathRulesHelper = new EffortPathRulesHelper(this);
}
}

View File

@ -10,7 +10,9 @@ export default class Effort extends KObject {
public status: EffortStatus,
public started: Date | null,
public ended: Date | null,
public area: Area | null) {
public area: Area | null,
public parent: Effort | null,
public body: string) {
super(id, KOC.EMS_EFFORT);
}

View File

@ -1,8 +1,8 @@
export enum EffortStatus {
DRAFT,
BACKLOG,
READY,
STARTED,
ENDED,
TRASHED
DRAFT = "DRAFT",
BACKLOG = "BACKLOG",
READY = "READY",
STARTED = "STARTED",
ENDED = "ENDED",
TRASHED = "TRASHED"
}

View File

@ -2,5 +2,5 @@ import Effort from "../../domain/effort/Effort";
import Area from "../../domain/Area";
export default interface CreateEffortUseCase {
taskUnderArea(area: Area): Effort;
taskUnderArea(area: Area): Promise<Effort>;
}

View File

@ -1,5 +1,5 @@
import Effort from "../../domain/effort/Effort";
export default interface EffortRepository {
save(effort: Effort): void;
save(effort: Effort): Promise<void>;
}

View File

@ -9,12 +9,12 @@ export default class CreateEffortService implements CreateEffortUseCase {
constructor(private effortRepository: EffortRepository) {
}
taskUnderArea(area: Area): Effort {
const title = "Task under " + area.name;
async taskUnderArea(area: Area): Promise<Effort> {
const title = crypto.randomUUID();
const id = crypto.randomUUID() as UUID;
const effort = new Effort(id, title, EffortStatus.DRAFT, null, null, area);
const effort = new Effort(id, title, EffortStatus.DRAFT, null, null, area, null, "Body");
this.effortRepository.save(effort);
await this.effortRepository.save(effort);
return effort;
}

7295
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -33,6 +33,7 @@
},
"dependencies": {
"compare-versions": "^6.1.1",
"jest": "^29.7.0"
"jest": "^29.7.0",
"obsidian-dev-utils": "^11.3.0"
}
}