Skip to content

Commit 054df44

Browse files
I've refactored your JavaScript modules to use classes, which helps remove test helpers.
Here's what I did: I updated several of your JavaScript modules (`session.js`, `tabcontrol.js`, `cui.js`) to use class-based designs for stateful logic. This change removes the need for test-specific helper functions (`_resetState`, `_getState`) in your production code. Key changes include: - `session.js`: I refactored this to a `Session` class. - `tabcontrol.js`: I refactored this to a `TabControl` class. - `cui.js`: I refactored the stateful idle-handling logic into a `CuiIdleHandler` class. Stateless utilities remain as exported functions. - I updated the respective test files (`session.test.js`, `tabcontrol.test.js`, `cui_core.test.js`) to use these new classes. - I updated `jest.setup.js` to remove the now-unnecessary reset calls for these modules. All JavaScript tests are passing, and ESLint shows only pre-existing or minor warnings. **Important Note on Your Build Process:** The current JavaScript build process in your `package.json` (`concat:js`) simply concatenates files. This is not compatible with the ES6 module structure I introduced in these refactorings. For these modules to be correctly consumed by browsers, you'll need to update your build process to use a proper JavaScript bundler (e.g., Webpack, Rollup). A bundler can understand ES6 modules and correctly scope them, while also defining how the public API (e.g., `Session` class, `CuiIdleHandler` class, utility functions) is exposed globally for browser consumption. This is a necessary follow-up task for you.
1 parent e77bb79 commit 054df44

File tree

7 files changed

+364
-267
lines changed

7 files changed

+364
-267
lines changed

web-modules/cui-javascript/src/main/resources/META-INF/resources/de.cuioss.javascript/cui.js

Lines changed: 43 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,44 @@
11
// Assuming jQuery ($) and faces are globally available from the test environment / browser
22

3-
// Module-scoped variable for state
4-
let _onIdleArray = [];
3+
// --- CuiIdleHandler Class ---
4+
export class CuiIdleHandler {
5+
constructor() {
6+
this.onIdleArray = [];
7+
}
8+
9+
/**
10+
* Registers a callback to be executed when an idle event occurs.
11+
* @param {function} callback - The callback function.
12+
*/
13+
register(callback) {
14+
if (typeof callback === 'function') {
15+
this.onIdleArray.push(callback);
16+
}
17+
}
18+
19+
/**
20+
* Executes all registered onIdle callbacks and shows timeout modals.
21+
*/
22+
execute() {
23+
// $ is assumed global
24+
if (typeof $ === 'function') {
25+
const modalEl = $('.modal');
26+
if (modalEl && typeof modalEl.modal === 'function') modalEl.modal('hide');
27+
28+
const confirmDialog = $('[data-modal-dialog-id=confirmDialogTimeout]');
29+
if (confirmDialog && typeof confirmDialog.modal === 'function') confirmDialog.modal('show');
30+
31+
const bodyEl = $(document.body);
32+
if (bodyEl && typeof bodyEl.addClass === 'function') bodyEl.addClass('modal-timeout');
33+
}
34+
35+
this.onIdleArray.forEach((callback) => {
36+
if (typeof callback === 'function') callback();
37+
});
38+
}
39+
}
40+
41+
// --- Standalone Utility Functions ---
542

