fix bugs, improve UI
This commit is contained in:
Vendored
+10
-10
@@ -1,6 +1,6 @@
|
|||||||
/* src/styles.css */
|
/* src/styles.css */
|
||||||
[unread] {
|
[unread] {
|
||||||
border-left: 10px solid var(--text-warning);
|
border-left: 10px solid var(--text-warn);
|
||||||
}
|
}
|
||||||
:root {
|
:root {
|
||||||
--thread-view-height-with-tools: 8rem;
|
--thread-view-height-with-tools: 8rem;
|
||||||
@@ -17,21 +17,21 @@
|
|||||||
.chat-object-view {
|
.chat-object-view {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
[showingchattools] :is(.thread-view, .chat-object-view) {
|
#message-tab:has([showingchattools]) :is(.thread-view, .chat-object-view) {
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
[showingchattools] header {
|
#message-tab:has([showingchattools]) header {
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
[showingchattools] .chat-object-view {
|
#message-tab:has([showingchattools]) .chat-object-view {
|
||||||
display: flex;
|
display: flex;
|
||||||
top: var(--header-height);
|
top: var(--header-height);
|
||||||
bottom: calc(var(--thread-view-height-with-tools) + var(--footer-top-line));
|
bottom: calc(var(--thread-view-height-with-tools) + var(--footer-top-line));
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
[showingchattools] .thread-view {
|
#message-tab:has([showingchattools]) .thread-view {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: var(--thread-view-height-with-tools);
|
height: var(--thread-view-height-with-tools);
|
||||||
top: unset;
|
top: unset;
|
||||||
@@ -39,25 +39,25 @@
|
|||||||
flex: 1;
|
flex: 1;
|
||||||
}
|
}
|
||||||
@media (min-width: 640px) and (max-width: 1400px) {
|
@media (min-width: 640px) and (max-width: 1400px) {
|
||||||
main.split:has([showingchattools]) {
|
main.split:has(#message-tab [showingchattools]) {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
main.split:has([showingchattools]) #settings-tab {
|
main.split:has(#message-tab [showingchattools]) #settings-tab {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@media (min-width: 640px) {
|
@media (min-width: 640px) {
|
||||||
[showingchattools] :is(.thread-view, .chat-object-view) {
|
#message-tab:has([showingchattools]) :is(.thread-view, .chat-object-view) {
|
||||||
top: var(--header-height);
|
top: var(--header-height);
|
||||||
bottom: var(--footer-top-line);
|
bottom: var(--footer-top-line);
|
||||||
}
|
}
|
||||||
[showingchattools] .chat-object-view {
|
#message-tab:has([showingchattools]) .chat-object-view {
|
||||||
left: 0px;
|
left: 0px;
|
||||||
right: var(--thread-view-width-with-tools);
|
right: var(--thread-view-width-with-tools);
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
border-right: 1px solid var(--border);
|
border-right: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
[showingchattools] .thread-view {
|
#message-tab:has([showingchattools]) .thread-view {
|
||||||
display: flex;
|
display: flex;
|
||||||
left: unset;
|
left: unset;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
|
|||||||
Vendored
+76
-23
@@ -1232,14 +1232,54 @@
|
|||||||
connect();
|
connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/Views/Objects/allObjectsView.tsx
|
// src/icons.ts
|
||||||
function AllObjectsView(chat, selectedObject, isShowingObjectModal) {
|
var icons = {
|
||||||
const objectConverter = (messageObject) => {
|
objectTitle: "label",
|
||||||
|
objectHistory: "history",
|
||||||
|
noteContent: "sticky_note_2",
|
||||||
|
categoryName: "category",
|
||||||
|
priority: "priority_high",
|
||||||
|
date: "calendar_month",
|
||||||
|
time: "schedule"
|
||||||
|
};
|
||||||
|
|
||||||
|
// src/Views/Objects/objectEntryView.tsx
|
||||||
|
function ObjectEntryView(chat, messageObject, selectedObject, isShowingObjectModal) {
|
||||||
|
const latest = chat.getMostRecentContent(messageObject);
|
||||||
function select() {
|
function select() {
|
||||||
selectedObject.value = messageObject;
|
selectedObject.value = messageObject;
|
||||||
isShowingObjectModal.value = true;
|
isShowingObjectModal.value = true;
|
||||||
}
|
}
|
||||||
return /* @__PURE__ */ createElement("button", { class: "tile", "on:click": select }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", null, chat.getObjectTitle(messageObject)), /* @__PURE__ */ createElement("span", { class: "secondary" }, messageObject.id)));
|
const fields = {
|
||||||
|
[icons.noteContent]: "---",
|
||||||
|
[icons.priority]: "---",
|
||||||
|
[icons.categoryName]: "---",
|
||||||
|
[icons.date]: "---",
|
||||||
|
[icons.time]: "---"
|
||||||
|
};
|
||||||
|
Object.entries(latest).forEach((entry) => {
|
||||||
|
let [key, value] = entry;
|
||||||
|
if (!value) return;
|
||||||
|
const icon = icons[key];
|
||||||
|
if (!icon) return;
|
||||||
|
fields[icon] = value;
|
||||||
|
});
|
||||||
|
const fieldElements = Object.entries(fields).map((field) => {
|
||||||
|
const [icon, value] = field;
|
||||||
|
return /* @__PURE__ */ createElement("span", { class: "flex-row control-gap align-center" }, /* @__PURE__ */ createElement("span", { class: "icon" }, icon), value);
|
||||||
|
});
|
||||||
|
return /* @__PURE__ */ createElement("button", { class: "tile justify-start", "on:click": select }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", null, chat.getObjectTitle(messageObject)), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("span", { class: "flex-column gap height-100 flex secondary ellipsis " }, ...fieldElements)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// src/Views/Objects/allObjectsView.tsx
|
||||||
|
function AllObjectsView(chat, selectedObject, isShowingObjectModal) {
|
||||||
|
const objectConverter = (messageObject) => {
|
||||||
|
return ObjectEntryView(
|
||||||
|
chat,
|
||||||
|
messageObject,
|
||||||
|
selectedObject,
|
||||||
|
isShowingObjectModal
|
||||||
|
);
|
||||||
};
|
};
|
||||||
const content = createProxyState(
|
const content = createProxyState(
|
||||||
[chat.objects],
|
[chat.objects],
|
||||||
@@ -1258,12 +1298,12 @@
|
|||||||
// src/Views/Objects/noteObjectsView.tsx
|
// src/Views/Objects/noteObjectsView.tsx
|
||||||
function NoteObjectsView(chat, selectedObject, isShowingObjectModal) {
|
function NoteObjectsView(chat, selectedObject, isShowingObjectModal) {
|
||||||
const objectConverter = (messageObject) => {
|
const objectConverter = (messageObject) => {
|
||||||
const latest = chat.getMostRecentContent(messageObject);
|
return ObjectEntryView(
|
||||||
function select() {
|
chat,
|
||||||
selectedObject.value = messageObject;
|
messageObject,
|
||||||
isShowingObjectModal.value = true;
|
selectedObject,
|
||||||
}
|
isShowingObjectModal
|
||||||
return /* @__PURE__ */ createElement("button", { class: "tile", "on:click": select }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("b", null, chat.getObjectTitle(messageObject)), /* @__PURE__ */ createElement("span", { class: "secondary ellipsis" }, latest.noteContent.split("\n")[0])));
|
);
|
||||||
};
|
};
|
||||||
const notes = new ListState();
|
const notes = new ListState();
|
||||||
chat.objects.subscribe(() => {
|
chat.objects.subscribe(() => {
|
||||||
@@ -1309,18 +1349,24 @@
|
|||||||
);
|
);
|
||||||
const editingDate = createProxyState(
|
const editingDate = createProxyState(
|
||||||
[selectedMessageObject],
|
[selectedMessageObject],
|
||||||
() => selectedMessageObject.value.isoDate ?? (/* @__PURE__ */ new Date()).toISOString()
|
() => selectedMessageObject.value.date ?? ""
|
||||||
);
|
);
|
||||||
const editingTime = createProxyState(
|
const editingTime = createProxyState(
|
||||||
[selectedMessageObject],
|
[selectedMessageObject],
|
||||||
() => selectedMessageObject.value.isoTime ?? (/* @__PURE__ */ new Date()).toISOString()
|
() => selectedMessageObject.value.time ?? ""
|
||||||
);
|
);
|
||||||
const editingPriority = createProxyState(
|
const editingPriority = createProxyState(
|
||||||
[selectedMessageObject],
|
[selectedMessageObject],
|
||||||
() => selectedMessageObject.value.priority ?? 0
|
() => selectedMessageObject.value.priority ?? 0
|
||||||
);
|
);
|
||||||
bulkSubscribe(
|
bulkSubscribe(
|
||||||
[editingNoteContent, editingCategory, editingDate, editingPriority],
|
[
|
||||||
|
editingNoteContent,
|
||||||
|
editingCategory,
|
||||||
|
editingDate,
|
||||||
|
editingTime,
|
||||||
|
editingPriority
|
||||||
|
],
|
||||||
() => didEditContent.value = true
|
() => didEditContent.value = true
|
||||||
);
|
);
|
||||||
function handleKeyDown(e) {
|
function handleKeyDown(e) {
|
||||||
@@ -1344,8 +1390,8 @@
|
|||||||
noteContent: editingNoteContent.value,
|
noteContent: editingNoteContent.value,
|
||||||
priority: editingPriority.value,
|
priority: editingPriority.value,
|
||||||
categoryName: editingCategory.value,
|
categoryName: editingCategory.value,
|
||||||
isoDate: editingDate.value,
|
date: editingDate.value,
|
||||||
isoTime: editingTime.value
|
time: editingTime.value
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
chat.addObjectAndSend(messageObject);
|
chat.addObjectAndSend(messageObject);
|
||||||
@@ -1363,35 +1409,35 @@
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
isPresented.subscribe(() => setTimeout(() => input.focus(), 100));
|
isPresented.subscribe(() => setTimeout(() => input.focus(), 100));
|
||||||
return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": isPresented, "on:keydown": handleKeyDown }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("main", null, /* @__PURE__ */ createElement("h2", null, chat.getObjectTitle(messageObject)), /* @__PURE__ */ createElement("span", { class: "secondary" }, messageObject.id), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("div", { class: "flex-column gap" }, /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "label"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.objectTitle), input)), /* @__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(
|
return /* @__PURE__ */ createElement("div", { class: "modal", "toggle:open": isPresented, "on:keydown": handleKeyDown }, /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("main", null, /* @__PURE__ */ createElement("h2", null, chat.getObjectTitle(messageObject)), /* @__PURE__ */ createElement("span", { class: "secondary" }, messageObject.id), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("div", { class: "flex-column gap" }, /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, icons.objectTitle), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.objectTitle), input)), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, icons.objectHistory), /* @__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
|
content.isoDateVersionCreated
|
||||||
).toLocaleString()))), /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_drop_down"))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "sticky_note_2"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.note), /* @__PURE__ */ createElement(
|
).toLocaleString()))), /* @__PURE__ */ createElement("span", { class: "icon" }, "arrow_drop_down"))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, icons.noteContent), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.note), /* @__PURE__ */ createElement(
|
||||||
"textarea",
|
"textarea",
|
||||||
{
|
{
|
||||||
rows: "5",
|
rows: "5",
|
||||||
"bind:value": editingNoteContent,
|
"bind:value": editingNoteContent,
|
||||||
placeholder: translation.noteContentPlaceholder
|
placeholder: translation.noteContentPlaceholder
|
||||||
}
|
}
|
||||||
))), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "category"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.category), /* @__PURE__ */ createElement(
|
))), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, icons.categoryName), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.category), /* @__PURE__ */ createElement(
|
||||||
"input",
|
"input",
|
||||||
{
|
{
|
||||||
"bind:value": editingCategory,
|
"bind:value": editingCategory,
|
||||||
placeholder: translation.categoryPlaceholder
|
placeholder: translation.categoryPlaceholder
|
||||||
}
|
}
|
||||||
))), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "priority_high"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.priority), /* @__PURE__ */ createElement(
|
))), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, icons.priority), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.priority), /* @__PURE__ */ createElement(
|
||||||
"input",
|
"input",
|
||||||
{
|
{
|
||||||
type: "number",
|
type: "number",
|
||||||
"bind:value": editingPriority,
|
"bind:value": editingPriority,
|
||||||
placeholder: translation.priorityPlaceholder
|
placeholder: translation.priorityPlaceholder
|
||||||
}
|
}
|
||||||
))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "calendar_month"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.date), /* @__PURE__ */ createElement("input", { type: "date", "bind:value": editingDate }))), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, "schedule"), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.time), /* @__PURE__ */ createElement("input", { type: "time", "bind:value": editingTime }))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("button", { class: "danger width-input", "on:click": deleteAndClose }, translation.deleteObject, /* @__PURE__ */ createElement("span", { class: "icon" }, "delete")))), /* @__PURE__ */ createElement("div", { class: "flex-row" }, /* @__PURE__ */ createElement("button", { class: "flex-1 width-100 danger", "on:click": closeModal }, translation.discard), /* @__PURE__ */ createElement("button", { class: "flex-1 width-100 primary", "on:click": saveAndClose }, translation.save, /* @__PURE__ */ createElement("span", { class: "icon" }, "save")))));
|
))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, icons.date), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.date), /* @__PURE__ */ createElement("input", { type: "date", "bind:value": editingDate }))), /* @__PURE__ */ createElement("label", { class: "tile" }, /* @__PURE__ */ createElement("span", { class: "icon" }, icons.time), /* @__PURE__ */ createElement("div", null, /* @__PURE__ */ createElement("span", null, translation.time), /* @__PURE__ */ createElement("input", { type: "time", "bind:value": editingTime }))), /* @__PURE__ */ createElement("hr", null), /* @__PURE__ */ createElement("button", { class: "danger width-input", "on:click": deleteAndClose }, translation.deleteObject, /* @__PURE__ */ createElement("span", { class: "icon" }, "delete")))), /* @__PURE__ */ createElement("div", { class: "flex-row" }, /* @__PURE__ */ createElement("button", { class: "flex-1 width-100 danger", "on:click": closeModal }, translation.discard), /* @__PURE__ */ createElement("button", { class: "flex-1 width-100 primary", "on:click": saveAndClose }, translation.save, /* @__PURE__ */ createElement("span", { class: "icon" }, "save")))));
|
||||||
}
|
}
|
||||||
|
|
||||||
// src/Views/Objects/chatObjectView.tsx
|
// src/Views/Objects/chatObjectView.tsx
|
||||||
var viewTypes = {
|
var viewTypes = {
|
||||||
all: [translation.viewAll, "grid_view"],
|
all: [translation.viewAll, "grid_view"],
|
||||||
notes: [translation.viewNotes, "sticky_note_2"]
|
notes: [translation.viewNotes, icons.noteContent]
|
||||||
};
|
};
|
||||||
function ChatObjectView(chat) {
|
function ChatObjectView(chat) {
|
||||||
const isShowingObjectModal = new State(false);
|
const isShowingObjectModal = new State(false);
|
||||||
@@ -1648,7 +1694,15 @@
|
|||||||
"children:append": [chat.outbox, outboxMessageConverter]
|
"children:append": [chat.outbox, outboxMessageConverter]
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
const listWrapper = /* @__PURE__ */ createElement("div", { class: "thread-view flex-column gap" }, messageList, outboxList);
|
const listWrapper = /* @__PURE__ */ createElement(
|
||||||
|
"div",
|
||||||
|
{
|
||||||
|
class: "thread-view flex-column gap",
|
||||||
|
"toggle:showingchattools": isShowingObjects
|
||||||
|
},
|
||||||
|
messageList,
|
||||||
|
outboxList
|
||||||
|
);
|
||||||
function scrollToBottom() {
|
function scrollToBottom() {
|
||||||
listWrapper.scrollTop = listWrapper.scrollHeight;
|
listWrapper.scrollTop = listWrapper.scrollHeight;
|
||||||
}
|
}
|
||||||
@@ -1700,7 +1754,6 @@
|
|||||||
return /* @__PURE__ */ createElement(
|
return /* @__PURE__ */ createElement(
|
||||||
"article",
|
"article",
|
||||||
{
|
{
|
||||||
"toggle:showingchattools": isShowingObjects,
|
|
||||||
id: "message-tab",
|
id: "message-tab",
|
||||||
"children:set": messageTabContent
|
"children:set": messageTabContent
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,10 +39,10 @@ export interface MessageObjectContent {
|
|||||||
id: string;
|
id: string;
|
||||||
|
|
||||||
noteContent?: string;
|
noteContent?: string;
|
||||||
categoryName?: string;
|
|
||||||
isoDate?: string;
|
|
||||||
isoTime?: string;
|
|
||||||
priority?: number;
|
priority?: number;
|
||||||
|
categoryName?: string;
|
||||||
|
date?: string;
|
||||||
|
time?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// chat
|
// chat
|
||||||
|
|||||||
@@ -61,7 +61,6 @@ export function MessageTab() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<article
|
<article
|
||||||
toggle:showingchattools={isShowingObjects}
|
|
||||||
id="message-tab"
|
id="message-tab"
|
||||||
children:set={messageTabContent}
|
children:set={messageTabContent}
|
||||||
></article>
|
></article>
|
||||||
|
|||||||
@@ -117,7 +117,10 @@ export function ThreadView(chat: Chat) {
|
|||||||
></div>
|
></div>
|
||||||
);
|
);
|
||||||
const listWrapper = (
|
const listWrapper = (
|
||||||
<div class="thread-view flex-column gap">
|
<div
|
||||||
|
class="thread-view flex-column gap"
|
||||||
|
toggle:showingchattools={isShowingObjects}
|
||||||
|
>
|
||||||
{messageList}
|
{messageList}
|
||||||
{outboxList}
|
{outboxList}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import * as React from "bloatless-react";
|
|||||||
|
|
||||||
import { Chat, MessageObject } from "../../Model/chatModel";
|
import { Chat, MessageObject } from "../../Model/chatModel";
|
||||||
|
|
||||||
|
import { ObjectEntryView } from "./objectEntryView";
|
||||||
import { translation } from "../../translations";
|
import { translation } from "../../translations";
|
||||||
|
|
||||||
export function AllObjectsView(
|
export function AllObjectsView(
|
||||||
@@ -12,18 +13,11 @@ export function AllObjectsView(
|
|||||||
const objectConverter: React.StateItemConverter<MessageObject> = (
|
const objectConverter: React.StateItemConverter<MessageObject> = (
|
||||||
messageObject
|
messageObject
|
||||||
) => {
|
) => {
|
||||||
function select() {
|
return ObjectEntryView(
|
||||||
selectedObject.value = messageObject;
|
chat,
|
||||||
isShowingObjectModal.value = true;
|
messageObject,
|
||||||
}
|
selectedObject,
|
||||||
|
isShowingObjectModal
|
||||||
return (
|
|
||||||
<button class="tile" on:click={select}>
|
|
||||||
<div>
|
|
||||||
<b>{chat.getObjectTitle(messageObject)}</b>
|
|
||||||
<span class="secondary">{messageObject.id}</span>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -5,11 +5,12 @@ import { Chat, MessageObject } from "../../Model/chatModel";
|
|||||||
import { AllObjectsView } from "./allObjectsView";
|
import { AllObjectsView } from "./allObjectsView";
|
||||||
import { NoteObjectsView } from "./noteObjectsView";
|
import { NoteObjectsView } from "./noteObjectsView";
|
||||||
import { ObjectDetailModal } from "./objectDetailModal";
|
import { ObjectDetailModal } from "./objectDetailModal";
|
||||||
|
import { icons } from "../../icons";
|
||||||
import { translation } from "../../translations";
|
import { translation } from "../../translations";
|
||||||
|
|
||||||
export const viewTypes = {
|
export const viewTypes = {
|
||||||
all: [translation.viewAll, "grid_view"],
|
all: [translation.viewAll, "grid_view"],
|
||||||
notes: [translation.viewNotes, "sticky_note_2"],
|
notes: [translation.viewNotes, icons.noteContent],
|
||||||
};
|
};
|
||||||
|
|
||||||
export function ChatObjectView(chat: Chat) {
|
export function ChatObjectView(chat: Chat) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import * as React from "bloatless-react";
|
|||||||
|
|
||||||
import { Chat, MessageObject } from "../../Model/chatModel";
|
import { Chat, MessageObject } from "../../Model/chatModel";
|
||||||
|
|
||||||
|
import { ObjectEntryView } from "./objectEntryView";
|
||||||
import { translation } from "../../translations";
|
import { translation } from "../../translations";
|
||||||
|
|
||||||
export function NoteObjectsView(
|
export function NoteObjectsView(
|
||||||
@@ -12,22 +13,11 @@ export function NoteObjectsView(
|
|||||||
const objectConverter: React.StateItemConverter<MessageObject> = (
|
const objectConverter: React.StateItemConverter<MessageObject> = (
|
||||||
messageObject
|
messageObject
|
||||||
) => {
|
) => {
|
||||||
const latest = chat.getMostRecentContent(messageObject);
|
return ObjectEntryView(
|
||||||
|
chat,
|
||||||
function select() {
|
messageObject,
|
||||||
selectedObject.value = messageObject;
|
selectedObject,
|
||||||
isShowingObjectModal.value = true;
|
isShowingObjectModal
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<button class="tile" on:click={select}>
|
|
||||||
<div>
|
|
||||||
<b>{chat.getObjectTitle(messageObject)}</b>
|
|
||||||
<span class="secondary ellipsis">
|
|
||||||
{latest.noteContent!.split("\n")[0]}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</button>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import * as React from "bloatless-react";
|
|||||||
|
|
||||||
import { Chat, MessageObject } from "../../Model/chatModel";
|
import { Chat, MessageObject } from "../../Model/chatModel";
|
||||||
|
|
||||||
|
import { icons } from "../../icons";
|
||||||
import { translation } from "../../translations";
|
import { translation } from "../../translations";
|
||||||
|
|
||||||
export function ObjectDetailModal(
|
export function ObjectDetailModal(
|
||||||
@@ -33,18 +34,24 @@ export function ObjectDetailModal(
|
|||||||
);
|
);
|
||||||
const editingDate = React.createProxyState(
|
const editingDate = React.createProxyState(
|
||||||
[selectedMessageObject],
|
[selectedMessageObject],
|
||||||
() => selectedMessageObject.value.isoDate ?? new Date().toISOString()
|
() => selectedMessageObject.value.date ?? ""
|
||||||
);
|
);
|
||||||
const editingTime = React.createProxyState(
|
const editingTime = React.createProxyState(
|
||||||
[selectedMessageObject],
|
[selectedMessageObject],
|
||||||
() => selectedMessageObject.value.isoTime ?? new Date().toISOString()
|
() => selectedMessageObject.value.time ?? ""
|
||||||
);
|
);
|
||||||
const editingPriority = React.createProxyState(
|
const editingPriority = React.createProxyState(
|
||||||
[selectedMessageObject],
|
[selectedMessageObject],
|
||||||
() => selectedMessageObject.value.priority ?? 0
|
() => selectedMessageObject.value.priority ?? 0
|
||||||
);
|
);
|
||||||
React.bulkSubscribe(
|
React.bulkSubscribe(
|
||||||
[editingNoteContent, editingCategory, editingDate, editingPriority],
|
[
|
||||||
|
editingNoteContent,
|
||||||
|
editingCategory,
|
||||||
|
editingDate,
|
||||||
|
editingTime,
|
||||||
|
editingPriority,
|
||||||
|
],
|
||||||
() => (didEditContent.value = true)
|
() => (didEditContent.value = true)
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -75,8 +82,8 @@ export function ObjectDetailModal(
|
|||||||
noteContent: editingNoteContent.value,
|
noteContent: editingNoteContent.value,
|
||||||
priority: editingPriority.value,
|
priority: editingPriority.value,
|
||||||
categoryName: editingCategory.value,
|
categoryName: editingCategory.value,
|
||||||
isoDate: editingDate.value,
|
date: editingDate.value,
|
||||||
isoTime: editingTime.value,
|
time: editingTime.value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,7 +115,7 @@ export function ObjectDetailModal(
|
|||||||
|
|
||||||
<div class="flex-column gap">
|
<div class="flex-column gap">
|
||||||
<label class="tile">
|
<label class="tile">
|
||||||
<span class="icon">label</span>
|
<span class="icon">{icons.objectTitle}</span>
|
||||||
<div>
|
<div>
|
||||||
<span>{translation.objectTitle}</span>
|
<span>{translation.objectTitle}</span>
|
||||||
{input}
|
{input}
|
||||||
@@ -118,7 +125,7 @@ export function ObjectDetailModal(
|
|||||||
<hr></hr>
|
<hr></hr>
|
||||||
|
|
||||||
<label class="tile">
|
<label class="tile">
|
||||||
<span class="icon">history</span>
|
<span class="icon">{icons.objectHistory}</span>
|
||||||
<div>
|
<div>
|
||||||
<span>{translation.objectVersion}</span>
|
<span>{translation.objectVersion}</span>
|
||||||
<select bind:value={selectedMessageObjectId}>
|
<select bind:value={selectedMessageObjectId}>
|
||||||
@@ -139,7 +146,7 @@ export function ObjectDetailModal(
|
|||||||
<hr></hr>
|
<hr></hr>
|
||||||
|
|
||||||
<label class="tile">
|
<label class="tile">
|
||||||
<span class="icon">sticky_note_2</span>
|
<span class="icon">{icons.noteContent}</span>
|
||||||
<div>
|
<div>
|
||||||
<span>{translation.note}</span>
|
<span>{translation.note}</span>
|
||||||
<textarea
|
<textarea
|
||||||
@@ -151,7 +158,7 @@ export function ObjectDetailModal(
|
|||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="tile">
|
<label class="tile">
|
||||||
<span class="icon">category</span>
|
<span class="icon">{icons.categoryName}</span>
|
||||||
<div>
|
<div>
|
||||||
<span>{translation.category}</span>
|
<span>{translation.category}</span>
|
||||||
<input
|
<input
|
||||||
@@ -162,7 +169,7 @@ export function ObjectDetailModal(
|
|||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="tile">
|
<label class="tile">
|
||||||
<span class="icon">priority_high</span>
|
<span class="icon">{icons.priority}</span>
|
||||||
<div>
|
<div>
|
||||||
<span>{translation.priority}</span>
|
<span>{translation.priority}</span>
|
||||||
<input
|
<input
|
||||||
@@ -176,7 +183,7 @@ export function ObjectDetailModal(
|
|||||||
<hr></hr>
|
<hr></hr>
|
||||||
|
|
||||||
<label class="tile">
|
<label class="tile">
|
||||||
<span class="icon">calendar_month</span>
|
<span class="icon">{icons.date}</span>
|
||||||
<div>
|
<div>
|
||||||
<span>{translation.date}</span>
|
<span>{translation.date}</span>
|
||||||
<input type="date" bind:value={editingDate}></input>
|
<input type="date" bind:value={editingDate}></input>
|
||||||
@@ -184,7 +191,7 @@ export function ObjectDetailModal(
|
|||||||
</label>
|
</label>
|
||||||
|
|
||||||
<label class="tile">
|
<label class="tile">
|
||||||
<span class="icon">schedule</span>
|
<span class="icon">{icons.time}</span>
|
||||||
<div>
|
<div>
|
||||||
<span>{translation.time}</span>
|
<span>{translation.time}</span>
|
||||||
<input type="time" bind:value={editingTime}></input>
|
<input type="time" bind:value={editingTime}></input>
|
||||||
|
|||||||
@@ -0,0 +1,62 @@
|
|||||||
|
import * as React from "bloatless-react";
|
||||||
|
|
||||||
|
import {
|
||||||
|
Chat,
|
||||||
|
MessageObject,
|
||||||
|
MessageObjectContent,
|
||||||
|
} from "../../Model/chatModel";
|
||||||
|
|
||||||
|
import { icons } from "../../icons";
|
||||||
|
|
||||||
|
export function ObjectEntryView(
|
||||||
|
chat: Chat,
|
||||||
|
messageObject: MessageObject,
|
||||||
|
selectedObject: React.State<MessageObject | undefined>,
|
||||||
|
isShowingObjectModal: React.State<boolean>
|
||||||
|
) {
|
||||||
|
const latest = chat.getMostRecentContent(messageObject);
|
||||||
|
|
||||||
|
function select() {
|
||||||
|
selectedObject.value = messageObject;
|
||||||
|
isShowingObjectModal.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fields = {
|
||||||
|
[icons.noteContent]: "---",
|
||||||
|
[icons.priority]: "---",
|
||||||
|
[icons.categoryName]: "---",
|
||||||
|
[icons.date]: "---",
|
||||||
|
[icons.time]: "---",
|
||||||
|
};
|
||||||
|
Object.entries(latest).forEach((entry) => {
|
||||||
|
let [key, value] = entry as [keyof MessageObjectContent, string];
|
||||||
|
if (!value) return;
|
||||||
|
|
||||||
|
const icon = icons[key];
|
||||||
|
if (!icon) return;
|
||||||
|
|
||||||
|
fields[icon] = value;
|
||||||
|
});
|
||||||
|
|
||||||
|
const fieldElements = Object.entries(fields).map((field) => {
|
||||||
|
const [icon, value] = field;
|
||||||
|
return (
|
||||||
|
<span class="flex-row control-gap align-center">
|
||||||
|
<span class="icon">{icon}</span>
|
||||||
|
{value}
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<button class="tile justify-start" on:click={select}>
|
||||||
|
<div>
|
||||||
|
<b>{chat.getObjectTitle(messageObject)}</b>
|
||||||
|
<hr></hr>
|
||||||
|
<span class="flex-column gap height-100 flex secondary ellipsis ">
|
||||||
|
{...fieldElements}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</button>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
export const icons = {
|
||||||
|
objectTitle: "label",
|
||||||
|
objectHistory: "history",
|
||||||
|
|
||||||
|
noteContent: "sticky_note_2",
|
||||||
|
categoryName: "category",
|
||||||
|
priority: "priority_high",
|
||||||
|
date: "calendar_month",
|
||||||
|
time: "schedule",
|
||||||
|
}
|
||||||
+10
-10
@@ -1,5 +1,5 @@
|
|||||||
[unread] {
|
[unread] {
|
||||||
border-left: 10px solid var(--text-warning);
|
border-left: 10px solid var(--text-warn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TOOLS */
|
/* TOOLS */
|
||||||
@@ -22,18 +22,18 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
[showingchattools] :is(.thread-view, .chat-object-view) {
|
#message-tab:has([showingchattools]) :is(.thread-view, .chat-object-view) {
|
||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
|
|
||||||
padding: 0px;
|
padding: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
[showingchattools] header {
|
#message-tab:has([showingchattools]) header {
|
||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
|
|
||||||
[showingchattools] .chat-object-view {
|
#message-tab:has([showingchattools]) .chat-object-view {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
top: var(--header-height);
|
top: var(--header-height);
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
border-bottom: 1px solid var(--border);
|
border-bottom: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
|
|
||||||
[showingchattools] .thread-view {
|
#message-tab:has([showingchattools]) .thread-view {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
height: var(--thread-view-height-with-tools);
|
height: var(--thread-view-height-with-tools);
|
||||||
@@ -54,22 +54,22 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 640px) and (max-width: 1400px) {
|
@media (min-width: 640px) and (max-width: 1400px) {
|
||||||
main.split:has([showingchattools]) {
|
main.split:has(#message-tab [showingchattools]) {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
main.split:has([showingchattools]) #settings-tab {
|
main.split:has(#message-tab [showingchattools]) #settings-tab {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 640px) {
|
@media (min-width: 640px) {
|
||||||
[showingchattools] :is(.thread-view, .chat-object-view) {
|
#message-tab:has([showingchattools]) :is(.thread-view, .chat-object-view) {
|
||||||
top: var(--header-height);
|
top: var(--header-height);
|
||||||
bottom: var(--footer-top-line);
|
bottom: var(--footer-top-line);
|
||||||
}
|
}
|
||||||
|
|
||||||
[showingchattools] .chat-object-view {
|
#message-tab:has([showingchattools]) .chat-object-view {
|
||||||
left: 0px;
|
left: 0px;
|
||||||
right: var(--thread-view-width-with-tools);
|
right: var(--thread-view-width-with-tools);
|
||||||
|
|
||||||
@@ -77,7 +77,7 @@
|
|||||||
border-right: 1px solid var(--border);
|
border-right: 1px solid var(--border);
|
||||||
}
|
}
|
||||||
|
|
||||||
[showingchattools] .thread-view {
|
#message-tab:has([showingchattools]) .thread-view {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
||||||
left: unset;
|
left: unset;
|
||||||
|
|||||||
Reference in New Issue
Block a user