2024-07-22 19:54:39 +02:00
|
|
|
import * as React from "bloatless-react";
|
|
|
|
|
|
2024-07-25 17:59:11 +02:00
|
|
|
import BoardsAndTasksModel, {
|
2026-04-01 08:29:39 +00:00
|
|
|
BoardInfoFileContent,
|
2024-07-25 17:59:11 +02:00
|
|
|
} 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-13 10:58:21 +00:00
|
|
|
contextDebugDescription = "task-page";
|
2026-04-12 19:20:37 +00:00
|
|
|
|
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,
|
2024-07-23 21:33:22 +02:00
|
|
|
);
|
2024-07-28 17:09:27 +02:00
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
// paths
|
|
|
|
|
getBasePath = (): string[] => {
|
|
|
|
|
return [...this.boardsAndTasksModel.getViewPath()];
|
|
|
|
|
};
|
|
|
|
|
getBoardViewPath = (boardId): string[] => {
|
|
|
|
|
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 {
|
|
|
|
|
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 ?? "";
|
2026-04-09 16:48:22 +00:00
|
|
|
this.coreViewModel.storageModel.write(path, lastUsedBoardId);
|
2026-04-01 08:29:39 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
openLastUsedBoard = (): void => {
|
|
|
|
|
const path: string[] = this.getLastUsedBoardPath();
|
2026-04-09 16:48:22 +00:00
|
|
|
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 => {
|
|
|
|
|
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-12 19:20:37 +00:00
|
|
|
super();
|
|
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
this.chatViewModel = chatViewModel;
|
|
|
|
|
|
2026-04-06 15:50:13 +00:00
|
|
|
this.loadData();
|
|
|
|
|
|
2026-04-01 08:29:39 +00:00
|
|
|
// handlers
|
2026-04-09 16:54:56 +00:00
|
|
|
boardsAndTasksModel.boardHandlerManager.addHandler(
|
2026-04-01 08:29:39 +00:00
|
|
|
(boardInfoFileContent: BoardInfoFileContent) => {
|
|
|
|
|
this.showBoardInList(boardInfoFileContent);
|
|
|
|
|
this.updateBoardIndices();
|
|
|
|
|
},
|
|
|
|
|
);
|
2026-04-12 19:20:37 +00:00
|
|
|
|
|
|
|
|
// context
|
|
|
|
|
this.chatViewModel.registerContext(ChatPageTypes.Tasks, this);
|
|
|
|
|
this.selectedBoardId.subscribeSilent(this.updateContexts);
|
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
|
|
|
}
|