643
// Private helper function for getData
744
function _decodeText(text) {
@@ -87,13 +124,13 @@ function _handleAjaxError() {
87124
export function addErrorMessage() {
88125
// faces is assumed global
89126
if (typeof faces !== "undefined" && faces.ajax && typeof faces.ajax.addOnError === 'function') {
90-
faces.ajax.addOnError((data) => {
127+
faces.ajax.addOnError((data) => { // data is unused but part of API
91128
_handleAjaxError();
92129
});
93130
}
94131
// $ is assumed global
95132
if (typeof $ === 'function' && typeof $(document).on === 'function') {
96-
$(document).on("pfAjaxError", function (event, xhr) {
133+
$(document).on("pfAjaxError", function (event, xhr ) {
97134
const statusText = 'statusText';
98135
if (xhr && xhr[statusText] !== 'abort') {
99136
_handleAjaxError();
@@ -146,37 +183,6 @@ export function registerComponentEnabler(callback) {
146183
}
147184
}
148185

149-
/**
150-
* Registers a callback to be executed when an idle event occurs.
151-
* @param {function} callback - The callback function.
152-
*/
153-
export function registerOnIdle(callback) {
154-
if (typeof callback === 'function') {
155-
_onIdleArray.push(callback);
156-
}
157-
}
158-
159-
/**
160-
* Executes all registered onIdle callbacks and shows timeout modals.
161-
*/
162-
export function executeOnIdle() {
163-
// $ is assumed global
164-
if (typeof $ === 'function') {
165-
const modalEl = $('.modal');
166-
if (modalEl && typeof modalEl.modal === 'function') modalEl.modal('hide');
167-
168-
const confirmDialog = $('[data-modal-dialog-id=confirmDialogTimeout]');
169-
if (confirmDialog && typeof confirmDialog.modal === 'function') confirmDialog.modal('show');
170-
171-
const bodyEl = $(document.body);
172-
if (bodyEl && typeof bodyEl.addClass === 'function') bodyEl.addClass('modal-timeout');
173-
}
174-
175-
_onIdleArray.forEach((callback) => {
176-
if (typeof callback === 'function') callback();
177-
});
178-
}
179-
180186
/**
181187
* Opens a URL in a new window/tab.
182188
* @param {string} applicationUrl - The URL to open.
@@ -195,21 +201,5 @@ export function openExternalApplicationInNewWindow(applicationUrl) {
195201
}
196202
}
197203

198-
/**
199-
* FOR TESTING PURPOSES ONLY.
200-
* Resets the internal state of the core module.
201-
*/
202-
export function _resetCoreState() {
203-
_onIdleArray = [];
204-
}
205-
206-
/**
207-
* FOR TESTING PURPOSES ONLY.
208-
* Gets the current internal state.
209-
* @returns {object} The internal state.
210-
*/
211-
export function _getCoreState() {
212-
return {
213-
onIdleArray: _onIdleArray
214-
};
215-
}
204+
// Removed _resetCoreState and _getCoreState as per instructions
205+
// Removed _onIdleArray, registerOnIdle, executeOnIdle as they are now part of CuiIdleHandler
Lines changed: 66 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,83 @@
11
import { escapeClientId } from './cui_utilities.js';
22

3-
// Module-scoped variables to hold state
4-
let _timeout = null;
5-
let _interval = 0;
6-
let _linkId = '';
7-
let _storedCallback = null;
3+
// Assuming jQuery ($) is available globally
84

9-
/**
10-
* Internal function to set the actual timeout.
11-
* Uses module-scoped variables.
12-
*/
13-
function _setLogoutTimeout() {
14-
if (_timeout) {
15-
clearTimeout(_timeout);
5+
export class Session {
6+
constructor(linkId, intervalSec, callback) {
7+
this.linkId = linkId;
8+
this.interval = (intervalSec === undefined || intervalSec <= 0 ? 1 : intervalSec) * 1000; // Default to 1 sec if invalid
9+
this.callback = callback;
10+
this.timeoutId = null;
1611
}
1712

18-
if (_storedCallback) {
19-
if (_interval > 0) {
20-
_timeout = setTimeout(_storedCallback, _interval);
13+
/**
14+
* Internal method to set the actual timeout.
15+
* Uses instance properties.
16+
*/
17+
_setTimer() {
18+
if (this.timeoutId) {
19+
clearTimeout(this.timeoutId);
2120
}
22-
} else {
23-
if (_interval > 0) {
24-
_timeout = setTimeout(() => {
25-
// Assuming jQuery ($) and escapeClientId are available
26-
// escapeClientId is imported, $ is assumed global for now
27-
const elementToClick = $(escapeClientId(_linkId));
28-
if (elementToClick.length > 0 && typeof elementToClick[0].click === 'function') {
29-
elementToClick[0].click();
30-
} else if (elementToClick.length > 0 && typeof elementToClick.click === 'function') {
31-
elementToClick.click();
21+
22+
if (this.interval <= 0) { // Do not set timer if interval is not positive
23+
this.timeoutId = null;
24+
return;
25+
}
26+
27+
if (this.callback) {
28+
this.timeoutId = setTimeout(this.callback, this.interval);
29+
} else if (this.linkId) { // Only set timeout if linkId is provided and no callback
30+
this.timeoutId = setTimeout(() => {
31+
const elementToClick = $(escapeClientId(this.linkId));
32+
if (elementToClick.length > 0) {
33+
if (typeof elementToClick[0].click === 'function') {
34+
elementToClick[0].click();
35+
} else if (typeof elementToClick.click === 'function') {
36+
elementToClick.click();
37+
}
3238
}
33-
}, _interval);
39+
}, this.interval);
40+
} else {
41+
this.timeoutId = null; // No action possible
3442
}
3543
}
36-
}
37-
38-
/**
39-
* Initialize logout timeout.
40-
* @param {number} intervalSec - Interval in seconds.
41-
* @param {string} linkId - The ID of the link to click if no callback.
42-
* @param {function} [callback] - Function to execute after timeout.
43-
*/
44-
export function startLogoutTimeout(intervalSec, linkId, callback) {
45-
_interval = (intervalSec === undefined ? 1 : intervalSec) * 1000;
46-
_linkId = linkId;
47-
_storedCallback = callback;
48-
_setLogoutTimeout();
49-
}
5044

51-
/**
52-
* Reset logout timeout using previously stored settings.
53-
*/
54-
export function resetLogoutTimeout() {
55-
if (_timeout) {
56-
clearTimeout(_timeout);
57-
_timeout = null;
45+
/**
46+
* Starts the logout timeout.
47+
*/
48+
start() {
49+
this._setTimer();
5850
}
59-
// Re-apply the timeout with the stored interval, linkId, and callback
60-
_setLogoutTimeout();
61-
}
6251

63-
/**
64-
* Stop the logout timeout.
65-
*/
66-
export function stopLogoutTimeout() {
67-
if (_timeout) {
68-
clearTimeout(_timeout);
69-
_timeout = null;
52+
/**
53+
* Resets the logout timeout using previously stored settings.
54+
*/
55+
reset() {
56+
// Stop any existing timer
57+
if (this.timeoutId) {
58+
clearTimeout(this.timeoutId);
59+
this.timeoutId = null;
60+
}
61+
// Re-apply the timer with the current instance settings
62+
this._setTimer();
7063
}
71-
}
7264

73-
/**
74-
* FOR TESTING PURPOSES ONLY.
75-
* Resets the internal state of the session module.
76-
*/
77-
export function _resetSessionState() {
78-
if (_timeout) {
79-
clearTimeout(_timeout);
65+
/**
66+
* Stops the logout timeout.
67+
*/
68+
stop() {
69+
if (this.timeoutId) {
70+
clearTimeout(this.timeoutId);
71+
this.timeoutId = null;
72+
}
8073
}
81-
_timeout = null;
82-
_interval = 0;
83-
_linkId = '';
84-
_storedCallback = null;
85-
}
8674

87-
/**
88-
* FOR TESTING PURPOSES ONLY.
89-
* Gets the current internal state.
90-
* @returns {object} The internal state.
91-
*/
92-
export function _getSessionState() {
93-
return {
94-
timeout: _timeout,
95-
interval: _interval,
96-
linkId: _linkId,
97-
storedCallback: _storedCallback
98-
};
75+
/**
76+
* FOR TESTING PURPOSES ONLY.
77+
* Gets the current timeout ID.
78+
* @returns {object} The internal timeout ID.
79+
*/
80+
_getTimeoutId() {
81+
return this.timeoutId;
82+
}
9983
}

0 commit comments

Comments
 (0)