Files
CT/src/ViewModel/Pages/taskPageViewModel.ts
T

198 lines
6.4 KiB
TypeScript
Raw Normal View History

2024-07-22 19:54:39 +02:00
import * as React from "bloatless-react";
import BoardsAndTasksModel, {
2026-04-01 08:29:39 +00:00
BoardInfoFileContent,
} from "../../Model/Files/boardsAndTasksModel";
2024-07-22 20:02:13 +02:00
2026-04-12 19:20:37 +00:00
import BoardViewModel, { BoardPageTypes } from "./boardViewModel";
import ChatViewModel, { ChatPageTypes } from "../Chat/chatViewModel";
import CoreViewModel, { Context, ContextHost } from "../Global/coreViewModel";
2024-07-23 14:27:38 +02:00
import { IndexManager } from "../../Model/Utility/utility";
2026-04-13 10:26:03 +00:00
import { CommonKeys } from "../../View/keystrokes";
2024-07-22 20:02:13 +02:00
2026-04-12 19:20:37 +00:00
export default class TaskPageViewModel extends ContextHost<string> {
2026-04-01 08:29:39 +00:00
// data
2026-04-13 10:58:21 +00:00
readonly boardIndexManager = new IndexManager<BoardViewModel>(
2026-04-01 08:29:39 +00:00
(boardViewModel: BoardViewModel) => boardViewModel.name.value,
);
2026-04-01 08:29:39 +00:00
// paths
getBasePath = (): string[] => {
return [...this.boardsAndTasksModel.getViewPath()];
};
2026-04-13 11:23:17 +00:00
getBoardViewPath = (boardId: string): string[] => {
2026-04-01 08:29:39 +00:00
return [...this.getBasePath(), boardId];
};
getLastUsedBoardPath = (): string[] => {
2026-04-08 20:28:59 +00:00
return [...this.getBasePath(), TaskPageViewModelSubPaths.LastUsedBoard];
2026-04-01 08:29:39 +00:00
};
2024-07-23 02:40:11 +02:00
2026-04-01 08:29:39 +00:00
// state
newBoardNameInput: React.State<string> = new React.State("");
boardViewModels: React.MapState<BoardViewModel> = new React.MapState();
isShowingBoadList: React.State<boolean> = new React.State(true);
selectedBoardId: React.State<string | undefined> = new React.State<any>(
undefined,
);
2026-04-12 19:20:37 +00:00
// context
get isOpen(): boolean {
return (
this.chatViewModel.isOpen &&
this.chatViewModel.selectedPage.value == ChatPageTypes.Tasks
);
}
get contextSelection(): string | undefined {
2026-04-12 19:20:37 +00:00
return this.selectedBoardId.value;
}
2026-04-01 08:29:39 +00:00
// guards
cannotCreateBoard: React.State<boolean> = React.createProxyState(
[this.newBoardNameInput],
() => this.newBoardNameInput.value == "",
);
// methods
createBoard = (): void => {
if (this.cannotCreateBoard.value == true) return;
const boardInfoFileContent: BoardInfoFileContent =
this.boardsAndTasksModel.createBoard(this.newBoardNameInput.value);
this.newBoardNameInput.value = "";
2024-07-23 14:27:38 +02:00
2024-07-23 02:40:11 +02:00
this.showBoardInList(boardInfoFileContent);
2026-04-01 08:29:39 +00:00
this.boardsAndTasksModel.updateBoardAndSend(boardInfoFileContent);
2024-07-24 14:34:28 +02:00
this.updateBoardIndices();
2026-04-01 08:29:39 +00:00
};
updateBoard = (boardInfoFileContent: BoardInfoFileContent): void => {
this.boardsAndTasksModel.updateBoardAndSend(boardInfoFileContent);
this.updateBoardIndices();
};
deleteBoard = (boardInfoFileContent: BoardInfoFileContent): void => {
this.boardsAndTasksModel.deleteBoard(boardInfoFileContent.fileId);
this.boardViewModels.remove(boardInfoFileContent.fileId);
this.updateBoardIndices();
};
// view
toggleBoardList = (): void => {
this.isShowingBoadList.value = !this.isShowingBoadList.value;
};
showBoardInList = (boardInfo: BoardInfoFileContent): void => {
const boardViewModel: BoardViewModel = new BoardViewModel(
this.coreViewModel,
this.chatViewModel,
this.boardsAndTasksModel,
this,
boardInfo,
);
this.boardViewModels.set(boardInfo.fileId, boardViewModel);
this.chatViewModel.taskBoardSuggestions.set(boardInfo.fileId, [
boardInfo.fileId,
this.boardsAndTasksModel.getBoardName(boardInfo.fileId),
]);
};
selectBoard = (boardViewModel: BoardViewModel): void => {
this.selectedBoardId.value = boardViewModel.boardInfo.fileId;
this.chatViewModel.displayedColor.value = boardViewModel.color.value;
this.storeLastUsedBoard();
};
closeBoard = (): void => {
2026-04-12 19:20:37 +00:00
this.closeContext();
2026-04-01 08:29:39 +00:00
this.selectedBoardId.value = undefined;
this.chatViewModel.resetColor();
this.storeLastUsedBoard();
};
updateBoardIndices = (): void => {
this.boardIndexManager.update([...this.boardViewModels.value.values()]);
for (const boardViewModel of this.boardViewModels.value.values()) {
boardViewModel.updateIndex();
}
};
// storage
storeLastUsedBoard = (): void => {
const path: string[] = this.getLastUsedBoardPath();
const lastUsedBoardId: string = this.selectedBoardId.value ?? "";
this.coreViewModel.storageModel.write(path, lastUsedBoardId);
2026-04-01 08:29:39 +00:00
};
openLastUsedBoard = (): void => {
const path: string[] = this.getLastUsedBoardPath();
const lastUsedBoardId: string | null =
this.coreViewModel.storageModel.read(path);
2026-04-01 08:29:39 +00:00
if (lastUsedBoardId == null) return;
const boardViewModel: BoardViewModel | undefined =
this.boardViewModels.value.get(lastUsedBoardId);
if (boardViewModel == undefined) return;
this.selectBoard(boardViewModel);
};
// load
loadData = (): void => {
2026-04-13 19:45:52 +00:00
this.closeContext();
2026-04-01 08:29:39 +00:00
this.boardViewModels.clear();
const boardIds: string[] = this.boardsAndTasksModel.listBoardIds();
for (const boardId of boardIds) {
const boardInfo: BoardInfoFileContent | null =
this.boardsAndTasksModel.getBoardInfo(boardId);
if (boardInfo == null) continue;
this.showBoardInList(boardInfo);
}
this.updateBoardIndices();
this.openLastUsedBoard();
};
// init
constructor(
2026-04-13 10:58:21 +00:00
public readonly coreViewModel: CoreViewModel,
public readonly chatViewModel: ChatViewModel,
public readonly boardsAndTasksModel: BoardsAndTasksModel,
2026-04-01 08:29:39 +00:00
) {
2026-04-13 19:45:52 +00:00
super("task-page");
2026-04-12 19:20:37 +00:00
2026-04-01 08:29:39 +00:00
this.chatViewModel = chatViewModel;
// context
this.chatViewModel.registerContext(ChatPageTypes.Tasks, this);
this.selectedBoardId.subscribeSilent(this.updateContexts);
2026-04-01 08:29:39 +00:00
// handlers
boardsAndTasksModel.boardHandlerManager.setHandler("task-page" + this.chatViewModel.chatModel.id,
2026-04-01 08:29:39 +00:00
(boardInfoFileContent: BoardInfoFileContent) => {
this.showBoardInList(boardInfoFileContent);
this.updateBoardIndices();
},
);
2026-04-12 19:20:37 +00:00
2026-04-13 19:45:52 +00:00
this.chatViewModel.currentContext.subscribeSilent((context) => {
if (!this.isOpen) return;
if (context != this) return;
this.openLastUsedBoard();
});
2026-04-13 10:26:03 +00:00
// keystrokes
this.registerKeyStroke(CommonKeys.Options, this.toggleBoardList);
2026-04-01 08:29:39 +00:00
}
2024-07-22 20:02:13 +02:00
}
2024-07-23 18:23:26 +02:00
2026-04-08 20:28:59 +00:00
export enum TaskPageViewModelSubPaths {
2026-04-01 08:29:39 +00:00
LastUsedBoard = "last-used-board",
2024-07-23 18:51:41 +02:00
}