add navigation for calendar

This commit is contained in:
marlon-erler
2024-07-18 17:42:41 +02:00
parent 4e068a8666
commit 788159ffff
10 changed files with 217 additions and 49 deletions
+41 -2
View File
@@ -43,14 +43,12 @@
left: unset; left: unset;
width: var(--split-thread-width); width: var(--split-thread-width);
} }
@media (max-width: 1300px) {
main:has([showingobjects][chatopen]) { main:has([showingobjects][chatopen]) {
display: flex; display: flex;
} }
main:has([showingobjects][chatopen]) #settings-tab { main:has([showingobjects][chatopen]) #settings-tab {
display: none; display: none;
} }
}
@media (max-width: 640px) { @media (max-width: 640px) {
[showingobjects][chatvisible][chatopen] .chat-object-view { [showingobjects][chatvisible][chatopen] .chat-object-view {
width: 100%; width: 100%;
@@ -69,3 +67,44 @@
width: 100%; width: 100%;
} }
} }
:root {
--day-view-width: 400px;
}
.calendar-wrapper {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
.calendar-wrapper .month-grid {
border-bottom: 1px solid var(--border);
}
.calendar-wrapper > * {
width: 100%;
height: 100%;
flex: 1;
}
@media (min-width: 900px) {
.calendar-wrapper:not([chatvisible] *) {
flex-direction: row;
}
.calendar-wrapper:not([chatvisible] *) .month-grid {
border-bottom: none;
border-right: 1px solid var(--border);
}
.calendar-wrapper:not([chatvisible] *) .day-view {
max-width: var(--day-view-width);
}
}
@media (min-width: 1200px) {
.calendar-wrapper {
flex-direction: row;
}
.calendar-wrapper .month-grid {
border-bottom: none;
border-right: 1px solid var(--border);
}
.calendar-wrapper .day-view {
max-width: var(--day-view-width);
}
}
+42 -16
View File
@@ -1007,7 +1007,6 @@
this.objects.set(messageObject.id, messageObject); this.objects.set(messageObject.id, messageObject);
} }
const latest = this.getMostRecentContent(messageObject); const latest = this.getMostRecentContent(messageObject);
if (!latest) return;
if (latest.categoryName) usedObjectCategories.add(latest.categoryName); if (latest.categoryName) usedObjectCategories.add(latest.categoryName);
if (latest.status) usedObjectStatuses.add(latest.status); if (latest.status) usedObjectStatuses.add(latest.status);
}; };
@@ -1302,6 +1301,7 @@
var isEncryptionAvailable = window.crypto.subtle != void 0; var isEncryptionAvailable = window.crypto.subtle != void 0;
var senderName = restoreState("sender-name", ""); var senderName = restoreState("sender-name", "");
var pageZoom = restoreState("page-zoom", 100); var pageZoom = restoreState("page-zoom", 100);
var dayInCalendar = restoreState("calendar-day", (/* @__PURE__ */ new Date()).toISOString().split("T")[0]);
pageZoom.subscribe(() => { pageZoom.subscribe(() => {
document.body.style.zoom = `${pageZoom.value}%`; document.body.style.zoom = `${pageZoom.value}%`;
document.body.style.webkitTextSizeAdjust = `${pageZoom.value}%`; document.body.style.webkitTextSizeAdjust = `${pageZoom.value}%`;
@@ -1652,7 +1652,6 @@
); );
messageObjects.handleAddition((messageObject) => { messageObjects.handleAddition((messageObject) => {
const latest = chat.getMostRecentContent(messageObject); const latest = chat.getMostRecentContent(messageObject);
if (!latest) return;
if (!latest.categoryName) return; if (!latest.categoryName) return;
const categoryName = latest.categoryName; const categoryName = latest.categoryName;
if (!boards.value.has(categoryName)) { if (!boards.value.has(categoryName)) {
@@ -1753,7 +1752,6 @@
const notes = new ListState(); const notes = new ListState();
messageObjects.handleAddition((messageObject) => { messageObjects.handleAddition((messageObject) => {
const latest = chat.getMostRecentContent(messageObject); const latest = chat.getMostRecentContent(messageObject);
if (!latest) return;
if (!latest.noteContent) return; if (!latest.noteContent) return;
notes.add(messageObject); notes.add(messageObject);
messageObjects.handleRemoval( messageObjects.handleRemoval(
@@ -1992,7 +1990,6 @@
function rename() { function rename() {
status.items.forEach((messageObject) => { status.items.forEach((messageObject) => {
const latest = chat.getMostRecentContent(messageObject); const latest = chat.getMostRecentContent(messageObject);
if (!latest) return;
latest.status = editingStatus.value; latest.status = editingStatus.value;
chat.addObject(messageObject); chat.addObject(messageObject);
}); });
@@ -2066,20 +2063,49 @@
); );
} }
// src/Views/Objects/dayView.tsx
function DayView(chat, messageObjects, selectedObject, isShowingObjectModal) {
const objectsForDayView = new ListState();
function processObject(messageObject) {
const latest = chat.getMostRecentContent(messageObject);
if (!latest.date || latest.date != dayInCalendar.value) return;
objectsForDayView.add(messageObject);
messageObjects.handleRemoval(messageObject, () => {
objectsForDayView.remove(messageObject);
});
}
messageObjects.handleAddition(processObject);
dayInCalendar.subscribeSilent(() => {
objectsForDayView.clear();
chat.objects.value.forEach(processObject);
});
const objectConverter = (messageObject) => {
const latest = chat.getMostRecentContent(messageObject);
const timeString = latest.time ?? "00:00";
const [hour, minute] = timeString.split(":");
const hourInMinutes = parseInt(hour) * 60;
const minutesTotal = parseInt(minute) + hourInMinutes;
const view = ObjectEntryView(
chat,
messageObject,
selectedObject,
isShowingObjectModal
);
view.style.order = minutesTotal;
return view;
};
return /* @__PURE__ */ createElement(
"div",
{
class: "day-view padding flex-column gap",
"children:prepend": [objectsForDayView, objectConverter]
}
);
}
// src/Views/Objects/calendarView.tsx // src/Views/Objects/calendarView.tsx
function CalendarView(chat, messageObjects, selectedObject, isShowingObjectModal) { function CalendarView(chat, messageObjects, selectedObject, isShowingObjectModal) {
const notes = new ListState(); return /* @__PURE__ */ createElement("div", { class: "calendar-wrapper" }, /* @__PURE__ */ createElement("div", { class: "month-grid" }, /* @__PURE__ */ createElement("input", { type: "date", "bind:value": dayInCalendar })), DayView(chat, messageObjects, selectedObject, isShowingObjectModal));
messageObjects.handleAddition((messageObject) => {
const latest = chat.getMostRecentContent(messageObject);
if (!latest) return;
if (!latest.date) return;
notes.add(messageObject);
messageObjects.handleRemoval(
messageObject,
() => notes.remove(messageObject)
);
});
return /* @__PURE__ */ createElement("div", { class: "width-100 height-100 scroll-v padding" }, ObjectGridView(chat, notes, selectedObject, isShowingObjectModal));
} }
// src/Views/Objects/objectPane.tsx // src/Views/Objects/objectPane.tsx
-1
View File
@@ -381,7 +381,6 @@ export class Chat {
} }
const latest = this.getMostRecentContent(messageObject); const latest = this.getMostRecentContent(messageObject);
if (!latest) return;
if (latest.categoryName) usedObjectCategories.add(latest.categoryName); if (latest.categoryName) usedObjectCategories.add(latest.categoryName);
if (latest.status) usedObjectStatuses.add(latest.status); if (latest.status) usedObjectStatuses.add(latest.status);
}; };
+2
View File
@@ -151,6 +151,8 @@ export const isPresentingSettingsModal = new React.State(false);
export const isEncryptionAvailable = window.crypto.subtle != undefined; export const isEncryptionAvailable = window.crypto.subtle != undefined;
export const senderName = React.restoreState("sender-name", ""); export const senderName = React.restoreState("sender-name", "");
export const pageZoom = React.restoreState("page-zoom", 100); export const pageZoom = React.restoreState("page-zoom", 100);
export const dayInCalendar = React.restoreState("calendar-day", new Date().toISOString().split("T")[0])
pageZoom.subscribe(() => { pageZoom.subscribe(() => {
document.body.style.zoom = `${pageZoom.value}%`; document.body.style.zoom = `${pageZoom.value}%`;
document.body.style.webkitTextSizeAdjust = `${pageZoom.value}%`; document.body.style.webkitTextSizeAdjust = `${pageZoom.value}%`;
+8 -15
View File
@@ -3,6 +3,8 @@ import * as React from "bloatless-react";
import { Chat, MessageObject } from "../../Model/chatModel"; import { Chat, MessageObject } from "../../Model/chatModel";
import { ObjectGridView } from "./objectGridView"; import { ObjectGridView } from "./objectGridView";
import { DayView } from "./dayView";
import { dayInCalendar } from "../../Model/model";
export function CalendarView( export function CalendarView(
chat: Chat, chat: Chat,
@@ -10,19 +12,10 @@ export function CalendarView(
selectedObject: React.State<MessageObject | undefined>, selectedObject: React.State<MessageObject | undefined>,
isShowingObjectModal: React.State<boolean> isShowingObjectModal: React.State<boolean>
) { ) {
const notes = new React.ListState<MessageObject>(); return <div class="calendar-wrapper">
messageObjects.handleAddition((messageObject) => { <div class="month-grid">
const latest = chat.getMostRecentContent(messageObject); <input type="date" bind:value={dayInCalendar}></input>
if (!latest) return; </div>
if (!latest.date) return; {DayView(chat, messageObjects, selectedObject, isShowingObjectModal)}
</div>
notes.add(messageObject);
messageObjects.handleRemoval(messageObject, () =>
notes.remove(messageObject)
);
});
return <div class="width-100 height-100 scroll-v padding">
{ObjectGridView(chat, notes, selectedObject, isShowingObjectModal)}
</div>;
} }
+59
View File
@@ -0,0 +1,59 @@
import * as React from "bloatless-react";
import { Chat, MessageObject } from "../../Model/chatModel";
import { ObjectEntryView } from "./objectEntryView";
import { dayInCalendar } from "../../Model/model";
export function DayView(
chat: Chat,
messageObjects:
| React.ListState<MessageObject>
| React.MapState<MessageObject>,
selectedObject: React.State<MessageObject | undefined>,
isShowingObjectModal: React.State<boolean>
) {
const objectsForDayView = new React.ListState<MessageObject>();
function processObject(messageObject: MessageObject) {
const latest = chat.getMostRecentContent(messageObject);
if (!latest.date || latest.date != dayInCalendar.value) return;
objectsForDayView.add(messageObject);
messageObjects.handleRemoval(messageObject, () => {
objectsForDayView.remove(messageObject);
})
}
messageObjects.handleAddition(processObject);
dayInCalendar.subscribeSilent(() => {
objectsForDayView.clear();
chat.objects.value.forEach(processObject);
})
const objectConverter: React.StateItemConverter<MessageObject> = (
messageObject
) => {
const latest = chat.getMostRecentContent(messageObject);
const timeString = latest.time ?? "00:00";
const [hour, minute] = timeString.split(":");
const hourInMinutes = parseInt(hour) * 60;
const minutesTotal = parseInt(minute) + hourInMinutes;
const view = ObjectEntryView(
chat,
messageObject,
selectedObject,
isShowingObjectModal
);
view.style.order = minutesTotal;
return view;
};
return (
<div
class="day-view padding flex-column gap"
children:prepend={[objectsForDayView, objectConverter]}
></div>
);
}
-1
View File
@@ -30,7 +30,6 @@ export function KanbanView(
messageObjects.handleAddition((messageObject) => { messageObjects.handleAddition((messageObject) => {
const latest = chat.getMostRecentContent(messageObject); const latest = chat.getMostRecentContent(messageObject);
if (!latest) return;
if (!latest.categoryName) return; if (!latest.categoryName) return;
const categoryName = latest.categoryName!; const categoryName = latest.categoryName!;
-1
View File
@@ -13,7 +13,6 @@ export function NoteObjectsView(
const notes = new React.ListState<MessageObject>(); const notes = new React.ListState<MessageObject>();
messageObjects.handleAddition((messageObject) => { messageObjects.handleAddition((messageObject) => {
const latest = chat.getMostRecentContent(messageObject); const latest = chat.getMostRecentContent(messageObject);
if (!latest) return;
if (!latest.noteContent) return; if (!latest.noteContent) return;
notes.add(messageObject); notes.add(messageObject);
-1
View File
@@ -145,7 +145,6 @@ function StatusHeaderView(chat: Chat, status: StatusData) {
function rename() { function rename() {
status.items.forEach((messageObject) => { status.items.forEach((messageObject) => {
const latest = chat.getMostRecentContent(messageObject); const latest = chat.getMostRecentContent(messageObject);
if (!latest) return;
latest.status = editingStatus.value; latest.status = editingStatus.value;
chat.addObject(messageObject); chat.addObject(messageObject);
+55 -2
View File
@@ -60,7 +60,7 @@
width: var(--split-thread-width); width: var(--split-thread-width);
} }
@media (max-width: 1300px) { /* hide settings tab */
main:has([showingobjects][chatopen]) { main:has([showingobjects][chatopen]) {
display: flex; display: flex;
} }
@@ -68,7 +68,6 @@
main:has([showingobjects][chatopen]) #settings-tab { main:has([showingobjects][chatopen]) #settings-tab {
display: none; display: none;
} }
}
@media (max-width: 640px) { @media (max-width: 640px) {
[showingobjects][chatvisible][chatopen] .chat-object-view { [showingobjects][chatvisible][chatopen] .chat-object-view {
@@ -93,3 +92,57 @@
width: 100%; width: 100%;
} }
} }
/* calendar */
:root {
--day-view-width: 400px;
}
.calendar-wrapper {
display: flex;
flex-direction: column;
width: 100%;
height: 100%;
}
.calendar-wrapper .month-grid {
border-bottom: 1px solid var(--border);
}
.calendar-wrapper > * {
width: 100%;
height: 100%;
flex: 1;
}
@media (min-width: 900px) {
.calendar-wrapper:not([chatvisible] *) {
flex-direction: row;
}
.calendar-wrapper:not([chatvisible] *) .month-grid {
border-bottom: none;
border-right: 1px solid var(--border);
}
.calendar-wrapper:not([chatvisible] *) .day-view {
max-width: var(--day-view-width);
}
}
@media (min-width: 1200px) {
.calendar-wrapper {
flex-direction: row;
}
.calendar-wrapper .month-grid {
border-bottom: none;
border-right: 1px solid var(--border);
}
.calendar-wrapper .day-view {
max-width: var(--day-view-width);
}
}