@schukai/monster 3.112.0 → 3.112.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/package.json +1 -1
- package/source/components/layout/style/panel.pcss +0 -7
- package/source/components/layout/stylesheet/panel.mjs +7 -14
- package/source/components/navigation/style/table-of-content.pcss +3 -2
- package/source/components/navigation/stylesheet/table-of-content.mjs +7 -14
- package/source/components/navigation/table-of-content.mjs +25 -9
- package/source/components/time/month-calendar.mjs +17 -12
- package/source/components/time/stylesheet/month-calendar.mjs +13 -6
- package/source/components/time/timeline/collection.mjs +200 -187
- package/source/components/time/timeline/item.mjs +159 -151
- package/source/components/tree-menu/tree-menu.mjs +36 -20
- package/source/monster.mjs +1 -1
- package/source/types/version.mjs +1 -1
- package/test/cases/monster.mjs +1 -1
- package/test/web/test.html +2 -2
- package/test/web/tests.js +7 -4
@@ -12,173 +12,181 @@
|
|
12
12
|
|
13
13
|
import { ID } from "../../../types/id.mjs";
|
14
14
|
import { isArray } from "../../../types/is.mjs";
|
15
|
-
import {BaseWithOptions} from "../../../types/basewithoptions.mjs";
|
15
|
+
import { BaseWithOptions } from "../../../types/basewithoptions.mjs";
|
16
16
|
|
17
17
|
const AppointmentType = {
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
18
|
+
TODO: "todo",
|
19
|
+
TASK: "task",
|
20
|
+
MILESTONE: "milestone",
|
21
|
+
EVENT: "event",
|
22
|
+
REMINDER: "reminder",
|
23
|
+
MEETING: "meeting",
|
24
|
+
CALL: "call",
|
25
|
+
APPOINTMENT: "appointment",
|
26
|
+
DEADLINE: "deadline",
|
27
|
+
BIRTHDAY: "birthday",
|
28
|
+
ANNIVERSARY: "anniversary",
|
29
|
+
HOLIDAY: "holiday",
|
30
|
+
VACATION: "vacation",
|
31
|
+
SICKDAY: "sickday",
|
32
|
+
OOO: "ooo",
|
33
|
+
CUSTOM: "custom",
|
34
34
|
};
|
35
35
|
|
36
36
|
class Item extends BaseWithOptions {
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
37
|
+
/**
|
38
|
+
* Creates a new Item.
|
39
|
+
*
|
40
|
+
* @param {Object} params - Parameters for creating the item.
|
41
|
+
* @param {string} [params.id] - Optional ID. If not provided, one will be generated.
|
42
|
+
* @param {string} params.title - Title of the item.
|
43
|
+
* @param {string} params.type - Type of the item (must be one of AppointmentType values).
|
44
|
+
* @param {string|Date} params.startDate - Start date/time.
|
45
|
+
* @param {string|Date} params.endDate - End date/time.
|
46
|
+
* @param {string} [params.description=""] - Optional description.
|
47
|
+
* @param {string|string[]} [params.userIds=[]] - One or more user IDs associated with this item.
|
48
|
+
* @throws {Error} If type is invalid or dates are not valid or startDate is after endDate.
|
49
|
+
*/
|
50
|
+
constructor({
|
51
|
+
id,
|
52
|
+
title,
|
53
|
+
type,
|
54
|
+
startDate,
|
55
|
+
endDate,
|
56
|
+
description = "",
|
57
|
+
userIds = [],
|
58
|
+
}) {
|
59
|
+
// Validate item type
|
60
|
+
if (!Object.values(AppointmentType).includes(type)) {
|
61
|
+
throw new Error(`Invalid appointment type: ${type}`);
|
62
|
+
}
|
55
63
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
64
|
+
// Convert startDate and endDate to Date objects
|
65
|
+
this.startDate = new Date(startDate);
|
66
|
+
this.endDate = new Date(endDate);
|
67
|
+
if (isNaN(this.startDate.getTime()) || isNaN(this.endDate.getTime())) {
|
68
|
+
throw new Error("Invalid start or end date");
|
69
|
+
}
|
70
|
+
// Ensure startDate is not after endDate
|
71
|
+
if (this.startDate > this.endDate) {
|
72
|
+
throw new Error("Start date cannot be after end date");
|
73
|
+
}
|
66
74
|
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
75
|
+
// Initialize fields
|
76
|
+
this.id = id || new ID().toString();
|
77
|
+
this.title = title || "new appointment";
|
78
|
+
this.type = type || AppointmentType.CUSTOM;
|
79
|
+
this.description = description || "";
|
72
80
|
|
73
|
-
|
74
|
-
|
75
|
-
|
81
|
+
// Ensure userIds is stored as an array
|
82
|
+
this.userIds = isArray(userIds) ? userIds : [userIds];
|
83
|
+
}
|
76
84
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
85
|
+
/**
|
86
|
+
* Calculates the duration of the item in days.
|
87
|
+
*
|
88
|
+
* @returns {number} Duration in days.
|
89
|
+
*/
|
90
|
+
getDurationInDays() {
|
91
|
+
const msPerDay = 1000 * 60 * 60 * 24;
|
92
|
+
return Math.ceil((this.endDate - this.startDate) / msPerDay);
|
93
|
+
}
|
86
94
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
95
|
+
/**
|
96
|
+
* Calculates the duration of the item in hours.
|
97
|
+
*
|
98
|
+
* @returns {number} Duration in hours.
|
99
|
+
*/
|
100
|
+
getDurationInHours() {
|
101
|
+
const msPerHour = 1000 * 60 * 60;
|
102
|
+
return Math.ceil((this.endDate - this.startDate) / msPerHour);
|
103
|
+
}
|
96
104
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
105
|
+
/**
|
106
|
+
* Calculates the duration of the item in minutes.
|
107
|
+
*
|
108
|
+
* @returns {number} Duration in minutes.
|
109
|
+
*/
|
110
|
+
getDurationInMinutes() {
|
111
|
+
const msPerMinute = 1000 * 60;
|
112
|
+
return Math.ceil((this.endDate - this.startDate) / msPerMinute);
|
113
|
+
}
|
106
114
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
115
|
+
/**
|
116
|
+
* Calculates the duration of the item in seconds.
|
117
|
+
*
|
118
|
+
* @returns {number} Duration in seconds.
|
119
|
+
*/
|
120
|
+
getDurationInSeconds() {
|
121
|
+
const msPerSecond = 1000;
|
122
|
+
return Math.ceil((this.endDate - this.startDate) / msPerSecond);
|
123
|
+
}
|
116
124
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
125
|
+
/**
|
126
|
+
* Checks if the item is active on the specified date.
|
127
|
+
*
|
128
|
+
* @param {string|Date} date - The date to check.
|
129
|
+
* @returns {boolean} True if the item is active on the given date.
|
130
|
+
* @throws {Error} If the provided date is invalid.
|
131
|
+
*/
|
132
|
+
isActiveOn(date) {
|
133
|
+
const d = new Date(date);
|
134
|
+
if (isNaN(d.getTime())) {
|
135
|
+
throw new Error("Invalid date");
|
136
|
+
}
|
137
|
+
return this.startDate <= d && this.endDate >= d;
|
138
|
+
}
|
131
139
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
140
|
+
/**
|
141
|
+
* Returns a JSON-compatible object representing the item.
|
142
|
+
*
|
143
|
+
* @returns {Object} JSON representation of the item.
|
144
|
+
*/
|
145
|
+
toJSON() {
|
146
|
+
return {
|
147
|
+
id: this.id,
|
148
|
+
title: this.title,
|
149
|
+
type: this.type,
|
150
|
+
description: this.description,
|
151
|
+
userIds: this.userIds,
|
152
|
+
startDate: this.startDate.toISOString(),
|
153
|
+
endDate: this.endDate.toISOString(),
|
154
|
+
};
|
155
|
+
}
|
148
156
|
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
157
|
+
/**
|
158
|
+
* Creates a new Item instance from a JSON object.
|
159
|
+
*
|
160
|
+
* @param {Object} json - The JSON object.
|
161
|
+
* @param {string} json.id - The ID of the item.
|
162
|
+
* @param {string} json.title - The title of the item.
|
163
|
+
* @param {string} json.type - The type of the item.
|
164
|
+
* @param {string} json.startDate - The start date in ISO format.
|
165
|
+
* @param {string} json.endDate - The end date in ISO format.
|
166
|
+
* @param {string} [json.description=""] - The description of the item.
|
167
|
+
* @param {string|string[]} [json.userIds=[]] - One or more user IDs.
|
168
|
+
* @returns {Item} A new Item instance.
|
169
|
+
*/
|
170
|
+
static fromJson(json) {
|
171
|
+
return new Item({
|
172
|
+
id: json.id,
|
173
|
+
title: json.title,
|
174
|
+
type: json.type,
|
175
|
+
startDate: json.startDate,
|
176
|
+
endDate: json.endDate,
|
177
|
+
description: json.description,
|
178
|
+
userIds: json.userIds,
|
179
|
+
});
|
180
|
+
}
|
173
181
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
+
/**
|
183
|
+
* Returns a readable string representation of the item.
|
184
|
+
*
|
185
|
+
* @returns {string} String representation of the item.
|
186
|
+
*/
|
187
|
+
toString() {
|
188
|
+
return `[${this.type}] ${this.title} (${this.startDate.toLocaleString()} - ${this.endDate.toLocaleString()})`;
|
189
|
+
}
|
182
190
|
}
|
183
191
|
|
184
192
|
export { Item, AppointmentType };
|
@@ -70,6 +70,12 @@ const controlElementSymbol = Symbol("controlElement");
|
|
70
70
|
*/
|
71
71
|
const openEntryEventHandlerSymbol = Symbol("openEntryEventHandler");
|
72
72
|
|
73
|
+
/**
|
74
|
+
* @private
|
75
|
+
* @type {symbol}
|
76
|
+
*/
|
77
|
+
const firstRunDoneSymbol = Symbol("firstRunDone");
|
78
|
+
|
73
79
|
/**
|
74
80
|
* TreeMenu
|
75
81
|
*
|
@@ -161,23 +167,16 @@ class TreeMenu extends CustomElement {
|
|
161
167
|
});
|
162
168
|
}
|
163
169
|
|
164
|
-
/**
|
165
|
-
*
|
166
|
-
*/
|
167
|
-
[initMethodSymbol]() {
|
168
|
-
super[initMethodSymbol]();
|
169
|
-
}
|
170
|
-
|
171
170
|
/**
|
172
171
|
* @return {void}
|
173
172
|
*/
|
174
173
|
[assembleMethodSymbol]() {
|
175
174
|
super[assembleMethodSymbol]();
|
176
175
|
|
177
|
-
initControlReferences.call(this);
|
178
|
-
initEventHandler.call(this);
|
179
|
-
initObserver.call(this);
|
180
176
|
queueMicrotask(() => {
|
177
|
+
initControlReferences.call(this);
|
178
|
+
initEventHandler.call(this);
|
179
|
+
initObserver.call(this);
|
181
180
|
copyIconMap.call(this);
|
182
181
|
});
|
183
182
|
}
|
@@ -230,15 +229,15 @@ class TreeMenu extends CustomElement {
|
|
230
229
|
|
231
230
|
currentNode.click();
|
232
231
|
|
233
|
-
let intend = parseInt(currentNode.getAttribute(ATTRIBUTE_INTEND));
|
232
|
+
let intend = Number.parseInt(currentNode.getAttribute(ATTRIBUTE_INTEND));
|
234
233
|
|
235
234
|
if (intend > 0) {
|
236
235
|
const refSet = new Set();
|
237
236
|
let ref = currentNode.previousElementSibling;
|
238
|
-
while (ref
|
239
|
-
const i = parseInt(ref.getAttribute(ATTRIBUTE_INTEND));
|
237
|
+
while (ref?.hasAttribute(ATTRIBUTE_INTEND)) {
|
238
|
+
const i = Number.parseInt(ref.getAttribute(ATTRIBUTE_INTEND));
|
240
239
|
|
241
|
-
if (isNaN(i)) {
|
240
|
+
if (Number.isNaN(i)) {
|
242
241
|
break;
|
243
242
|
}
|
244
243
|
|
@@ -342,10 +341,10 @@ function initEventHandler() {
|
|
342
341
|
let intend = currentEntry.intend;
|
343
342
|
if (intend > 0) {
|
344
343
|
let ref = container.previousElementSibling;
|
345
|
-
while (ref
|
346
|
-
const i = parseInt(ref.getAttribute(ATTRIBUTE_INTEND));
|
344
|
+
while (ref?.hasAttribute(ATTRIBUTE_INTEND)) {
|
345
|
+
const i = Number.parseInt(ref.getAttribute(ATTRIBUTE_INTEND));
|
347
346
|
|
348
|
-
if (isNaN(i)) {
|
347
|
+
if (Number.isNaN(i)) {
|
349
348
|
break;
|
350
349
|
}
|
351
350
|
|
@@ -393,10 +392,10 @@ function initEventHandler() {
|
|
393
392
|
return a >= b;
|
394
393
|
};
|
395
394
|
|
396
|
-
while (ref
|
395
|
+
while (ref?.hasAttribute(ATTRIBUTE_INTEND)) {
|
397
396
|
const refIntend = ref.getAttribute(ATTRIBUTE_INTEND);
|
398
397
|
|
399
|
-
if (!cmp(parseInt(refIntend), childIntend)) {
|
398
|
+
if (!cmp(Number.parseInt(refIntend), childIntend)) {
|
400
399
|
if (refIntend === intend) {
|
401
400
|
break;
|
402
401
|
}
|
@@ -456,9 +455,26 @@ function importEntries() {
|
|
456
455
|
|
457
456
|
const selector = mappingOptions?.["selector"];
|
458
457
|
|
458
|
+
let filteredData;
|
459
|
+
if (this[firstRunDoneSymbol] !== true) {
|
460
|
+
filteredData = data.filter(
|
461
|
+
(entry) =>
|
462
|
+
!entry[parentKey] ||
|
463
|
+
entry[parentKey] === null ||
|
464
|
+
entry[parentKey] === undefined ||
|
465
|
+
entry[parentKey] === 0,
|
466
|
+
);
|
467
|
+
setTimeout(() => {
|
468
|
+
this[firstRunDoneSymbol] = true;
|
469
|
+
importEntries.call(this);
|
470
|
+
}, 0);
|
471
|
+
} else {
|
472
|
+
filteredData = data;
|
473
|
+
}
|
474
|
+
|
459
475
|
let nodes;
|
460
476
|
try {
|
461
|
-
nodes = buildTree(
|
477
|
+
nodes = buildTree(filteredData, selector, id, parentKey, {
|
462
478
|
filter,
|
463
479
|
rootReferences,
|
464
480
|
});
|
package/source/monster.mjs
CHANGED
@@ -31,7 +31,7 @@ export * from "./components/content/viewer.mjs";
|
|
31
31
|
export * from "./components/content/copy.mjs";
|
32
32
|
export * from "./components/content/camera.mjs";
|
33
33
|
export * from "./components/time/timeline/segment.mjs";
|
34
|
-
export * from "./components/time/
|
34
|
+
export * from "./components/time/timeline/item.mjs";
|
35
35
|
export * from "./components/time/month-calendar.mjs";
|
36
36
|
export * from "./components/form/message-state-button.mjs";
|
37
37
|
export * from "./components/form/password.mjs";
|
package/source/types/version.mjs
CHANGED
package/test/cases/monster.mjs
CHANGED
package/test/web/test.html
CHANGED
@@ -9,8 +9,8 @@
|
|
9
9
|
</head>
|
10
10
|
<body>
|
11
11
|
<div id="headline" style="display: flex;align-items: center;justify-content: center;flex-direction: column;">
|
12
|
-
<h1 style='margin-bottom: 0.1em;'>Monster 3.
|
13
|
-
<div id="lastupdate" style='font-size:0.7em'>last update
|
12
|
+
<h1 style='margin-bottom: 0.1em;'>Monster 3.112.0</h1>
|
13
|
+
<div id="lastupdate" style='font-size:0.7em'>last update Sa 8. Mär 00:49:17 CET 2025</div>
|
14
14
|
</div>
|
15
15
|
<div id="mocha-errors"
|
16
16
|
style="color: red;font-weight: bold;display: flex;align-items: center;justify-content: center;flex-direction: column;margin:20px;"></div>
|