@schukai/monster 3.92.3 → 3.94.0

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 CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
 
4
4
 
5
+ ## [3.94.0] - 2024-12-22
6
+
7
+ ### Add Features
8
+
9
+ - **log:** auto update timestamp [#270](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/270)
10
+
11
+
12
+
13
+ ## [3.93.0] - 2024-12-22
14
+
15
+ ### Add Features
16
+
17
+ - **log:** update the apearance of the log [#270](https://gitlab.schukai.com/oss/libraries/javascript/monster/issues/270)
18
+
19
+
20
+
5
21
  ## [3.92.3] - 2024-12-20
6
22
 
7
23
  ### Bug Fixes
package/package.json CHANGED
@@ -1 +1 @@
1
- {"author":"schukai GmbH","dependencies":{"@floating-ui/dom":"^1.6.12","@popperjs/core":"^2.11.8"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"3.92.3"}
1
+ {"author":"schukai GmbH","dependencies":{"@floating-ui/dom":"^1.6.12","@popperjs/core":"^2.11.8"},"description":"Monster is a simple library for creating fast, robust and lightweight websites.","homepage":"https://monsterjs.org/","keywords":["framework","web","dom","css","sass","mobile-first","app","front-end","templates","schukai","core","shopcloud","alvine","monster","buildmap","stack","observer","observable","uuid","node","nodelist","css-in-js","logger","log","theme"],"license":"AGPL 3.0","main":"source/monster.mjs","module":"source/monster.mjs","name":"@schukai/monster","repository":{"type":"git","url":"https://gitlab.schukai.com/oss/libraries/javascript/monster.git"},"type":"module","version":"3.94.0"}
@@ -81,6 +81,9 @@ const filterObserverSymbol = Symbol("filterObserver");
81
81
  * @copyright schukai GmbH
82
82
  * @summary A rest api datasource
83
83
  */
84
+
85
+
86
+
84
87
  class Rest extends Datasource {
85
88
  /**
86
89
  * the constructor of the class
@@ -453,6 +456,13 @@ function initFilter() {
453
456
  filterControl.attachObserver(this[filterObserverSymbol]);
454
457
  }
455
458
 
459
+ /**
460
+ * @private
461
+ * @param json
462
+ * @param response
463
+ * @param filterControl
464
+ * @returns {Promise<never>|Promise<Awaited<unknown>>}
465
+ */
456
466
  function handleIntersectionObserver(json, response, filterControl) {
457
467
  const path = new Pathfinder(json);
458
468
 
@@ -495,6 +505,9 @@ function initAutoInit() {
495
505
  });
496
506
  }
497
507
 
508
+ /**
509
+ * @private
510
+ */
498
511
  function initEventHandler() {
499
512
  this[intersectionObserverHandlerSymbol] = (entries) => {
500
513
  entries.forEach((entry) => {
@@ -515,6 +528,9 @@ function initEventHandler() {
515
528
  };
516
529
  }
517
530
 
531
+ /**
532
+ * @private
533
+ */
518
534
  function initIntersectionObserver() {
519
535
  this.classList.add("intersection-observer");
520
536
 
@@ -528,6 +544,7 @@ function initIntersectionObserver() {
528
544
  this[intersectionObserverHandlerSymbol],
529
545
  options,
530
546
  );
547
+
531
548
  this[intersectionObserverObserverSymbol].observe(this);
532
549
  }
533
550
 
@@ -66,10 +66,10 @@ class Entry extends Base {
66
66
  */
67
67
  get internalDefaults() {
68
68
  return {
69
- title: undefined,
70
- message: undefined,
71
- user: undefined,
72
- date: undefined,
69
+ title: null,
70
+ message: null,
71
+ user: null,
72
+ date: null,
73
73
  };
74
74
  }
75
75
 
@@ -12,19 +12,20 @@
12
12
  * SPDX-License-Identifier: AGPL-3.0
13
13
  */
14
14
 
15
- import { instanceSymbol } from "../../constants.mjs";
15
+ import {instanceSymbol} from "../../constants.mjs";
16
16
  import {
17
- assembleMethodSymbol,
18
- CustomElement,
19
- getSlottedElements,
20
- registerCustomElement,
17
+ assembleMethodSymbol,
18
+ CustomElement,
19
+ getSlottedElements,
20
+ registerCustomElement,
21
21
  } from "../../dom/customelement.mjs";
22
- import { LogStyleSheet } from "./stylesheet/log.mjs";
23
- import { Entry } from "./log/entry.mjs";
24
- import { validateInstance } from "../../types/validate.mjs";
22
+ import {LogStyleSheet} from "./stylesheet/log.mjs";
23
+ import {Entry} from "./log/entry.mjs";
24
+ import {validateInstance, validateString} from "../../types/validate.mjs";
25
25
  import "./state.mjs";
26
+ import {getWindow} from "../../dom/util.mjs";
26
27
 
27
- export { Log };
28
+ export {Log};
28
29
 
29
30
  /**
30
31
  * @private
@@ -39,133 +40,154 @@ const logElementSymbol = Symbol("logElement");
39
40
  const emptyStateElementSymbol = Symbol("emptyStateElement");
40
41
 
41
42
  /**
42
- * A Log component
43
+ * A log entry
43
44
  *
44
- * @fragments /fragments/components/layout/collapse/
45
+ * @fragments /fragments/components/state/log
46
+ *
47
+ * @example /examples/components/state/log-simple
48
+ *
49
+ * @issue https://localhost.alvine.dev:8444/development/issues/closed/270.html
45
50
  *
46
51
  * @since 3.74.0
47
52
  * @copyright schukai GmbH
48
- * @summary A Log component to show a log message.
49
- */
53
+ * @summary The log entry is a single entry in the log.
54
+ **/
50
55
  class Log extends CustomElement {
51
- /**
52
- * @return {void}
53
- */
54
- [assembleMethodSymbol]() {
55
- super[assembleMethodSymbol]();
56
-
57
- initControlReferences.call(this);
58
- initEventHandler.call(this);
59
- }
60
-
61
- /**
62
- * This method is called by the `instanceof` operator.
63
- * @return {symbol}
64
- */
65
- static get [instanceSymbol]() {
66
- return Symbol.for("@schukai/monster/components/state/log@@instance");
67
- }
68
-
69
- /**
70
- * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
71
- * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
72
- *
73
- * The individual configuration values can be found in the table.
74
- *
75
- * @property {Object} templates Template definitions
76
- * @property {string} templates.main Main template
77
- * @property {Object} labels Labels
78
- * @property {string} labels.nothingToReport Label for empty state
79
- */
80
- get defaults() {
81
- return Object.assign({}, super.defaults, {
82
- templates: {
83
- main: getTemplate(),
84
- },
85
-
86
- labels: {
87
- nothingToReport: "There is nothing to report yet.",
88
- },
89
-
90
- entries: [],
91
- });
92
- }
93
-
94
- /**
95
- * @return {void}
96
- */
97
- connectedCallback() {
98
- super.connectedCallback();
99
-
100
- const slottedElements = getSlottedElements.call(this);
101
- if (slottedElements.size > 0) {
102
- this[emptyStateElementSymbol].style.display = "none";
103
- }
104
- }
105
-
106
- /**
107
- * Clear the log
108
- *
109
- * @return {Log}
110
- */
111
- clear() {
112
- this[logElementSymbol].innerHTML = "";
113
- this[emptyStateElementSymbol].style.display = "block";
114
- return this;
115
- }
116
-
117
- /**
118
- * Add an entry to the log
119
- * @param entry
120
- * @return {Log}
121
- */
122
- addEntry(entry) {
123
- validateInstance(entry, Entry);
124
-
125
- const entries = this.getOption("entries");
126
- entries.push(entry);
127
-
128
- /** this field is not used, but triggers a change event */
129
- this.setOption("length", entries.length - 1);
130
-
131
- return this;
132
- }
133
-
134
- /**
135
- * Add a log message
136
- * @param message
137
- * @param date
138
- * @return {Log}
139
- */
140
- addMessage(message, date) {
141
- if (!date) {
142
- date = new Date();
143
- }
144
-
145
- this.addEntry(
146
- new Entry({
147
- message: message,
148
- date: date,
149
- }),
150
- );
151
-
152
- return this;
153
- }
154
-
155
- /**
156
- *
157
- * @return {string}
158
- */
159
- static getTag() {
160
- return "monster-log";
161
- }
162
-
163
- /**
164
- * @return {CSSStyleSheet[]}
165
- */
166
- static getCSSStyleSheet() {
167
- return [LogStyleSheet];
168
- }
56
+ /**
57
+ * @return {void}
58
+ */
59
+ [assembleMethodSymbol]() {
60
+ super[assembleMethodSymbol]();
61
+
62
+ initControlReferences.call(this);
63
+ initEventHandler.call(this);
64
+ }
65
+
66
+ /**
67
+ * This method is called by the `instanceof` operator.
68
+ * @return {symbol}
69
+ */
70
+ static get [instanceSymbol]() {
71
+ return Symbol.for("@schukai/monster/components/state/log@@instance");
72
+ }
73
+
74
+ /**
75
+ * To set the options via the HTML tag, the attribute `data-monster-options` must be used.
76
+ * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
77
+ *
78
+ * The individual configuration values can be found in the table.
79
+ *
80
+ * @property {Object} templates Template definitions
81
+ * @property {string} templates.main Main template
82
+ * @property {Object} labels Labels
83
+ * @property {string} labels.nothingToReport Label for empty state
84
+ * @property {number} updateFrequency Update frequency in milliseconds for the timestamp
85
+ */
86
+ get defaults() {
87
+ return Object.assign({}, super.defaults, {
88
+ templates: {
89
+ main: getTemplate(),
90
+ },
91
+
92
+ labels: {
93
+ nothingToReport: "There is nothing to report yet.",
94
+ },
95
+
96
+ classes: {
97
+ direction: "vertical",
98
+ },
99
+
100
+ updateFrequency: 10000,
101
+
102
+ entries: [],
103
+
104
+ timestamp: 0,
105
+ });
106
+ }
107
+
108
+ /**
109
+ * @return {void}
110
+ */
111
+ connectedCallback() {
112
+ super.connectedCallback();
113
+
114
+ const slottedElements = getSlottedElements.call(this);
115
+ if (slottedElements.size > 0) {
116
+ this[emptyStateElementSymbol].style.display = "none";
117
+ }
118
+ }
119
+
120
+ /**
121
+ * Clear the log
122
+ *
123
+ * @return {Log}
124
+ */
125
+ clear() {
126
+ this[logElementSymbol].innerHTML = "";
127
+ this[emptyStateElementSymbol].style.display = "block";
128
+ return this;
129
+ }
130
+
131
+ /**
132
+ * Add an entry to the log
133
+ * @param {Entry} entry
134
+ * @return {Log}
135
+ */
136
+ addEntry(entry) {
137
+ validateInstance(entry, Entry);
138
+
139
+ if (entry.date === undefined || entry.date === null) {
140
+ entry.date = new Date();
141
+ }
142
+
143
+ const entries = this.getOption("entries");
144
+ entries.push(entry);
145
+
146
+ /** this field is not used, but triggers a change event */
147
+ this.setOption("length", entries.length - 1);
148
+
149
+ return this;
150
+ }
151
+
152
+ /**
153
+ * Add a log message
154
+ *
155
+ * @param {string} message
156
+ * @param {Date} date
157
+ * @return {Log}
158
+ * @throws {TypeError} message is not a string
159
+ */
160
+ addMessage(message, date) {
161
+ if (!date) {
162
+ date = new Date();
163
+ }
164
+
165
+ validateString(message);
166
+
167
+ this.addEntry(
168
+ new Entry({
169
+ message: message,
170
+ date: date,
171
+ }),
172
+ );
173
+
174
+ return this;
175
+ }
176
+
177
+ /**
178
+ *
179
+ * @return {string}
180
+ */
181
+ static getTag() {
182
+ return "monster-log";
183
+ }
184
+
185
+ /**
186
+ * @return {CSSStyleSheet[]}
187
+ */
188
+ static getCSSStyleSheet() {
189
+ return [LogStyleSheet];
190
+ }
169
191
  }
170
192
 
171
193
  /**
@@ -174,37 +196,44 @@ class Log extends CustomElement {
174
196
  * @throws {Error} no shadow-root is defined
175
197
  */
176
198
  function initControlReferences() {
177
- if (!this.shadowRoot) {
178
- throw new Error("no shadow-root is defined");
179
- }
180
-
181
- this[logElementSymbol] = this.shadowRoot.querySelector(
182
- "[data-monster-role=control]",
183
- );
184
- this[emptyStateElementSymbol] = this.shadowRoot.querySelector(
185
- "[data-monster-role=empty-state]",
186
- );
199
+ if (!this.shadowRoot) {
200
+ throw new Error("no shadow-root is defined");
201
+ }
202
+
203
+ this[logElementSymbol] = this.shadowRoot.querySelector(
204
+ "[data-monster-role=control]",
205
+ );
206
+ this[emptyStateElementSymbol] = this.shadowRoot.querySelector(
207
+ "[data-monster-role=empty-state]",
208
+ );
187
209
  }
188
210
 
189
211
  /**
190
212
  * @private
191
213
  */
192
214
  function initEventHandler() {
193
- if (!this.shadowRoot) {
194
- throw new Error("no shadow-root is defined");
195
- }
215
+ if (!this.shadowRoot) {
216
+ throw new Error("no shadow-root is defined");
217
+ }
196
218
 
197
- this.shadowRoot.addEventListener("slotchange", (event) => {
198
- const slottedElements = getSlottedElements.call(this);
219
+ this.shadowRoot.addEventListener("slotchange", (event) => {
220
+ const slottedElements = getSlottedElements.call(this);
199
221
 
200
- if (slottedElements.size > 0) {
201
- this[emptyStateElementSymbol].style.display = "none";
202
- } else {
203
- this[emptyStateElementSymbol].style.display = "block";
204
- }
205
- });
222
+ if (slottedElements.size > 0) {
223
+ this[emptyStateElementSymbol].style.display = "none";
224
+ } else {
225
+ this[emptyStateElementSymbol].style.display = "block";
226
+ }
227
+ });
206
228
 
207
- return this;
229
+ setInterval(() => {
230
+ getWindow().requestAnimationFrame(() => {
231
+ const timestamp = (new Date()).toTimeString();
232
+ this.setOption("timestamp", timestamp);
233
+ });
234
+ }, this.getOption("updateFrequency"));
235
+
236
+ return this;
208
237
  }
209
238
 
210
239
  /**
@@ -212,23 +241,22 @@ function initEventHandler() {
212
241
  * @return {string}
213
242
  */
214
243
  function getTemplate() {
215
- // language=HTML
216
- return `
244
+ // language=HTML
245
+ return `
217
246
  <template id="entry">
218
247
  <li data-monster-role="entry">
219
- <span></span>
220
- <div data-monster-replace="path:entry.title"
221
- data-monster-attributes="class path:entry.title | ?:title:hidden"></div>
222
- <div data-monster-replace="path:entry.message"
223
- data-monster-attributes="class path:entry.message | ?:message:hidden"></div>
224
- <div data-monster-replace="path:entry.user"
225
- data-monster-attributes="class path:entry.user | ?:user:hidden"></div>
226
- <div data-monster-attributes="class path:entry.date | is-set | ?:datetime:hidden">
227
- <span data-monster-replace="path:entry.date | date"></span>
228
- <span data-monster-replace="path:entry.date | time"></span>
229
- </div>
248
+ <span data-monster-replace="path:entry.user"
249
+ data-monster-attributes="class path:entry.user | ?:user:hidden"></span>
250
+ <span data-monster-replace="path:entry.title"
251
+ data-monster-attributes="class path:entry.title | ?:title:hidden"></span>
252
+ <span data-monster-replace="path:entry.message"
253
+ data-monster-attributes="class path:entry.message | ?:message:hidden"></span>
254
+ <span data-monster-replace="path:entry.date | time-ago"
255
+ data-monster-attributes="title path:entry.date | datetime"></span>
256
+
230
257
  </li>
231
258
  </template>
259
+
232
260
  <div part="control" data-monster-role="control">
233
261
  <div data-monster-role="empty-state" data-monster-attributes="class path:entries | has-entries | ?:hidden:">
234
262
  <monster-state>
@@ -240,7 +268,7 @@ function getTemplate() {
240
268
  <path d="m256 314.925781c-2.628906 0-5.210938 1.066407-7.070312 2.929688-1.859376 1.867187-2.929688 4.4375-2.929688 7.070312 0 2.636719 1.070312 5.207031 2.929688 7.078125 1.859374 1.859375 4.441406 2.921875 7.070312 2.921875s5.210938-1.0625 7.070312-2.921875c1.859376-1.871094 2.929688-4.441406 2.929688-7.078125 0-2.632812-1.070312-5.203125-2.929688-7.070312-1.859374-1.863281-4.441406-2.929688-7.070312-2.929688zm0 0"/>
241
269
  </svg>
242
270
  </div>
243
- <div part="content" monster-replace="path:labels.nothingToReport">
271
+ <div part="content" data-monster-replace="path:labels.nothingToReport">
244
272
  There is nothing to report yet.
245
273
  </div>
246
274
  </monster-state>
@@ -8,104 +8,56 @@
8
8
  @import "../../style/mixin/hover.pcss";
9
9
 
10
10
  [data-monster-role=entries] {
11
- overflow: hidden;
12
- padding: 10px 0 40px 60px;
11
+ display: flex;
12
+ flex-direction: column;
13
+ align-items: flex-start;
14
+ border: 0;
15
+ padding: 0;
16
+ margin: 0;
17
+ box-sizing: border-box;
18
+ position: relative;
13
19
 
14
20
  & ul {
15
21
  list-style-type: none;
16
22
  margin: 0;
17
- padding: 0;
18
- position: relative;
19
- top: 0
20
- }
21
-
22
- & ul:last-of-type {
23
- top: 2rem;
23
+ padding: 0 0 0 1.8rem; /* Abstand links behalten */
24
+ width: 100%; /* Flex-Container-Anpassung */
24
25
  }
25
26
 
26
27
  & ul:before {
27
28
  content: "";
28
29
  display: block;
29
- width: 0;
30
+ width: 2px;
30
31
  height: 100%;
31
- border: 1px dashed var(--monster-color-primary-2);
32
+
33
+ border-left-color: var(--monster-bg-color-primary-3);
34
+ border-left-style: dotted;
35
+ border-left-width: 1px;
32
36
  position: absolute;
37
+ left: 1rem;
38
+ bottom: 0;
33
39
  top: 0;
34
- left: 30px
35
40
  }
36
41
 
37
42
  & ul li {
38
- margin: 20px 60px 60px;
39
- position: relative;
40
- padding: 10px 20px;
41
- color: var(--monster-color-primary-2);
42
- background-color: var(--monster-bg-color-primary-2);
43
+ margin: 0;
44
+ padding: 0.1rem 0.3rem;
45
+ color: var(--monster-color-primary-1);
46
+ background-color: var(--monster-bg-color-primary-1);
43
47
  border-radius: 5px;
48
+ position: relative;
44
49
  }
45
50
 
46
-
47
- & ul li > span {
48
- content: "";
49
- display: block;
50
- width: 0;
51
- height: 100%;
52
- border: 1px solid var(--monster-color-primary-2);
53
- position: absolute;
54
- top: 0;
55
- left: -30px
56
- }
57
-
58
- & ul li > span:before, & ul li > span:after {
51
+ & ul li:before {
59
52
  content: "";
60
- display: block;
61
- width: 10px;
62
- height: 10px;
53
+ width: 6px;
54
+ height: 6px;
55
+ box-sizing: border-box;
63
56
  border-radius: 50%;
64
- background: var(--monster-bg-color-primary-2);
65
- border: 2px solid var(--monster-color-primary-2);
66
- position: absolute;
67
- left: -7.5px
68
- }
69
-
70
- & ul li > span:before {
71
- top: -10px
72
- }
73
-
74
- & ul li > span:after {
75
- top: 95%
76
- }
77
-
78
- & .title {
79
- text-transform: uppercase;
80
- margin-bottom: 5px
81
- }
82
-
83
- & .message:first-letter {
84
- }
85
-
86
- & .user {
87
- margin-top: 10px;
88
- font-style: italic;
89
- text-align: right;
90
- margin-right: 20px;
91
- font-size: 0.8rem;
92
- }
93
-
94
- & .datetime span {
57
+ background: var(--monster-bg-color-primary-3);
58
+ border: 1px solid var(--monster-color-primary-2);
95
59
  position: absolute;
96
- left: -100px;
97
- color: var(--monster-color-primary-1);
98
- background-color: var(--monster-bg-color-primary-1);
99
- font-size: 0.5rem;
100
- }
101
-
102
- & .datetime span:first-child {
103
- top: -16px
104
- }
105
-
106
- & .datetime span:last-child {
107
- top: 94%
60
+ left: calc(-1rem + (5px / 4));
61
+ top: 0.6rem;
108
62
  }
109
-
110
-
111
- }
63
+ }