fix object editing

This commit is contained in:
marlon-erler
2024-07-11 16:45:45 +02:00
parent a824ad97d5
commit 4cc9201bc5
4 changed files with 145 additions and 101 deletions
+62 -41
View File
@@ -621,25 +621,35 @@
}; };
// objects // objects
createObjectFromTitle = (title) => { createObjectFromTitle = (title) => {
return { const firstObjectContent = this.createObjectContent();
const messageObject = {
id: UUID(), id: UUID(),
title, title,
contentVersions: [this.createObjectContent()] contentVersions: {}
};
this.addObjectContent(messageObject, firstObjectContent);
return messageObject;
};
createObjectContent = () => {
return {
id: UUID(),
isoDateVersionCreated: (/* @__PURE__ */ new Date()).toISOString()
}; };
}; };
addObject = (messageObject) => { addObjectContent = (messageObject, content) => {
this.objects.set(messageObject.id, messageObject); messageObject.contentVersions[content.id] = content;
}; };
updateObject = (id, contents) => { addObject = (messageObject) => {
const messageObject = this.objects.value.get(id); const existingObject = this.objects.value.get(messageObject.id);
if (!messageObject) return; if (existingObject) {
if (contents) { existingObject.title = messageObject.title;
messageObject.contentVersions.push(contents); Object.values(messageObject.contentVersions).forEach((content) => {
messageObject.contentVersions.sort( this.addObjectContent(existingObject, content);
(a, b) => a.isoDateVersionCreated > b.isoDateVersionCreated ? 0 : 1 });
); this.objects.set(existingObject.id, existingObject);
} else {
this.objects.set(messageObject.id, messageObject);
} }
this.sendObject(messageObject);
}; };
addObjectAndSend = (messageObject) => { addObjectAndSend = (messageObject) => {
this.addObject(messageObject); this.addObject(messageObject);
@@ -661,18 +671,23 @@
clearObjects = () => { clearObjects = () => {
this.objects.clear(); this.objects.clear();
}; };
getLatestObjectContent = (messageObject) => { getSortedContents = (messageObject) => {
return this.getObjectContentFromIndex(messageObject, 0); const contents = Object.values(messageObject.contentVersions);
contents.sort(
(a, b) => a.isoDateVersionCreated > b.isoDateVersionCreated ? 0 : 1
);
return contents;
}; };
getObjectContentFromIndex = (messageObject, index) => { getMostRecentContentId = (messageObject) => {
const versions = messageObject.contentVersions; const contents = Object.values(messageObject.contentVersions);
return versions[index] ?? this.createObjectContent(); return contents[contents.length - 1].id;
}; };
createObjectContent = () => { getMostRecentContent = (messageObject) => {
return { const id = this.getMostRecentContentId(messageObject);
id: UUID(), return this.getObjectContentFromId(messageObject, id);
isoDateVersionCreated: (/* @__PURE__ */ new Date()).toISOString() };
}; getObjectContentFromId = (messageObject, contentId) => {
return messageObject.contentVersions[contentId];
}; };
// channel // channel
setChannel = () => { setChannel = () => {
@@ -1209,13 +1224,12 @@
// src/Views/Objects/objectDetailModal.tsx // src/Views/Objects/objectDetailModal.tsx
function ObjectDetailModal(chat, messageObject, isPresented) { function ObjectDetailModal(chat, messageObject, isPresented) {
const editingTitle = new State(messageObject.title); const editingTitle = new State(messageObject.title);
const selectedMessageObjectIndex = new State(0); const selectedMessageObjectId = new State(
chat.getMostRecentContentId(messageObject)
);
const selectedMessageObject = createProxyState( const selectedMessageObject = createProxyState(
[selectedMessageObjectIndex], [selectedMessageObjectId],
() => chat.getObjectContentFromIndex( () => chat.getObjectContentFromId(messageObject, selectedMessageObjectId.value)
messageObject,
selectedMessageObjectIndex.value
)
); );
const didEditContent = new State(false); const didEditContent = new State(false);
const editingNoteContent = createProxyState( const editingNoteContent = createProxyState(
@@ -1240,14 +1254,14 @@
} }
function saveAndClose() { function saveAndClose() {
messageObject.title = editingTitle.value; messageObject.title = editingTitle.value;
chat.updateObject( if (didEditContent.value == true) {
messageObject.id, chat.addObjectContent(messageObject, {
didEditContent.value == true ? {
isoDateVersionCreated: (/* @__PURE__ */ new Date()).toISOString(), isoDateVersionCreated: (/* @__PURE__ */ new Date()).toISOString(),
id: UUID(), id: UUID(),
noteContent: editingNoteContent.value noteContent: editingNoteContent.value
} : void 0 });
); }
chat.addObjectAndSend(messageObject);
closeModal(); closeModal();
} }
function deleteAndClose() { function deleteAndClose() {
@@ -1260,7 +1274,9 @@
"bind:value": editingTitle, "bind:value": editingTitle,
placeholder: translation.objectTitlePlaceholder placeholder: translation.objectTitlePlaceholder
} }
))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "history"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.objectVersion), /* @__PURE__ */ createElement("select", { "bind:value": selectedMessageObjectIndex }, ...messageObject.contentVersions.map((content, index) => /* @__PURE__ */ createElement("option", { value: index }, new Date(content.isoDateVersionCreated).toLocaleString()))), /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_drop_down"))), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "sticky_note_2"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.noteContent), /* @__PURE__ */ createElement( ))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "history"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.objectVersion), /* @__PURE__ */ createElement("select", { "bind:value": selectedMessageObjectId }, ...chat.getSortedContents(messageObject).map((content) => /* @__PURE__ */ createElement("option", { value: content.id }, new Date(
content.isoDateVersionCreated
).toLocaleString()))), /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_drop_down"))), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "sticky_note_2"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.noteContent), /* @__PURE__ */ createElement(
"textarea", "textarea",
{ {
rows: "5", rows: "5",
@@ -1279,17 +1295,22 @@
function ChatToolView(chat) { function ChatToolView(chat) {
const isShowingObjectModal = new State(false); const isShowingObjectModal = new State(false);
const selectedObject = new State(void 0); const selectedObject = new State(void 0);
const objectModal = createProxyState([selectedObject], () => { const objectModal = createProxyState(
if (selectedObject.value == void 0) return /* @__PURE__ */ createElement("div", null); [chat.objects, selectedObject],
return ObjectDetailModal(chat, selectedObject.value, isShowingObjectModal); () => {
}); if (selectedObject.value == void 0) return /* @__PURE__ */ createElement("div", null);
return ObjectDetailModal(
chat,
selectedObject.value,
isShowingObjectModal
);
}
);
function createItem() { function createItem() {
const newObject = chat.createObjectFromTitle("New item"); const newObject = chat.createObjectFromTitle("New item");
chat.addObjectAndSend(newObject); chat.addObjectAndSend(newObject);
} }
const itemConverter = (messageObject) => { const itemConverter = (messageObject) => {
const latestObject = chat.getLatestObjectContent(messageObject);
if (!latestObject) return /* @__PURE__ */ createElement("div", null);
function select() { function select() {
selectedObject.value = messageObject; selectedObject.value = messageObject;
isShowingObjectModal.value = true; isShowingObjectModal.value = true;
+49 -30
View File
@@ -29,7 +29,7 @@ export interface ChatMessage {
export interface MessageObject { export interface MessageObject {
id: string; id: string;
title: string; title: string;
contentVersions: MessageObjectContent[]; contentVersions: { [key: string]: MessageObjectContent };
} }
export interface MessageObjectContent { export interface MessageObjectContent {
@@ -156,8 +156,8 @@ export class Chat {
if (channels.indexOf(this.primaryChannel.value) == -1) return; if (channels.indexOf(this.primaryChannel.value) == -1) return;
if (data.subscribed != undefined) this.handleSubscription(data.subscribed); if (data.subscribed != undefined) this.handleSubscription(data.subscribed);
if (!data.messageBody) return; if (!data.messageBody) return;
const message: ChatMessage = JSON.parse(data.messageBody); const message: ChatMessage = JSON.parse(data.messageBody);
const { sender, body, channel, isoDate, messageObjectString } = message; const { sender, body, channel, isoDate, messageObjectString } = message;
@@ -197,7 +197,6 @@ export class Chat {
}; };
// sending // sending
sendMessagesInOutbox = () => { sendMessagesInOutbox = () => {
this.outbox.value.forEach(async (message) => { this.outbox.value.forEach(async (message) => {
const isSent = await this.sendMessage(message); const isSent = await this.sendMessage(message);
@@ -298,27 +297,41 @@ export class Chat {
// objects // objects
createObjectFromTitle = (title: string): MessageObject => { createObjectFromTitle = (title: string): MessageObject => {
return { const firstObjectContent = this.createObjectContent();
const messageObject: MessageObject = {
id: React.UUID(), id: React.UUID(),
title, title,
contentVersions: [this.createObjectContent()], contentVersions: {},
};
this.addObjectContent(messageObject, firstObjectContent);
return messageObject;
};
createObjectContent = () => {
return {
id: React.UUID(),
isoDateVersionCreated: new Date().toISOString(),
}; };
}; };
addObject = (messageObject: MessageObject): void => { addObjectContent = (
this.objects.set(messageObject.id, messageObject); messageObject: MessageObject,
content: MessageObjectContent
): void => {
messageObject.contentVersions[content.id] = content;
}; };
updateObject = (id: string, contents?: MessageObjectContent): void => { addObject = (messageObject: MessageObject): void => {
const messageObject = this.objects.value.get(id); const existingObject = this.objects.value.get(messageObject.id);
if (!messageObject) return; if (existingObject) {
if (contents) { existingObject.title = messageObject.title;
messageObject.contentVersions.push(contents); Object.values(messageObject.contentVersions).forEach((content) => {
messageObject.contentVersions.sort((a, b) => this.addObjectContent(existingObject, content);
a.isoDateVersionCreated > b.isoDateVersionCreated ? 0 : 1 });
); this.objects.set(existingObject.id, existingObject);
} else {
this.objects.set(messageObject.id, messageObject);
} }
this.sendObject(messageObject);
}; };
addObjectAndSend = (messageObject: MessageObject): void => { addObjectAndSend = (messageObject: MessageObject): void => {
@@ -346,25 +359,31 @@ export class Chat {
this.objects.clear(); this.objects.clear();
}; };
getLatestObjectContent = ( getSortedContents = (
messageObject: MessageObject messageObject: MessageObject
): MessageObjectContent => { ): MessageObjectContent[] => {
return this.getObjectContentFromIndex(messageObject, 0); const contents = Object.values(messageObject.contentVersions);
contents.sort((a, b) =>
a.isoDateVersionCreated > b.isoDateVersionCreated ? 0 : 1
);
return contents;
}; };
getObjectContentFromIndex = ( getMostRecentContentId = (messageObject: MessageObject): string => {
const contents = Object.values(messageObject.contentVersions);
return contents[contents.length - 1].id;
};
getMostRecentContent = (messageObject: MessageObject): MessageObjectContent => {
const id = this.getMostRecentContentId(messageObject);
return this.getObjectContentFromId(messageObject, id);
}
getObjectContentFromId = (
messageObject: MessageObject, messageObject: MessageObject,
index: number contentId: string
): MessageObjectContent => { ): MessageObjectContent => {
const versions = messageObject.contentVersions; return messageObject.contentVersions[contentId];
return versions[index] ?? this.createObjectContent();
};
createObjectContent = () => {
return {
id: React.UUID(),
isoDateVersionCreated: new Date().toISOString(),
};
}; };
// channel // channel
+23 -22
View File
@@ -12,14 +12,13 @@ export function ObjectDetailModal(
// state // state
const editingTitle = new React.State(messageObject.title); const editingTitle = new React.State(messageObject.title);
const selectedMessageObjectIndex = new React.State(0); const selectedMessageObjectId = new React.State(
chat.getMostRecentContentId(messageObject)
);
const selectedMessageObject = React.createProxyState( const selectedMessageObject = React.createProxyState(
[selectedMessageObjectIndex], [selectedMessageObjectId],
() => () =>
chat.getObjectContentFromIndex( chat.getObjectContentFromId(messageObject, selectedMessageObjectId.value)
messageObject,
selectedMessageObjectIndex.value
)
); );
const didEditContent = new React.State(false); const didEditContent = new React.State(false);
@@ -51,18 +50,16 @@ export function ObjectDetailModal(
function saveAndClose() { function saveAndClose() {
messageObject.title = editingTitle.value; messageObject.title = editingTitle.value;
chat.updateObject( if (didEditContent.value == true) {
messageObject.id, chat.addObjectContent(messageObject, {
didEditContent.value == true isoDateVersionCreated: new Date().toISOString(),
? { id: React.UUID(),
isoDateVersionCreated: new Date().toISOString(),
id: React.UUID(),
noteContent: editingNoteContent.value, noteContent: editingNoteContent.value,
} });
: undefined }
);
chat.addObjectAndSend(messageObject);
closeModal(); closeModal();
} }
@@ -98,12 +95,16 @@ export function ObjectDetailModal(
<span class="icon">history</span> <span class="icon">history</span>
<div> <div>
<span>{translation.objectVersion}</span> <span>{translation.objectVersion}</span>
<select bind:value={selectedMessageObjectIndex}> <select bind:value={selectedMessageObjectId}>
{...messageObject.contentVersions.map((content, index) => ( {...chat
<option value={index}> .getSortedContents(messageObject)
{new Date(content.isoDateVersionCreated).toLocaleString()} .map((content) => (
</option> <option value={content.id}>
))} {new Date(
content.isoDateVersionCreated
).toLocaleString()}
</option>
))}
</select> </select>
<span class="icon">arrow_drop_down</span> <span class="icon">arrow_drop_down</span>
</div> </div>
+11 -8
View File
@@ -9,11 +9,18 @@ import { translation } from "../../translations";
export function ChatToolView(chat: Chat) { export function ChatToolView(chat: Chat) {
const isShowingObjectModal = new React.State(false); const isShowingObjectModal = new React.State(false);
const selectedObject = new React.State<MessageObject | undefined>(undefined); const selectedObject = new React.State<MessageObject | undefined>(undefined);
const objectModal = React.createProxyState([selectedObject], () => { const objectModal = React.createProxyState(
if (selectedObject.value == undefined) return <div></div>; [chat.objects, selectedObject],
() => {
if (selectedObject.value == undefined) return <div></div>;
return ObjectDetailModal(chat, selectedObject.value, isShowingObjectModal); return ObjectDetailModal(
}); chat,
selectedObject.value,
isShowingObjectModal
);
}
);
function createItem() { function createItem() {
const newObject = chat.createObjectFromTitle("New item"); const newObject = chat.createObjectFromTitle("New item");
@@ -23,10 +30,6 @@ export function ChatToolView(chat: Chat) {
const itemConverter: React.StateItemConverter<MessageObject> = ( const itemConverter: React.StateItemConverter<MessageObject> = (
messageObject messageObject
) => { ) => {
const latestObject = chat.getLatestObjectContent(messageObject);
if (!latestObject) return <div></div>; //TODO
function select() { function select() {
selectedObject.value = messageObject; selectedObject.value = messageObject;
isShowingObjectModal.value = true; isShowingObjectModal.value = true;