Skip to content
Snippets Groups Projects
Verified Commit 083f4ba2 authored by Volker Schukai's avatar Volker Schukai :alien:
Browse files

fix: update test and optimize tree-menu

parent 16739986
No related branches found
No related tags found
No related merge requests found
......@@ -6,6 +6,6 @@
"checkJs": false,
"moduleResolution": "node"
},
"include": ["source/**/*"]
"include": ["source/**/*"],
"exclude": ["node_modules"]
}
{
"name": "@schukai/monster",
"version": "3.111.0",
"version": "3.112.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@schukai/monster",
"version": "3.111.0",
"version": "3.112.0",
"license": "AGPL 3.0",
"dependencies": {
"@floating-ui/dom": "^1.6.13",
......
......@@ -113,9 +113,13 @@ class MonthCalendar extends CustomElement {
* @property {boolean} disabled=false Disabled state
*/
get defaults() {
const startDate = new Date();
const startDateString = startDate.getFullYear() + "-" + ("00" + (startDate.getMonth() + 1)).slice(-2) + "-" + ("00" + startDate.getDate()).slice(-2);
const startDateString =
startDate.getFullYear() +
"-" +
("00" + (startDate.getMonth() + 1)).slice(-2) +
"-" +
("00" + startDate.getDate()).slice(-2);
return Object.assign({}, super.defaults, {
templates: {
......@@ -681,11 +685,13 @@ function initEventHandler() {
.querySelectorAll("[data-monster-role='day-cell']")
.forEach((element) => {
element.addEventListener("click", (event) => {
console.log(event.relatedTarget, "event1");
console.log(event.composedPath(), "event");
console.log(event.relatedTarget,'event1')
console.log(event.composedPath(),'event')
const hoveredElement = this.shadowRoot.elementFromPoint(event.clientX, event.clientY);
const hoveredElement = this.shadowRoot.elementFromPoint(
event.clientX,
event.clientY,
);
if (hoveredElement instanceof AppointmentSegment) {
return;
}
......@@ -714,7 +720,6 @@ function initEventHandler() {
//const appointments = getAppointmentsPerDay() || [];
popper.style.width = element.getBoundingClientRect().width + "px";
popper.style.zIndex = 1000;
......
This diff is collapsed.
......@@ -12,9 +12,11 @@ import {isArray} from "../../../types/is.mjs";
function isSameDay(date1, date2) {
const d1 = new Date(date1);
const d2 = new Date(date2);
return d1.getFullYear() === d2.getFullYear() &&
return (
d1.getFullYear() === d2.getFullYear() &&
d1.getMonth() === d2.getMonth() &&
d1.getDate() === d2.getDate();
d1.getDate() === d2.getDate()
);
}
class AppointmentCollection {
......@@ -37,45 +39,49 @@ class AppointmentCollection {
if (isNaN(start.getTime()) || isNaN(end.getTime())) {
throw new Error("Invalid date range");
}
return this.appointments.filter(app =>
app.endDate >= start && app.startDate <= end
return this.appointments.filter(
(app) => app.endDate >= start && app.startDate <= end,
);
}
// Get appointments that start on a specific day
getAppointmentsStartingOn(date) {
return this.appointments.filter(app => isSameDay(app.startDate, date));
return this.appointments.filter((app) => isSameDay(app.startDate, date));
}
// Get appointments that end on a specific day
getAppointmentsEndingOn(date) {
return this.appointments.filter(app => isSameDay(app.endDate, date));
return this.appointments.filter((app) => isSameDay(app.endDate, date));
}
// Get appointments active on a specific day (the day falls between startDate and endDate, inclusive)
getAppointmentsForDay(date) {
const d = new Date(date);
return this.appointments.filter(app =>
app.startDate <= d && app.endDate >= d
return this.appointments.filter(
(app) => app.startDate <= d && app.endDate >= d,
);
}
// Get appointments where the specified date is strictly between the start and end dates
getAppointmentsWithDateAsMiddleDay(date) {
const d = new Date(date);
return this.appointments.filter(app =>
app.startDate < d && app.endDate > d && !isSameDay(app.startDate, d) && !isSameDay(app.endDate, d)
return this.appointments.filter(
(app) =>
app.startDate < d &&
app.endDate > d &&
!isSameDay(app.startDate, d) &&
!isSameDay(app.endDate, d),
);
}
// Get appointments filtered by type (e.g., all milestones)
getAppointmentsByType(type) {
return this.appointments.filter(app => app.type === type);
return this.appointments.filter((app) => app.type === type);
}
// Export the entire collection as JSON
toJSON() {
return this.appointments.map(app => app.toJSON());
return this.appointments.map((app) => app.toJSON());
}
/**
......@@ -97,7 +103,7 @@ class AppointmentCollection {
if (appointmentOrId instanceof TimelineItem) {
appointment = appointmentOrId;
} else {
appointment = this.appointments.find(app => app.id === appointmentOrId);
appointment = this.appointments.find((app) => app.id === appointmentOrId);
if (!appointment) {
throw new Error("Appointment not found");
}
......@@ -122,7 +128,7 @@ class AppointmentCollection {
description: appointment.description,
userIds: appointment.userIds,
startDate: currentStart.toISOString(),
endDate: currentEnd.toISOString()
endDate: currentEnd.toISOString(),
};
slices.push(slice);
......@@ -144,7 +150,7 @@ try {
startDate: "2025-03-05T09:00:00",
endDate: "2025-03-05T10:00:00",
description: "Weekly team meeting",
userIds: ["user1", "user2"]
userIds: ["user1", "user2"],
});
const appointment2 = new TimelineItem({
......@@ -153,7 +159,7 @@ try {
startDate: "2025-03-06T08:00:00",
endDate: "2025-03-06T12:00:00",
description: "Kickoff for the new project",
userIds: "user3" // single user id; will be converted to an array
userIds: "user3", // single user id; will be converted to an array
});
// An appointment spanning over 30 days
......@@ -163,7 +169,7 @@ try {
startDate: "2025-04-01T09:00:00",
endDate: "2025-05-15T17:00:00",
description: "Project spanning multiple weeks",
userIds: ["user4"]
userIds: ["user4"],
});
// Create an appointment collection and add appointments
......@@ -173,33 +179,40 @@ try {
collection.addAppointment(appointment3);
console.log("Appointments on 2025-03-05:");
collection.getAppointmentsForDay("2025-03-05").forEach(app => console.log(app.toString()));
collection
.getAppointmentsForDay("2025-03-05")
.forEach((app) => console.log(app.toString()));
console.log("\nAppointments in range 2025-03-05 to 2025-03-06:");
collection.getAppointmentsInRange("2025-03-05T00:00:00", "2025-03-06T23:59:59")
.forEach(app => console.log(app.toString()));
collection
.getAppointmentsInRange("2025-03-05T00:00:00", "2025-03-06T23:59:59")
.forEach((app) => console.log(app.toString()));
console.log("\nAll milestones:");
collection.getAppointmentsByType(AppointmentType.MILESTONE)
.forEach(app => console.log(app.toString()));
collection
.getAppointmentsByType(AppointmentType.MILESTONE)
.forEach((app) => console.log(app.toString()));
// Split appointment3 into weekly slices (7-day slices)
console.log("\nWeekly slices for Long Term Project:");
const weeklySlices = collection.splitAppointment(appointment3, 7);
weeklySlices.forEach(slice => {
console.log(`Slice ${slice.sliceIndex}: ${slice.startDate} to ${slice.endDate}`);
weeklySlices.forEach((slice) => {
console.log(
`Slice ${slice.sliceIndex}: ${slice.startDate} to ${slice.endDate}`,
);
});
// Split appointment3 into 14-day slices
console.log("\n14-day slices for Long Term Project:");
const biweeklySlices = collection.splitAppointment(appointment3, 14);
biweeklySlices.forEach(slice => {
console.log(`Slice ${slice.sliceIndex}: ${slice.startDate} to ${slice.endDate}`);
biweeklySlices.forEach((slice) => {
console.log(
`Slice ${slice.sliceIndex}: ${slice.startDate} to ${slice.endDate}`,
);
});
console.log("\nJSON Export of the collection:");
console.log(JSON.stringify(collection.toJSON(), null, 2));
} catch (error) {
console.error("Error:", error.message);
}
......@@ -30,7 +30,7 @@ const AppointmentType = {
VACATION: "vacation",
SICKDAY: "sickday",
OOO: "ooo",
CUSTOM: "custom"
CUSTOM: "custom",
};
class Item extends BaseWithOptions {
......@@ -47,7 +47,15 @@ class Item extends BaseWithOptions {
* @param {string|string[]} [params.userIds=[]] - One or more user IDs associated with this item.
* @throws {Error} If type is invalid or dates are not valid or startDate is after endDate.
*/
constructor({ id, title, type, startDate, endDate, description = "", userIds = [] }) {
constructor({
id,
title,
type,
startDate,
endDate,
description = "",
userIds = [],
}) {
// Validate item type
if (!Object.values(AppointmentType).includes(type)) {
throw new Error(`Invalid appointment type: ${type}`);
......@@ -142,7 +150,7 @@ class Item extends BaseWithOptions {
description: this.description,
userIds: this.userIds,
startDate: this.startDate.toISOString(),
endDate: this.endDate.toISOString()
endDate: this.endDate.toISOString(),
};
}
......@@ -167,7 +175,7 @@ class Item extends BaseWithOptions {
startDate: json.startDate,
endDate: json.endDate,
description: json.description,
userIds: json.userIds
userIds: json.userIds,
});
}
......
......@@ -70,6 +70,12 @@ const controlElementSymbol = Symbol("controlElement");
*/
const openEntryEventHandlerSymbol = Symbol("openEntryEventHandler");
/**
* @private
* @type {symbol}
*/
const firstRunDoneSymbol = Symbol("firstRunDone");
/**
* TreeMenu
*
......@@ -161,23 +167,16 @@ class TreeMenu extends CustomElement {
});
}
/**
*
*/
[initMethodSymbol]() {
super[initMethodSymbol]();
}
/**
* @return {void}
*/
[assembleMethodSymbol]() {
super[assembleMethodSymbol]();
queueMicrotask(() => {
initControlReferences.call(this);
initEventHandler.call(this);
initObserver.call(this);
queueMicrotask(() => {
copyIconMap.call(this);
});
}
......@@ -230,15 +229,15 @@ class TreeMenu extends CustomElement {
currentNode.click();
let intend = parseInt(currentNode.getAttribute(ATTRIBUTE_INTEND));
let intend = Number.parseInt(currentNode.getAttribute(ATTRIBUTE_INTEND));
if (intend > 0) {
const refSet = new Set();
let ref = currentNode.previousElementSibling;
while (ref && ref.hasAttribute(ATTRIBUTE_INTEND)) {
const i = parseInt(ref.getAttribute(ATTRIBUTE_INTEND));
while (ref?.hasAttribute(ATTRIBUTE_INTEND)) {
const i = Number.parseInt(ref.getAttribute(ATTRIBUTE_INTEND));
if (isNaN(i)) {
if (Number.isNaN(i)) {
break;
}
......@@ -342,10 +341,10 @@ function initEventHandler() {
let intend = currentEntry.intend;
if (intend > 0) {
let ref = container.previousElementSibling;
while (ref && ref.hasAttribute(ATTRIBUTE_INTEND)) {
const i = parseInt(ref.getAttribute(ATTRIBUTE_INTEND));
while (ref?.hasAttribute(ATTRIBUTE_INTEND)) {
const i = Number.parseInt(ref.getAttribute(ATTRIBUTE_INTEND));
if (isNaN(i)) {
if (Number.isNaN(i)) {
break;
}
......@@ -393,10 +392,10 @@ function initEventHandler() {
return a >= b;
};
while (ref && ref.hasAttribute(ATTRIBUTE_INTEND)) {
while (ref?.hasAttribute(ATTRIBUTE_INTEND)) {
const refIntend = ref.getAttribute(ATTRIBUTE_INTEND);
if (!cmp(parseInt(refIntend), childIntend)) {
if (!cmp(Number.parseInt(refIntend), childIntend)) {
if (refIntend === intend) {
break;
}
......@@ -456,9 +455,26 @@ function importEntries() {
const selector = mappingOptions?.["selector"];
let filteredData;
if (this[firstRunDoneSymbol] !== true) {
filteredData = data.filter(
(entry) =>
!entry[parentKey] ||
entry[parentKey] === null ||
entry[parentKey] === undefined ||
entry[parentKey] === 0,
);
setTimeout(() => {
this[firstRunDoneSymbol] = true;
importEntries.call(this);
}, 0);
} else {
filteredData = data;
}
let nodes;
try {
nodes = buildTree(data, selector, id, parentKey, {
nodes = buildTree(filteredData, selector, id, parentKey, {
filter,
rootReferences,
});
......
......@@ -31,7 +31,7 @@ export * from "./components/content/viewer.mjs";
export * from "./components/content/copy.mjs";
export * from "./components/content/camera.mjs";
export * from "./components/time/timeline/segment.mjs";
export * from "./components/time/appointment.mjs";
export * from "./components/time/timeline/item.mjs";
export * from "./components/time/month-calendar.mjs";
export * from "./components/form/message-state-button.mjs";
export * from "./components/form/password.mjs";
......
......@@ -156,7 +156,7 @@ function getMonsterVersion() {
}
/** don't touch, replaced by make with package.json version */
monsterVersion = new Version("3.111.0");
monsterVersion = new Version("3.112.0");
return monsterVersion;
}
......@@ -7,7 +7,7 @@ describe('Monster', function () {
let monsterVersion
/** don´t touch, replaced by make with package.json version */
monsterVersion = new Version("3.111.0")
monsterVersion = new Version("3.112.0")
let m = getMonsterVersion();
......
......@@ -9,8 +9,8 @@
</head>
<body>
<div id="headline" style="display: flex;align-items: center;justify-content: center;flex-direction: column;">
<h1 style='margin-bottom: 0.1em;'>Monster 3.111.0</h1>
<div id="lastupdate" style='font-size:0.7em'>last update Mi 5. Mär 13:29:26 CET 2025</div>
<h1 style='margin-bottom: 0.1em;'>Monster 3.112.0</h1>
<div id="lastupdate" style='font-size:0.7em'>last update Sa 8. Mär 00:49:17 CET 2025</div>
</div>
<div id="mocha-errors"
style="color: red;font-weight: bold;display: flex;align-items: center;justify-content: center;flex-direction: column;margin:20px;"></div>
......
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment