implement task version history
This commit is contained in:
@@ -5,12 +5,12 @@ import {
|
||||
checkMatchesObjectStructure,
|
||||
} from "../Utility/typeSafety";
|
||||
import FileModel, { FileContent, FileModelSubPath } from "./fileModel";
|
||||
import { v4, version } from "uuid";
|
||||
|
||||
import ChatModel from "../Chat/chatModel";
|
||||
import { Color } from "../../colors";
|
||||
import { HandlerManager } from "../Utility/utility";
|
||||
import StorageModel from "../Global/storageModel";
|
||||
import { v4 } from "uuid";
|
||||
|
||||
export default class BoardModel {
|
||||
storageModel: StorageModel;
|
||||
@@ -169,12 +169,30 @@ export default class BoardModel {
|
||||
return fileIds;
|
||||
};
|
||||
|
||||
getTaskFileContent = (taskId: string): TaskFileContent | null => {
|
||||
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);
|
||||
const taskReferencePath: string[] = this.getTaskReferencePath(
|
||||
|
||||
@@ -13,3 +13,12 @@ export const StringToOption: React.StateItemConverter<string> = (
|
||||
) => {
|
||||
return Option(string, string, false);
|
||||
};
|
||||
|
||||
export const VersionIdToOption: React.StateItemConverter<string> = (
|
||||
versionId: string
|
||||
) => {
|
||||
const [date, rest] = versionId.split("T");
|
||||
const [time] = rest.split(".");
|
||||
const readableName = `${date} ${time}`;
|
||||
return Option(readableName, versionId, false);
|
||||
};
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import * as React from "bloatless-react";
|
||||
|
||||
import { StringToOption, VersionIdToOption } from "../Components/option";
|
||||
|
||||
import { DangerousActionButton } from "../Components/dangerousActionButton";
|
||||
import TaskViewModel from "../../ViewModel/Pages/taskViewModel";
|
||||
import { translations } from "../translations";
|
||||
@@ -11,6 +13,20 @@ export function TaskSettingsModal(taskViewModel: TaskViewModel) {
|
||||
<main>
|
||||
<h2>{translations.chatPage.task.taskSettingsHeadline}</h2>
|
||||
|
||||
<label class="tile flex-no">
|
||||
<span class="icon">history</span>
|
||||
<div>
|
||||
<span>{translations.general.fileVersionLabel}</span>
|
||||
<select
|
||||
bind:value={taskViewModel.selectedVersionId}
|
||||
children:append={[taskViewModel.versionIds, VersionIdToOption]}
|
||||
></select>
|
||||
<span class="icon">arrow_drop_down</span>
|
||||
</div>
|
||||
</label>
|
||||
|
||||
<hr></hr>
|
||||
|
||||
<label class="tile flex-no">
|
||||
<span class="icon">label</span>
|
||||
<div>
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
const englishTranslations = {
|
||||
general: {
|
||||
deleteItemButtonAudioLabel: "delete item",
|
||||
|
||||
|
||||
abortButton: "Abort",
|
||||
closeButton: "Close",
|
||||
|
||||
|
||||
confirmButton: "Confirm",
|
||||
saveButton: "Save",
|
||||
setButton: "Set",
|
||||
|
||||
fileVersionLabel: "Version",
|
||||
},
|
||||
|
||||
regional: {
|
||||
@@ -134,7 +136,7 @@ const englishTranslations = {
|
||||
createBoardButtonAudioLabel: "create board",
|
||||
|
||||
///
|
||||
|
||||
|
||||
noBoardSelected: "No board selected",
|
||||
boardNotFound: "Board not found",
|
||||
|
||||
|
||||
@@ -175,7 +175,7 @@ export default class BoardViewModel {
|
||||
);
|
||||
for (const taskId of taskIds) {
|
||||
const taskFileContent: TaskFileContent | null =
|
||||
this.boardModel.getTaskFileContent(taskId);
|
||||
this.boardModel.getLatestTaskFileContent(taskId);
|
||||
if (taskFileContent == null) continue;
|
||||
|
||||
const taskViewModel: TaskViewModel = new TaskViewModel(
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
import * as React from "bloatless-react";
|
||||
|
||||
import BoardModel, { TaskFileContent } from "../../Model/Files/boardModel";
|
||||
import { localeCompare, padZero } from "../../Model/Utility/utility";
|
||||
|
||||
import BoardViewModel from "./boardViewModel";
|
||||
import { padZero } from "../../Model/Utility/utility";
|
||||
|
||||
export default class TaskViewModel {
|
||||
boardModel: BoardModel;
|
||||
@@ -49,6 +49,9 @@ export default class TaskViewModel {
|
||||
date: React.State<string> = new React.State("");
|
||||
time: React.State<string> = new React.State("");
|
||||
|
||||
selectedVersionId: React.State<string> = new React.State("");
|
||||
versionIds: React.ListState<string> = new React.ListState();
|
||||
|
||||
// view
|
||||
open = (): void => {
|
||||
this.boardViewModel.selectTask(this);
|
||||
@@ -96,7 +99,30 @@ export default class TaskViewModel {
|
||||
};
|
||||
|
||||
// load
|
||||
loadVersionIds = (): void => {
|
||||
const versionIds: string[] = this.boardModel.listTaskVersionIds(
|
||||
this.task.fileId
|
||||
);
|
||||
const sortedVersionIds = versionIds.sort(localeCompare).reverse();
|
||||
this.versionIds.clear();
|
||||
this.versionIds.add(...sortedVersionIds);
|
||||
};
|
||||
|
||||
switchVersion = (versionId: string): void => {
|
||||
const taskFileContent: TaskFileContent | null =
|
||||
this.boardModel.getSpecificTaskFileContent(this.task.fileId, versionId);
|
||||
if (taskFileContent == null) return;
|
||||
|
||||
this.task = taskFileContent;
|
||||
this.loadTaskData();
|
||||
};
|
||||
|
||||
loadAllData = (): void => {
|
||||
this.loadTaskData();
|
||||
this.loadVersionIds();
|
||||
};
|
||||
|
||||
loadTaskData = (): void => {
|
||||
this.name.value = this.task.name;
|
||||
this.description.value = this.task.description ?? "";
|
||||
|
||||
@@ -106,6 +132,8 @@ export default class TaskViewModel {
|
||||
|
||||
this.date.value = this.task.date ?? "";
|
||||
this.time.value = this.task.time ?? "";
|
||||
|
||||
this.selectedVersionId.value = this.task.fileContentId;
|
||||
};
|
||||
|
||||
// init
|
||||
@@ -119,6 +147,12 @@ export default class TaskViewModel {
|
||||
|
||||
this.task = taskFileContent;
|
||||
|
||||
// load
|
||||
this.loadAllData();
|
||||
|
||||
// subscriptions
|
||||
this.selectedVersionId.subscribeSilent((selectedVersionId) => {
|
||||
this.switchVersion(selectedVersionId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user