work-tracing/static/js/userStates.js
2025-05-16 17:55:30 +04:00

136 lines
5.2 KiB
JavaScript

/**
* userStates.js - User state management
*
* This module handles all functionality related to user working states.
*/
import AppState from './state.js';
import { fetchUserStates } from './api.js';
/**
* Get user state display HTML
* @param {string} username - Username to get state for
* @returns {string} - HTML string for displaying the user state
*/
export function getUserStateDisplay(username) {
const state = getUserActualState(username);
if (state === 'working') {
return '<span class="badge bg-success">Working</span>';
} else if (state === 'not_working') {
return '<span class="badge bg-secondary">Not Working</span>';
} else {
return '<span class="badge bg-light text-dark">Unknown</span>';
}
}
/**
* Get the actual state for a user (from API or simulation)
* @param {string} username - Username to get state for
* @returns {string} - User state ('working', 'not_working', or 'unknown')
*/
export function getUserActualState(username) {
// const userStates = AppState.getUserStates(); // This line is now inside the AppState check
// Removed obsolete simulation logic:
// [Multi-line commented out block that was here previously]
// Return state from API if available, otherwise 'unknown'
// Ensure AppState and getUserStates are available before calling
if (AppState && typeof AppState.getUserStates === 'function') {
const states = AppState.getUserStates();
return states[username] || 'unknown';
}
console.warn("AppState.getUserStates is not available in getUserActualState. Returning 'unknown'.");
return 'unknown'; // Fallback if AppState is not ready
}
/**
* Get state value for sorting (numeric value)
* @param {string} username - Username to get state value for
* @returns {number} - Numeric state value for sorting
*/
export function getUserStateValue(username) {
// Return a numeric value for sorting states
// Working (2) > Unknown (1) > Not Working (0)
const state = getUserActualState(username);
if (state === 'working') {
return 2;
} else if (state === 'unknown') {
return 1;
} else {
return 0;
}
}
/**
* Update displayed states in the table
*/
export function updateTableStates() {
// Get all user rows
const userRows = document.querySelectorAll('.user-link');
userRows.forEach(userLink => {
const username = userLink.getAttribute('data-user');
const row = userLink.closest('tr');
const stateCell = row.querySelector('.user-state-cell');
if (stateCell) {
stateCell.innerHTML = getUserStateDisplay(username);
}
});
}
/**
* Refresh user states from server
* @param {boolean} forceRefresh - Force refresh even if cache is valid
* @returns {Promise<Object>} - Promise resolving to user states
*/
export async function refreshUserStates(forceRefresh = false) {
const refreshStatesBtn = document.getElementById('refreshStates');
// Check if AppState and its methods are available
if (!AppState || typeof AppState.isAutoRefreshEnabled !== 'function') {
console.error("AppState or AppState.isAutoRefreshEnabled is not available in refreshUserStates.");
// Attempt to restore button if it exists, then return
if (refreshStatesBtn) {
refreshStatesBtn.innerHTML = '<i class="bi bi-arrow-clockwise"></i> Refresh States';
refreshStatesBtn.disabled = false;
}
return Promise.reject(new Error("AppState not ready for refreshing user states.")); // Return a rejected promise
}
// Show a small spinner only if force refresh and not auto-refresh
if (refreshStatesBtn && forceRefresh && !AppState.isAutoRefreshEnabled()) {
refreshStatesBtn.innerHTML = '<span class="spinner-border spinner-border-sm" role="status" aria-hidden="true"></span> Refreshing...';
refreshStatesBtn.disabled = true;
} else if (!refreshStatesBtn && forceRefresh && !AppState.isAutoRefreshEnabled()) {
console.warn("refreshStatesBtn not found, cannot update UI during state refresh.");
}
try {
// Fetch the latest user states
const states = await fetchUserStates(forceRefresh);
// Update existing rows with new states
updateTableStates();
// If we're filtering by state, reapply the filter with the new state data
// This is likely handled by dashboard.js after loadReportData completes which includes state updates.
// Commenting out to avoid potential double filtering or race conditions.
// if (AppState.getCurrentStateFilter() !== 'all') {
// // Note: This requires the filters module
// // Will need to be imported or called through a callback
// console.log('State filter reapplication from userStates.js - potentially redundant');
// // Filters.filterTableByState(AppState.getCurrentStateFilter()); // Example if it were to be called here
// }
return states;
} finally {
if (refreshStatesBtn && forceRefresh && !AppState.isAutoRefreshEnabled()) {
refreshStatesBtn.innerHTML = '<i class="bi bi-arrow-clockwise"></i> Refresh States';
refreshStatesBtn.disabled = false;
}
}
}