implement auto reconnect
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
// this file is responsible for managing boards within chats and tasks within boards.
|
||||
|
||||
import {
|
||||
DATA_VERSION,
|
||||
checkMatchesObjectStructure,
|
||||
DATA_VERSION,
|
||||
checkMatchesObjectStructure,
|
||||
} from "../Utility/typeSafety";
|
||||
import FileModel, { FileContent, FileModelSubPath } from "./fileModel";
|
||||
|
||||
@@ -15,316 +15,324 @@ import StorageModel from "../Global/storageModel";
|
||||
import { v4 } from "uuid";
|
||||
|
||||
export default class BoardsAndTasksModel {
|
||||
storageModel: StorageModel;
|
||||
settingsModel: SettingsModel;
|
||||
chatModel: ChatModel;
|
||||
fileModel: FileModel;
|
||||
storageModel: StorageModel;
|
||||
settingsModel: SettingsModel;
|
||||
chatModel: ChatModel;
|
||||
fileModel: FileModel;
|
||||
|
||||
calendarModel: CalendarModel;
|
||||
calendarModel: CalendarModel;
|
||||
|
||||
// data
|
||||
boardHandlerManager: HandlerManager<BoardInfoFileContent> =
|
||||
new HandlerManager();
|
||||
taskHandlerManager: HandlerManager<TaskFileContent> = new HandlerManager();
|
||||
// data
|
||||
boardHandlerManager: HandlerManager<BoardInfoFileContent> =
|
||||
new HandlerManager();
|
||||
taskHandlerManager: HandlerManager<TaskFileContent> = new HandlerManager();
|
||||
|
||||
// paths
|
||||
getBasePath = (): string[] => {
|
||||
return this.fileModel.getModelContainerPath(FileModelSubPath.ModelTask);
|
||||
};
|
||||
// paths
|
||||
getBasePath = (): string[] => {
|
||||
return this.fileModel.getModelContainerPath(FileModelSubPath.ModelTask);
|
||||
};
|
||||
|
||||
getViewPath = (): string[] => {
|
||||
return [...this.getBasePath(), FileModelSubPath.ModelView];
|
||||
};
|
||||
getViewPath = (): string[] => {
|
||||
return [...this.getBasePath(), FileModelSubPath.ModelView];
|
||||
};
|
||||
|
||||
getBoardFilePath = (boardId: string): string[] => {
|
||||
return [...this.fileModel.getFilePath(boardId)];
|
||||
};
|
||||
getBoardFilePath = (boardId: string): string[] => {
|
||||
return [...this.fileModel.getFilePath(boardId)];
|
||||
};
|
||||
|
||||
getTaskFilePath = (taskId: string): string[] => {
|
||||
return [...this.fileModel.getFilePath(taskId)];
|
||||
};
|
||||
getTaskFilePath = (taskId: string): string[] => {
|
||||
return [...this.fileModel.getFilePath(taskId)];
|
||||
};
|
||||
|
||||
getBoardContainerPath = (): string[] => {
|
||||
return [...this.getBasePath(), TaskModelSubPaths.Boards];
|
||||
};
|
||||
getBoardContainerPath = (): string[] => {
|
||||
return [...this.getBasePath(), TaskModelSubPaths.Boards];
|
||||
};
|
||||
|
||||
getBoardDirectoryPath = (boardId: string): string[] => {
|
||||
return [...this.getBoardContainerPath(), boardId];
|
||||
};
|
||||
getBoardDirectoryPath = (boardId: string): string[] => {
|
||||
return [...this.getBoardContainerPath(), boardId];
|
||||
};
|
||||
|
||||
getTaskContainerPath = (boardId: string): string[] => {
|
||||
return [
|
||||
...this.getBoardDirectoryPath(boardId),
|
||||
TaskModelSubPaths.BoardTasks,
|
||||
];
|
||||
};
|
||||
getTaskContainerPath = (boardId: string): string[] => {
|
||||
return [
|
||||
...this.getBoardDirectoryPath(boardId),
|
||||
TaskModelSubPaths.BoardTasks,
|
||||
];
|
||||
};
|
||||
|
||||
getTaskReferencePath = (boardId: string, fileId: string): string[] => {
|
||||
return [...this.getTaskContainerPath(boardId), fileId];
|
||||
};
|
||||
getTaskReferencePath = (boardId: string, fileId: string): string[] => {
|
||||
return [...this.getTaskContainerPath(boardId), fileId];
|
||||
};
|
||||
|
||||
// handlers
|
||||
handleFileContent = (fileContent: FileContent<string>): void => {
|
||||
if (
|
||||
checkMatchesObjectStructure(fileContent, BoardInfoFileContentReference) ==
|
||||
true
|
||||
// handlers
|
||||
handleFileContent = (fileContent: FileContent<string>): void => {
|
||||
if (
|
||||
checkMatchesObjectStructure(
|
||||
fileContent,
|
||||
BoardInfoFileContentReference,
|
||||
) == true
|
||||
) {
|
||||
this.handleBoard(fileContent as BoardInfoFileContent);
|
||||
} else if (
|
||||
checkMatchesObjectStructure(
|
||||
fileContent,
|
||||
TaskFileContentReference,
|
||||
) == true
|
||||
) {
|
||||
this.handleTask(fileContent as TaskFileContent);
|
||||
}
|
||||
};
|
||||
|
||||
handleBoard = (boardInfoFileContent: BoardInfoFileContent) => {
|
||||
this.updateBoard(boardInfoFileContent);
|
||||
};
|
||||
|
||||
handleTask = (taskFileContent: TaskFileContent) => {
|
||||
this.updateTask(taskFileContent);
|
||||
};
|
||||
|
||||
// boards
|
||||
createBoard = (name: string): BoardInfoFileContent => {
|
||||
const boardInfoFileContent: BoardInfoFileContent =
|
||||
BoardsAndTasksModel.createBoardInfoFileContent(
|
||||
v4(),
|
||||
name,
|
||||
Color.Standard,
|
||||
);
|
||||
return boardInfoFileContent;
|
||||
};
|
||||
|
||||
updateBoard = (boardInfoFileContent: BoardInfoFileContent): void => {
|
||||
this.storeBoard(boardInfoFileContent);
|
||||
this.boardHandlerManager.trigger(boardInfoFileContent);
|
||||
};
|
||||
|
||||
updateBoardAndSend = (boardInfoFileContent: BoardInfoFileContent): void => {
|
||||
this.updateBoard(boardInfoFileContent);
|
||||
this.chatModel.sendMessage("", boardInfoFileContent);
|
||||
};
|
||||
|
||||
storeBoard = (boardInfoFileContent: BoardInfoFileContent): void => {
|
||||
// store info
|
||||
this.fileModel.storeFileContent(boardInfoFileContent);
|
||||
|
||||
// add to list
|
||||
const boardDirectoryPath: string[] = this.getBoardDirectoryPath(
|
||||
boardInfoFileContent.fileId,
|
||||
);
|
||||
this.storageModel.write(boardDirectoryPath, "");
|
||||
};
|
||||
|
||||
deleteBoard = (boardId: string): void => {
|
||||
const boardFilePath: string[] = this.getBoardFilePath(boardId);
|
||||
const boardDirectoryPath: string[] =
|
||||
this.getBoardDirectoryPath(boardId);
|
||||
|
||||
this.storageModel.removeRecursively(boardFilePath);
|
||||
this.storageModel.removeRecursively(boardDirectoryPath);
|
||||
};
|
||||
|
||||
listBoardIds = (): string[] => {
|
||||
const boardContainerPath: string[] = this.getBoardContainerPath();
|
||||
const boardIds: string[] = this.storageModel.list(boardContainerPath);
|
||||
return boardIds;
|
||||
};
|
||||
|
||||
getBoardInfo = (fileId: string): BoardInfoFileContent | null => {
|
||||
const boardInfoFileContentOrNull: BoardInfoFileContent | null =
|
||||
this.fileModel.getLatestFileContent(
|
||||
fileId,
|
||||
BoardInfoFileContentReference,
|
||||
);
|
||||
return boardInfoFileContentOrNull;
|
||||
};
|
||||
|
||||
getBoardName = (boardId: string): string => {
|
||||
const boardInfo: BoardInfoFileContent | null =
|
||||
this.getBoardInfo(boardId);
|
||||
if (boardInfo == null) return "";
|
||||
return boardInfo.name;
|
||||
};
|
||||
|
||||
//tasks
|
||||
createTask = (boardId: string): TaskFileContent => {
|
||||
const taskFileContent: TaskFileContent =
|
||||
BoardsAndTasksModel.createTaskFileContent(v4(), "", boardId);
|
||||
return taskFileContent;
|
||||
};
|
||||
|
||||
updateTask = (taskFileContent: TaskFileContent): void => {
|
||||
this.storeTask(taskFileContent);
|
||||
this.taskHandlerManager.trigger(taskFileContent);
|
||||
};
|
||||
|
||||
updateTaskAndSend = (taskFileContent: TaskFileContent): void => {
|
||||
this.updateTask(taskFileContent);
|
||||
this.chatModel.sendMessage("", taskFileContent);
|
||||
};
|
||||
|
||||
storeTask = (taskFileContent: TaskFileContent): void => {
|
||||
// store info
|
||||
this.fileModel.storeFileContent(taskFileContent);
|
||||
|
||||
// add to board
|
||||
const taskReferencePath: string[] = this.getTaskReferencePath(
|
||||
taskFileContent.boardId,
|
||||
taskFileContent.fileId,
|
||||
);
|
||||
this.storageModel.write(taskReferencePath, "");
|
||||
|
||||
// add to calendar
|
||||
this.calendarModel.storeTaskReference(taskFileContent);
|
||||
};
|
||||
|
||||
listTaskIds = (boardId: string): string[] => {
|
||||
const taskContainerPath: string[] = this.getTaskContainerPath(boardId);
|
||||
const fileIds: string[] = this.storageModel.list(taskContainerPath);
|
||||
return fileIds;
|
||||
};
|
||||
|
||||
listTaskVersionIds = (taskId: string): string[] => {
|
||||
const versionIds: string[] = this.fileModel.listFileContentIds(taskId);
|
||||
return versionIds;
|
||||
};
|
||||
|
||||
getLatestTaskFileContent = (taskId: string): TaskFileContent | null => {
|
||||
const taskFileContentOrNull: TaskFileContent | null =
|
||||
this.fileModel.getLatestFileContent(
|
||||
taskId,
|
||||
TaskFileContentReference,
|
||||
);
|
||||
return taskFileContentOrNull;
|
||||
};
|
||||
|
||||
getSpecificTaskFileContent = (
|
||||
taskId: string,
|
||||
versionId: string,
|
||||
): TaskFileContent | null => {
|
||||
const taskFileContentOrNull: TaskFileContent | null =
|
||||
this.fileModel.getFileContent(
|
||||
taskId,
|
||||
versionId,
|
||||
TaskFileContentReference,
|
||||
);
|
||||
return taskFileContentOrNull;
|
||||
};
|
||||
|
||||
deleteTask = (boardId: string, taskId: string): void => {
|
||||
const taskFilePath: string[] = this.getTaskFilePath(taskId);
|
||||
this.storageModel.removeRecursively(taskFilePath);
|
||||
|
||||
this.deleteTaskReference(boardId, taskId);
|
||||
};
|
||||
|
||||
deleteTaskReference = (boardId: string, taskId: string): void => {
|
||||
const taskReferencePath: string[] = this.getTaskReferencePath(
|
||||
boardId,
|
||||
taskId,
|
||||
);
|
||||
this.storageModel.removeRecursively(taskReferencePath);
|
||||
};
|
||||
|
||||
// init
|
||||
constructor(
|
||||
storageModel: StorageModel,
|
||||
settingsModel: SettingsModel,
|
||||
chatModel: ChatModel,
|
||||
fileModel: FileModel,
|
||||
) {
|
||||
this.handleBoard(fileContent as BoardInfoFileContent);
|
||||
} else if (
|
||||
checkMatchesObjectStructure(fileContent, TaskFileContentReference) == true
|
||||
) {
|
||||
this.handleTask(fileContent as TaskFileContent);
|
||||
this.storageModel = storageModel;
|
||||
this.settingsModel = settingsModel;
|
||||
this.chatModel = chatModel;
|
||||
this.fileModel = fileModel;
|
||||
|
||||
this.calendarModel = new CalendarModel(
|
||||
this.storageModel,
|
||||
this.settingsModel,
|
||||
this.fileModel,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
handleBoard = (boardInfoFileContent: BoardInfoFileContent) => {
|
||||
this.updateBoard(boardInfoFileContent);
|
||||
};
|
||||
// utility
|
||||
static createBoardInfoFileContent = (
|
||||
fileId: string,
|
||||
name: string,
|
||||
color: Color,
|
||||
): BoardInfoFileContent => {
|
||||
const fileContent: FileContent<"board-info"> =
|
||||
FileModel.createFileContent(fileId, "board-info");
|
||||
return {
|
||||
...fileContent,
|
||||
|
||||
handleTask = (taskFileContent: TaskFileContent) => {
|
||||
this.updateTask(taskFileContent);
|
||||
};
|
||||
|
||||
// boards
|
||||
createBoard = (name: string): BoardInfoFileContent => {
|
||||
const boardInfoFileContent: BoardInfoFileContent =
|
||||
BoardsAndTasksModel.createBoardInfoFileContent(
|
||||
v4(),
|
||||
name,
|
||||
Color.Standard
|
||||
);
|
||||
return boardInfoFileContent;
|
||||
};
|
||||
|
||||
updateBoard = (boardInfoFileContent: BoardInfoFileContent): void => {
|
||||
this.storeBoard(boardInfoFileContent);
|
||||
this.boardHandlerManager.trigger(boardInfoFileContent);
|
||||
};
|
||||
|
||||
updateBoardAndSend = (boardInfoFileContent: BoardInfoFileContent): void => {
|
||||
this.updateBoard(boardInfoFileContent);
|
||||
this.chatModel.sendMessage("", boardInfoFileContent);
|
||||
};
|
||||
|
||||
storeBoard = (boardInfoFileContent: BoardInfoFileContent): void => {
|
||||
// store info
|
||||
this.fileModel.storeFileContent(boardInfoFileContent);
|
||||
|
||||
// add to list
|
||||
const boardDirectoryPath: string[] = this.getBoardDirectoryPath(
|
||||
boardInfoFileContent.fileId
|
||||
);
|
||||
this.storageModel.write(boardDirectoryPath, "");
|
||||
};
|
||||
|
||||
deleteBoard = (boardId: string): void => {
|
||||
const boardFilePath: string[] = this.getBoardFilePath(boardId);
|
||||
const boardDirectoryPath: string[] = this.getBoardDirectoryPath(boardId);
|
||||
|
||||
this.storageModel.removeRecursively(boardFilePath);
|
||||
this.storageModel.removeRecursively(boardDirectoryPath);
|
||||
};
|
||||
|
||||
listBoardIds = (): string[] => {
|
||||
const boardContainerPath: string[] = this.getBoardContainerPath();
|
||||
const boardIds: string[] = this.storageModel.list(boardContainerPath);
|
||||
return boardIds;
|
||||
};
|
||||
|
||||
getBoardInfo = (fileId: string): BoardInfoFileContent | null => {
|
||||
const boardInfoFileContentOrNull: BoardInfoFileContent | null =
|
||||
this.fileModel.getLatestFileContent(
|
||||
fileId,
|
||||
BoardInfoFileContentReference
|
||||
);
|
||||
return boardInfoFileContentOrNull;
|
||||
};
|
||||
|
||||
getBoardName = (boardId: string): string => {
|
||||
const boardInfo: BoardInfoFileContent|null = this.getBoardInfo(boardId);
|
||||
if (boardInfo == null) return "";
|
||||
return boardInfo.name;
|
||||
}
|
||||
|
||||
//tasks
|
||||
createTask = (boardId: string): TaskFileContent => {
|
||||
const taskFileContent: TaskFileContent =
|
||||
BoardsAndTasksModel.createTaskFileContent(v4(), "", boardId);
|
||||
return taskFileContent;
|
||||
};
|
||||
|
||||
updateTask = (taskFileContent: TaskFileContent): void => {
|
||||
this.storeTask(taskFileContent);
|
||||
this.taskHandlerManager.trigger(taskFileContent);
|
||||
};
|
||||
|
||||
updateTaskAndSend = (taskFileContent: TaskFileContent): void => {
|
||||
this.updateTask(taskFileContent);
|
||||
this.chatModel.sendMessage("", taskFileContent);
|
||||
};
|
||||
|
||||
storeTask = (taskFileContent: TaskFileContent): void => {
|
||||
// store info
|
||||
this.fileModel.storeFileContent(taskFileContent);
|
||||
|
||||
// add to board
|
||||
const taskReferencePath: string[] = this.getTaskReferencePath(
|
||||
taskFileContent.boardId,
|
||||
taskFileContent.fileId
|
||||
);
|
||||
this.storageModel.write(taskReferencePath, "");
|
||||
|
||||
// add to calendar
|
||||
this.calendarModel.storeTaskReference(taskFileContent);
|
||||
};
|
||||
|
||||
listTaskIds = (boardId: string): string[] => {
|
||||
const taskContainerPath: string[] = this.getTaskContainerPath(boardId);
|
||||
const fileIds: string[] = this.storageModel.list(taskContainerPath);
|
||||
return fileIds;
|
||||
};
|
||||
|
||||
listTaskVersionIds = (taskId: string): string[] => {
|
||||
const versionIds: string[] = this.fileModel.listFileContentIds(taskId);
|
||||
return versionIds;
|
||||
};
|
||||
|
||||
getLatestTaskFileContent = (taskId: string): TaskFileContent | null => {
|
||||
const taskFileContentOrNull: TaskFileContent | null =
|
||||
this.fileModel.getLatestFileContent(taskId, TaskFileContentReference);
|
||||
return taskFileContentOrNull;
|
||||
};
|
||||
|
||||
getSpecificTaskFileContent = (
|
||||
taskId: string,
|
||||
versionId: string
|
||||
): TaskFileContent | null => {
|
||||
const taskFileContentOrNull: TaskFileContent | null =
|
||||
this.fileModel.getFileContent(
|
||||
taskId,
|
||||
versionId,
|
||||
TaskFileContentReference
|
||||
);
|
||||
return taskFileContentOrNull;
|
||||
};
|
||||
|
||||
deleteTask = (boardId: string, taskId: string): void => {
|
||||
const taskFilePath: string[] = this.getTaskFilePath(taskId);
|
||||
this.storageModel.removeRecursively(taskFilePath);
|
||||
|
||||
this.deleteTaskReference(boardId, taskId);
|
||||
};
|
||||
|
||||
deleteTaskReference = (boardId: string, taskId: string): void => {
|
||||
const taskReferencePath: string[] = this.getTaskReferencePath(
|
||||
boardId,
|
||||
taskId
|
||||
);
|
||||
this.storageModel.removeRecursively(taskReferencePath);
|
||||
};
|
||||
|
||||
// init
|
||||
constructor(
|
||||
storageModel: StorageModel,
|
||||
settingsModel: SettingsModel,
|
||||
chatModel: ChatModel,
|
||||
fileModel: FileModel
|
||||
) {
|
||||
this.storageModel = storageModel;
|
||||
this.settingsModel = settingsModel;
|
||||
this.chatModel = chatModel;
|
||||
this.fileModel = fileModel;
|
||||
|
||||
this.calendarModel = new CalendarModel(
|
||||
this.storageModel,
|
||||
this.settingsModel,
|
||||
this.fileModel
|
||||
);
|
||||
}
|
||||
|
||||
// utility
|
||||
static createBoardInfoFileContent = (
|
||||
fileId: string,
|
||||
name: string,
|
||||
color: Color
|
||||
): BoardInfoFileContent => {
|
||||
const fileContent: FileContent<"board-info"> = FileModel.createFileContent(
|
||||
fileId,
|
||||
"board-info"
|
||||
);
|
||||
return {
|
||||
...fileContent,
|
||||
|
||||
name,
|
||||
color,
|
||||
name,
|
||||
color,
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
static createTaskFileContent = (
|
||||
fileId: string,
|
||||
name: string,
|
||||
boardId: string
|
||||
): TaskFileContent => {
|
||||
const fileContent: FileContent<"task"> = FileModel.createFileContent(
|
||||
fileId,
|
||||
"task"
|
||||
);
|
||||
return {
|
||||
...fileContent,
|
||||
static createTaskFileContent = (
|
||||
fileId: string,
|
||||
name: string,
|
||||
boardId: string,
|
||||
): TaskFileContent => {
|
||||
const fileContent: FileContent<"task"> = FileModel.createFileContent(
|
||||
fileId,
|
||||
"task",
|
||||
);
|
||||
return {
|
||||
...fileContent,
|
||||
|
||||
name,
|
||||
boardId,
|
||||
name,
|
||||
boardId,
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export enum TaskModelSubPaths {
|
||||
Boards = "boards",
|
||||
BoardTasks = "tasks",
|
||||
Boards = "boards",
|
||||
BoardTasks = "tasks",
|
||||
}
|
||||
|
||||
// types
|
||||
export interface BoardInfoFileContent extends FileContent<"board-info"> {
|
||||
name: string;
|
||||
color: Color;
|
||||
name: string;
|
||||
color: Color;
|
||||
}
|
||||
|
||||
export interface TaskFileContent extends FileContent<"task"> {
|
||||
name: string;
|
||||
boardId: string;
|
||||
name: string;
|
||||
boardId: string;
|
||||
|
||||
description?: string;
|
||||
description?: string;
|
||||
|
||||
category?: string;
|
||||
status?: string;
|
||||
priority?: string;
|
||||
category?: string;
|
||||
status?: string;
|
||||
priority?: string;
|
||||
|
||||
date?: string;
|
||||
time?: string;
|
||||
date?: string;
|
||||
time?: string;
|
||||
}
|
||||
|
||||
// reference
|
||||
export const BoardInfoFileContentReference: BoardInfoFileContent = {
|
||||
dataVersion: DATA_VERSION,
|
||||
dataVersion: DATA_VERSION,
|
||||
|
||||
fileId: "string",
|
||||
fileContentId: "",
|
||||
creationDate: "",
|
||||
fileId: "string",
|
||||
fileContentId: "",
|
||||
creationDate: "",
|
||||
|
||||
type: "board-info",
|
||||
type: "board-info",
|
||||
|
||||
name: "",
|
||||
color: "" as Color,
|
||||
name: "",
|
||||
color: "" as Color,
|
||||
};
|
||||
|
||||
export const TaskFileContentReference: TaskFileContent = {
|
||||
dataVersion: DATA_VERSION,
|
||||
dataVersion: DATA_VERSION,
|
||||
|
||||
fileId: "string",
|
||||
fileContentId: "",
|
||||
creationDate: "",
|
||||
type: "task",
|
||||
fileId: "string",
|
||||
fileContentId: "",
|
||||
creationDate: "",
|
||||
type: "task",
|
||||
|
||||
name: "",
|
||||
boardId: "",
|
||||
name: "",
|
||||
boardId: "",
|
||||
};
|
||||
|
||||
+138
-136
@@ -7,158 +7,160 @@ import StorageModel from "../Global/storageModel";
|
||||
import { TaskFileContent } from "./boardsAndTasksModel";
|
||||
|
||||
export default class CalendarModel {
|
||||
storageModel: StorageModel;
|
||||
fileModel: FileModel;
|
||||
settingsModel: SettingsModel;
|
||||
storageModel: StorageModel;
|
||||
fileModel: FileModel;
|
||||
settingsModel: SettingsModel;
|
||||
|
||||
// paths
|
||||
getBasePath = (): string[] => {
|
||||
return this.fileModel.getModelContainerPath(FileModelSubPath.ModelCalendar);
|
||||
};
|
||||
|
||||
getViewPath = (): string[] => {
|
||||
return [...this.getBasePath(), FileModelSubPath.ModelView];
|
||||
};
|
||||
|
||||
getMonthContainerPath = (): string[] => {
|
||||
return [...this.getBasePath(), CalendarModelSubPaths.Months];
|
||||
};
|
||||
|
||||
getMonthPath = (monthString: string): string[] => {
|
||||
return [...this.getMonthContainerPath(), monthString];
|
||||
};
|
||||
|
||||
// main
|
||||
storeTaskReference = (taskFileContent: TaskFileContent): void => {
|
||||
if (taskFileContent.date == undefined) return;
|
||||
|
||||
const monthString: string = CalendarModel.isoToMonthString(
|
||||
taskFileContent.date
|
||||
);
|
||||
|
||||
const monthPath: string[] = this.getMonthPath(monthString);
|
||||
const referencePath: string[] = [...monthPath, taskFileContent.fileId];
|
||||
|
||||
this.storageModel.write(referencePath, "");
|
||||
};
|
||||
|
||||
deleteTaskReference = (monthString: string, taskId: string): void => {
|
||||
const monthPath: string[] = this.getMonthPath(monthString);
|
||||
const referencePath: string[] = [...monthPath, taskId];
|
||||
|
||||
this.storageModel.write(referencePath, "");
|
||||
};
|
||||
|
||||
listTaskIds = (monthString: string): string[] => {
|
||||
const monthPath: string[] = this.getMonthPath(monthString);
|
||||
return this.storageModel.list(monthPath);
|
||||
};
|
||||
|
||||
generateMonthGrid = <T>(
|
||||
year: number,
|
||||
month: number,
|
||||
defaultValueCreator: () => T
|
||||
): MonthGrid<T> => {
|
||||
// get today
|
||||
const date: Date = new Date();
|
||||
const isCurrentMonth: boolean =
|
||||
year == date.getFullYear() && month == date.getMonth() + 1;
|
||||
|
||||
// get data for offset
|
||||
date.setDate(1);
|
||||
date.setMonth(month - 1);
|
||||
date.setFullYear(year);
|
||||
|
||||
const firstWeekdayOfMonth = date.getDay();
|
||||
const firstDayOfWeekSetting: number = parseInt(
|
||||
this.settingsModel.firstDayOfWeek
|
||||
);
|
||||
|
||||
const offset: number =
|
||||
firstWeekdayOfMonth < firstDayOfWeekSetting
|
||||
? 7 - firstDayOfWeekSetting
|
||||
: firstWeekdayOfMonth - firstDayOfWeekSetting;
|
||||
|
||||
// get total day count
|
||||
date.setMonth(month);
|
||||
date.setDate(-1);
|
||||
const daysInMonth: number = date.getDate() + 1;
|
||||
|
||||
const grid: MonthGrid<T> = {
|
||||
offset,
|
||||
firstDayOfWeek: parseInt(this.settingsModel.firstDayOfWeek),
|
||||
isCurrentMonth,
|
||||
year,
|
||||
month,
|
||||
days: {},
|
||||
// paths
|
||||
getBasePath = (): string[] => {
|
||||
return this.fileModel.getModelContainerPath(
|
||||
FileModelSubPath.ModelCalendar,
|
||||
);
|
||||
};
|
||||
|
||||
for (let i = 0; i < daysInMonth; i++) {
|
||||
const paddedDate: string = CalendarModel.padDateOrMonth(
|
||||
(i + 1).toString()
|
||||
);
|
||||
grid.days[paddedDate] = defaultValueCreator();
|
||||
getViewPath = (): string[] => {
|
||||
return [...this.getBasePath(), FileModelSubPath.ModelView];
|
||||
};
|
||||
|
||||
getMonthContainerPath = (): string[] => {
|
||||
return [...this.getBasePath(), CalendarModelSubPaths.Months];
|
||||
};
|
||||
|
||||
getMonthPath = (monthString: string): string[] => {
|
||||
return [...this.getMonthContainerPath(), monthString];
|
||||
};
|
||||
|
||||
// main
|
||||
storeTaskReference = (taskFileContent: TaskFileContent): void => {
|
||||
if (taskFileContent.date == undefined) return;
|
||||
|
||||
const monthString: string = CalendarModel.isoToMonthString(
|
||||
taskFileContent.date,
|
||||
);
|
||||
|
||||
const monthPath: string[] = this.getMonthPath(monthString);
|
||||
const referencePath: string[] = [...monthPath, taskFileContent.fileId];
|
||||
|
||||
this.storageModel.write(referencePath, "");
|
||||
};
|
||||
|
||||
deleteTaskReference = (monthString: string, taskId: string): void => {
|
||||
const monthPath: string[] = this.getMonthPath(monthString);
|
||||
const referencePath: string[] = [...monthPath, taskId];
|
||||
|
||||
this.storageModel.write(referencePath, "");
|
||||
};
|
||||
|
||||
listTaskIds = (monthString: string): string[] => {
|
||||
const monthPath: string[] = this.getMonthPath(monthString);
|
||||
return this.storageModel.list(monthPath);
|
||||
};
|
||||
|
||||
generateMonthGrid = <T>(
|
||||
year: number,
|
||||
month: number,
|
||||
defaultValueCreator: () => T,
|
||||
): MonthGrid<T> => {
|
||||
// get today
|
||||
const date: Date = new Date();
|
||||
const isCurrentMonth: boolean =
|
||||
year == date.getFullYear() && month == date.getMonth() + 1;
|
||||
|
||||
// get data for offset
|
||||
date.setDate(1);
|
||||
date.setMonth(month - 1);
|
||||
date.setFullYear(year);
|
||||
|
||||
const firstWeekdayOfMonth = date.getDay();
|
||||
const firstDayOfWeekSetting: number = parseInt(
|
||||
this.settingsModel.firstDayOfWeek,
|
||||
);
|
||||
|
||||
const offset: number =
|
||||
firstWeekdayOfMonth < firstDayOfWeekSetting
|
||||
? 7 - firstDayOfWeekSetting
|
||||
: firstWeekdayOfMonth - firstDayOfWeekSetting;
|
||||
|
||||
// get total day count
|
||||
date.setMonth(month);
|
||||
date.setDate(-1);
|
||||
const daysInMonth: number = date.getDate() + 1;
|
||||
|
||||
const grid: MonthGrid<T> = {
|
||||
offset,
|
||||
firstDayOfWeek: parseInt(this.settingsModel.firstDayOfWeek),
|
||||
isCurrentMonth,
|
||||
year,
|
||||
month,
|
||||
days: {},
|
||||
};
|
||||
|
||||
for (let i = 0; i < daysInMonth; i++) {
|
||||
const paddedDate: string = CalendarModel.padDateOrMonth(
|
||||
(i + 1).toString(),
|
||||
);
|
||||
grid.days[paddedDate] = defaultValueCreator();
|
||||
}
|
||||
|
||||
return grid;
|
||||
};
|
||||
|
||||
// init
|
||||
constructor(
|
||||
storageModel: StorageModel,
|
||||
settingsModel: SettingsModel,
|
||||
fileModel: FileModel,
|
||||
) {
|
||||
this.storageModel = storageModel;
|
||||
this.settingsModel = settingsModel;
|
||||
this.fileModel = fileModel;
|
||||
}
|
||||
|
||||
return grid;
|
||||
};
|
||||
// utility
|
||||
static isoToMonthString = (dateISOString: string): string => {
|
||||
const [year, month, _] = dateISOString.split("-");
|
||||
return CalendarModel.getMonthString(year, month);
|
||||
};
|
||||
|
||||
// init
|
||||
constructor(
|
||||
storageModel: StorageModel,
|
||||
settingsModel: SettingsModel,
|
||||
fileModel: FileModel
|
||||
) {
|
||||
this.storageModel = storageModel;
|
||||
this.settingsModel = settingsModel;
|
||||
this.fileModel = fileModel;
|
||||
}
|
||||
static isoToDateString = (dateISOString: string): string => {
|
||||
const [year, month, date, _] = dateISOString.split("-");
|
||||
const paddedDate = CalendarModel.padDateOrMonth(date ?? "");
|
||||
return paddedDate;
|
||||
};
|
||||
|
||||
// utility
|
||||
static isoToMonthString = (dateISOString: string): string => {
|
||||
const [year, month, _] = dateISOString.split("-");
|
||||
return CalendarModel.getMonthString(year, month);
|
||||
};
|
||||
static getMonthString = (year: string = "", month: string = ""): string => {
|
||||
const paddedYear: string = year.padStart(4, "0");
|
||||
const paddedMonth: string = CalendarModel.padDateOrMonth(month);
|
||||
return `${paddedYear}-${paddedMonth}`;
|
||||
};
|
||||
|
||||
static isoToDateString = (dateISOString: string): string => {
|
||||
const [year, month, date, _] = dateISOString.split("-");
|
||||
const paddedDate = CalendarModel.padDateOrMonth(date ?? "");
|
||||
return paddedDate;
|
||||
};
|
||||
static getISODateString = (
|
||||
year: string,
|
||||
month: string,
|
||||
date: string,
|
||||
): string => {
|
||||
const monthString: string = CalendarModel.getMonthString(year, month);
|
||||
const paddedDate: string = CalendarModel.padDateOrMonth(date);
|
||||
return `${monthString}-${paddedDate}`;
|
||||
};
|
||||
|
||||
static getMonthString = (year: string = "", month: string = ""): string => {
|
||||
const paddedYear: string = year.padStart(4, "0");
|
||||
const paddedMonth: string = CalendarModel.padDateOrMonth(month);
|
||||
return `${paddedYear}-${paddedMonth}`;
|
||||
};
|
||||
|
||||
static getISODateString = (
|
||||
year: string,
|
||||
month: string,
|
||||
date: string
|
||||
): string => {
|
||||
const monthString: string = CalendarModel.getMonthString(year, month);
|
||||
const paddedDate: string = CalendarModel.padDateOrMonth(date);
|
||||
return `${monthString}-${paddedDate}`;
|
||||
};
|
||||
|
||||
static padDateOrMonth = (input: string): string => {
|
||||
return input.padStart(2, "0");
|
||||
};
|
||||
static padDateOrMonth = (input: string): string => {
|
||||
return input.padStart(2, "0");
|
||||
};
|
||||
}
|
||||
|
||||
export enum CalendarModelSubPaths {
|
||||
Months = "months",
|
||||
Months = "months",
|
||||
}
|
||||
|
||||
// types
|
||||
export interface MonthGrid<T> {
|
||||
offset: number;
|
||||
firstDayOfWeek: number;
|
||||
isCurrentMonth: boolean;
|
||||
offset: number;
|
||||
firstDayOfWeek: number;
|
||||
isCurrentMonth: boolean;
|
||||
|
||||
year: number;
|
||||
month: number;
|
||||
year: number;
|
||||
month: number;
|
||||
|
||||
days: { [date: string]: T };
|
||||
days: { [date: string]: T };
|
||||
}
|
||||
|
||||
+178
-175
@@ -2,14 +2,14 @@
|
||||
|
||||
import { DATA_VERSION, ValidObject } from "../Utility/typeSafety";
|
||||
import StorageModel, {
|
||||
StorageModelSubPath,
|
||||
filePaths,
|
||||
StorageModelSubPath,
|
||||
filePaths,
|
||||
} from "../Global/storageModel";
|
||||
import {
|
||||
StringEntryObject,
|
||||
createTimestamp,
|
||||
parseValidObject,
|
||||
stringify,
|
||||
StringEntryObject,
|
||||
createTimestamp,
|
||||
parseValidObject,
|
||||
stringify,
|
||||
} from "../Utility/utility";
|
||||
|
||||
import BoardsAndTasksModel from "./boardsAndTasksModel";
|
||||
@@ -18,191 +18,194 @@ import SettingsModel from "../Global/settingsModel";
|
||||
import { v4 } from "uuid";
|
||||
|
||||
export default class FileModel {
|
||||
storageModel: StorageModel;
|
||||
settingsModel: SettingsModel;
|
||||
storageModel: StorageModel;
|
||||
settingsModel: SettingsModel;
|
||||
|
||||
chatModel: ChatModel;
|
||||
boardsAndTasksModel: BoardsAndTasksModel;
|
||||
chatModel: ChatModel;
|
||||
boardsAndTasksModel: BoardsAndTasksModel;
|
||||
|
||||
// paths
|
||||
getBasePath = (): string[] => {
|
||||
return StorageModel.getPath(
|
||||
StorageModelSubPath.Chat,
|
||||
filePaths.chat.files(this.chatModel.id)
|
||||
);
|
||||
};
|
||||
|
||||
getFileContainerPath = (): string[] => {
|
||||
return [...this.getBasePath(), FileModelSubPath.Data];
|
||||
};
|
||||
|
||||
getModelContainerPath = (modelName: FileModelSubPath): string[] => {
|
||||
return [...this.getBasePath(), FileModelSubPath.Model, modelName];
|
||||
};
|
||||
|
||||
getFilePath = (fileId: string): string[] => {
|
||||
return [...this.getFileContainerPath(), fileId];
|
||||
};
|
||||
|
||||
getFileContentPath = (fileId: string, fileContentId: string): string[] => {
|
||||
const filePath: string[] = this.getFilePath(fileId);
|
||||
return [...filePath, fileContentId];
|
||||
};
|
||||
|
||||
// handlers
|
||||
handleStringifiedFileContent = (stringifiedFileContent: string): void => {
|
||||
const fileContent: FileContent<string> | null = parseValidObject(
|
||||
stringifiedFileContent,
|
||||
FileContentReference
|
||||
);
|
||||
if (fileContent == null) return;
|
||||
|
||||
this.handleFileContent(fileContent);
|
||||
};
|
||||
|
||||
handleFileContent = (fileContent: FileContent<string>): void => {
|
||||
const didStore: boolean = this.storeFileContent(fileContent);
|
||||
if (didStore == false) return;
|
||||
|
||||
this.boardsAndTasksModel.handleFileContent(fileContent);
|
||||
};
|
||||
|
||||
// methods
|
||||
addFileContentAndSend = (fileContent: FileContent<string>): void => {
|
||||
this.handleFileContent(fileContent);
|
||||
this.chatModel.sendMessage("", fileContent);
|
||||
};
|
||||
|
||||
// storage
|
||||
storeFileContent = (fileContent: FileContent<string>): boolean => {
|
||||
const fileContentPath: string[] = this.getFileContentPath(
|
||||
fileContent.fileId,
|
||||
fileContent.fileContentId
|
||||
);
|
||||
|
||||
// check if fileContent already exists
|
||||
const existingFileContent: string | null =
|
||||
this.storageModel.read(fileContentPath);
|
||||
if (existingFileContent != null) return false;
|
||||
|
||||
const stringifiedContent: string = stringify(fileContent);
|
||||
this.storageModel.write(fileContentPath, stringifiedContent);
|
||||
return true;
|
||||
};
|
||||
|
||||
listFileIds = (): string[] => {
|
||||
return this.storageModel.list(this.getBasePath());
|
||||
};
|
||||
|
||||
listFileContentIds = (fileId: string): string[] => {
|
||||
const filePath: string[] = this.getFilePath(fileId);
|
||||
return this.storageModel.list(filePath);
|
||||
};
|
||||
|
||||
selectLatestFileContentId = (
|
||||
fileContentIds: string[]
|
||||
): string | undefined => {
|
||||
return fileContentIds[fileContentIds.length - 1];
|
||||
};
|
||||
|
||||
getFileContent = <T extends FileContent<string>>(
|
||||
fileId: string,
|
||||
fileContentName: string,
|
||||
reference: T
|
||||
): T | null => {
|
||||
const filePath: string[] = this.getFileContentPath(fileId, fileContentName);
|
||||
const fileContentOrNull: T | null = this.storageModel.readStringifiable(
|
||||
filePath,
|
||||
reference
|
||||
);
|
||||
return fileContentOrNull;
|
||||
};
|
||||
|
||||
getLatestFileContent = <T extends FileContent<string>>(
|
||||
fileId: string,
|
||||
reference: T
|
||||
): T | null => {
|
||||
const fileContentsIds: string[] = this.listFileContentIds(fileId);
|
||||
const latestFileContentId: string | undefined =
|
||||
this.selectLatestFileContentId(fileContentsIds);
|
||||
if (latestFileContentId == undefined) return null;
|
||||
|
||||
const fileContent: T | null = this.getFileContent(
|
||||
fileId,
|
||||
latestFileContentId,
|
||||
reference
|
||||
);
|
||||
return fileContent;
|
||||
};
|
||||
|
||||
// init
|
||||
constructor(
|
||||
storageModel: StorageModel,
|
||||
settingsModel: SettingsModel,
|
||||
chatModel: ChatModel
|
||||
) {
|
||||
this.chatModel = chatModel;
|
||||
this.settingsModel = settingsModel;
|
||||
this.storageModel = storageModel;
|
||||
|
||||
this.boardsAndTasksModel = new BoardsAndTasksModel(
|
||||
this.storageModel,
|
||||
this.settingsModel,
|
||||
chatModel,
|
||||
this
|
||||
);
|
||||
}
|
||||
|
||||
// utility
|
||||
static generateFileContentId = (creationDate: string): string => {
|
||||
return creationDate + v4();
|
||||
};
|
||||
|
||||
static createFileContent = <T extends string>(
|
||||
fileId: string,
|
||||
type: T
|
||||
): FileContent<T> => {
|
||||
const creationDate: string = createTimestamp();
|
||||
const fileContentId: string = FileModel.generateFileContentId(creationDate);
|
||||
|
||||
return {
|
||||
dataVersion: DATA_VERSION,
|
||||
|
||||
fileId,
|
||||
fileContentId,
|
||||
creationDate,
|
||||
type,
|
||||
// paths
|
||||
getBasePath = (): string[] => {
|
||||
return StorageModel.getPath(
|
||||
StorageModelSubPath.Chat,
|
||||
filePaths.chat.files(this.chatModel.id),
|
||||
);
|
||||
};
|
||||
|
||||
getFileContainerPath = (): string[] => {
|
||||
return [...this.getBasePath(), FileModelSubPath.Data];
|
||||
};
|
||||
|
||||
getModelContainerPath = (modelName: FileModelSubPath): string[] => {
|
||||
return [...this.getBasePath(), FileModelSubPath.Model, modelName];
|
||||
};
|
||||
|
||||
getFilePath = (fileId: string): string[] => {
|
||||
return [...this.getFileContainerPath(), fileId];
|
||||
};
|
||||
|
||||
getFileContentPath = (fileId: string, fileContentId: string): string[] => {
|
||||
const filePath: string[] = this.getFilePath(fileId);
|
||||
return [...filePath, fileContentId];
|
||||
};
|
||||
|
||||
// handlers
|
||||
handleStringifiedFileContent = (stringifiedFileContent: string): void => {
|
||||
const fileContent: FileContent<string> | null = parseValidObject(
|
||||
stringifiedFileContent,
|
||||
FileContentReference,
|
||||
);
|
||||
if (fileContent == null) return;
|
||||
|
||||
this.handleFileContent(fileContent);
|
||||
};
|
||||
|
||||
handleFileContent = (fileContent: FileContent<string>): void => {
|
||||
const didStore: boolean = this.storeFileContent(fileContent);
|
||||
if (didStore == false) return;
|
||||
|
||||
this.boardsAndTasksModel.handleFileContent(fileContent);
|
||||
};
|
||||
|
||||
// methods
|
||||
addFileContentAndSend = (fileContent: FileContent<string>): void => {
|
||||
this.handleFileContent(fileContent);
|
||||
this.chatModel.sendMessage("", fileContent);
|
||||
};
|
||||
|
||||
// storage
|
||||
storeFileContent = (fileContent: FileContent<string>): boolean => {
|
||||
const fileContentPath: string[] = this.getFileContentPath(
|
||||
fileContent.fileId,
|
||||
fileContent.fileContentId,
|
||||
);
|
||||
|
||||
// check if fileContent already exists
|
||||
const existingFileContent: string | null =
|
||||
this.storageModel.read(fileContentPath);
|
||||
if (existingFileContent != null) return false;
|
||||
|
||||
const stringifiedContent: string = stringify(fileContent);
|
||||
this.storageModel.write(fileContentPath, stringifiedContent);
|
||||
return true;
|
||||
};
|
||||
|
||||
listFileIds = (): string[] => {
|
||||
return this.storageModel.list(this.getBasePath());
|
||||
};
|
||||
|
||||
listFileContentIds = (fileId: string): string[] => {
|
||||
const filePath: string[] = this.getFilePath(fileId);
|
||||
return this.storageModel.list(filePath);
|
||||
};
|
||||
|
||||
selectLatestFileContentId = (
|
||||
fileContentIds: string[],
|
||||
): string | undefined => {
|
||||
return fileContentIds[fileContentIds.length - 1];
|
||||
};
|
||||
|
||||
getFileContent = <T extends FileContent<string>>(
|
||||
fileId: string,
|
||||
fileContentName: string,
|
||||
reference: T,
|
||||
): T | null => {
|
||||
const filePath: string[] = this.getFileContentPath(
|
||||
fileId,
|
||||
fileContentName,
|
||||
);
|
||||
const fileContentOrNull: T | null = this.storageModel.readStringifiable(
|
||||
filePath,
|
||||
reference,
|
||||
);
|
||||
return fileContentOrNull;
|
||||
};
|
||||
|
||||
getLatestFileContent = <T extends FileContent<string>>(
|
||||
fileId: string,
|
||||
reference: T,
|
||||
): T | null => {
|
||||
const fileContentsIds: string[] = this.listFileContentIds(fileId);
|
||||
const latestFileContentId: string | undefined =
|
||||
this.selectLatestFileContentId(fileContentsIds);
|
||||
if (latestFileContentId == undefined) return null;
|
||||
|
||||
const fileContent: T | null = this.getFileContent(
|
||||
fileId,
|
||||
latestFileContentId,
|
||||
reference,
|
||||
);
|
||||
return fileContent;
|
||||
};
|
||||
|
||||
// init
|
||||
constructor(
|
||||
storageModel: StorageModel,
|
||||
settingsModel: SettingsModel,
|
||||
chatModel: ChatModel,
|
||||
) {
|
||||
this.chatModel = chatModel;
|
||||
this.settingsModel = settingsModel;
|
||||
this.storageModel = storageModel;
|
||||
|
||||
this.boardsAndTasksModel = new BoardsAndTasksModel(
|
||||
this.storageModel,
|
||||
this.settingsModel,
|
||||
chatModel,
|
||||
this,
|
||||
);
|
||||
}
|
||||
|
||||
// utility
|
||||
static generateFileContentId = (creationDate: string): string => {
|
||||
return creationDate + v4();
|
||||
};
|
||||
|
||||
static createFileContent = <T extends string>(
|
||||
fileId: string,
|
||||
type: T,
|
||||
): FileContent<T> => {
|
||||
const creationDate: string = createTimestamp();
|
||||
const fileContentId: string =
|
||||
FileModel.generateFileContentId(creationDate);
|
||||
|
||||
return {
|
||||
dataVersion: DATA_VERSION,
|
||||
|
||||
fileId,
|
||||
fileContentId,
|
||||
creationDate,
|
||||
type,
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
// paths
|
||||
export enum FileModelSubPath {
|
||||
Data = "data",
|
||||
Model = "model",
|
||||
ModelView = "view",
|
||||
ModelTask = "tasks",
|
||||
ModelCalendar = "calendar",
|
||||
Data = "data",
|
||||
Model = "model",
|
||||
ModelView = "view",
|
||||
ModelTask = "tasks",
|
||||
ModelCalendar = "calendar",
|
||||
}
|
||||
|
||||
// types
|
||||
export interface FileContent<T extends string>
|
||||
extends ValidObject,
|
||||
StringEntryObject {
|
||||
fileId: string;
|
||||
fileContentId: string;
|
||||
creationDate: string;
|
||||
extends ValidObject, StringEntryObject {
|
||||
fileId: string;
|
||||
fileContentId: string;
|
||||
creationDate: string;
|
||||
|
||||
type: T;
|
||||
type: T;
|
||||
}
|
||||
|
||||
// references
|
||||
export const FileContentReference: FileContent<string> = {
|
||||
dataVersion: DATA_VERSION,
|
||||
dataVersion: DATA_VERSION,
|
||||
|
||||
fileId: "",
|
||||
fileContentId: "",
|
||||
creationDate: "",
|
||||
fileId: "",
|
||||
fileContentId: "",
|
||||
creationDate: "",
|
||||
|
||||
type: "",
|
||||
type: "",
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user