Global UI Design
Document Type: Domain Design (Tier 2) Domain: GLOBALUI, UI, KEYBOARD Domain Character: Thin orchestration SRS References: globalui.md, ui.md, keyboard.md Status: Draft Last Updated: 2026-01-25
1. Overview
1.1 Purpose
The Global UI subsystem provides cross-cutting user interface behaviors that apply throughout the application. This includes system status communication, session management, user identification, notification delivery, user preference controls, display optimization, and keyboard shortcuts.
This is a thin orchestration domain. The subsystem coordinates frontend components with minimal owned business logic. Most requirements are implemented entirely in Vue.js frontend components, with backend support for:
- Maintenance mode display (Laravel maintenance framework)
- Feature flags (infinite scrolling toggle)
- Session management (Cognito authentication)
1.2 Requirements Covered
| REQ ID | Title | Priority |
|---|---|---|
| REQ-GLOBALUI-001 | Display Maintenance Status | Must |
| REQ-GLOBALUI-002 | Display Application Version | Must |
| REQ-GLOBALUI-003 | Communicate Session Termination Reason | Must |
| REQ-GLOBALUI-004 | Provide Idle Timeout Warning | Must |
| REQ-GLOBALUI-005 | Paginate Application Notifications | Must |
| REQ-GLOBALUI-006 | Display User Display Names | Must |
| REQ-GLOBALUI-007 | Filter Sites by Cognito Group | Must |
| REQ-GLOBALUI-008 | Display User Role Indicator | Must |
| REQ-GLOBALUI-009 | Provide Infinite Scrolling Toggle | Must |
| REQ-UI-001 | Display Optimization | Must |
| REQ-KEYBOARD-001 | Execute Actions via Keyboard Shortcuts | Must |
| REQ-KEYBOARD-002 | Dismiss Active Modal or Widget | Must |
1.3 Constraints
Tier 2 Constraint: This document describes ownership, patterns, and design rationale. It links to reference docs for full schemas and API specifications.
1.4 Dependencies
| Direction | Domain/Component | Purpose |
|---|---|---|
| Consumes | Auth/Cognito | User identity, role, session state |
| ClientConfiguration | Idle timeout, display settings | |
| Feature Flags | Infinite scrolling toggle state | |
| Pusher Events | Real-time notification updates | |
| Provides to | All Application Screens | Layout, navigation, shortcuts, modals |
2. Component Architecture
2.1 Component Diagram
2.2 Component Responsibilities
| Component | Layer | Responsibility | REQ Trace |
|---|---|---|---|
SpaController | Backend | Serves Vue.js SPA shell | All GLOBALUI, UI, KEYBOARD |
MaintenanceViewController | Backend | Returns maintenance page during deployment | REQ-GLOBALUI-001 |
FeaturesController | Backend | Manages feature toggle state | REQ-GLOBALUI-009 |
Feature | Backend Model | Stores feature flag state | REQ-GLOBALUI-009 |
AppLayout.vue | Frontend | Main application layout with header, sidebar, notifications | REQ-GLOBALUI-002 to 009 |
AppSidebar.vue | Frontend | Navigation sidebar with version display | REQ-GLOBALUI-002 |
UserRoleIndicator.vue | Frontend | Colored role badge with tooltip | REQ-GLOBALUI-008 |
Notifications.vue | Frontend | Notification bell and pagination | REQ-GLOBALUI-005 |
CountdownDialog.vue | Frontend | Idle timeout warning with countdown | REQ-GLOBALUI-004 |
PaginationToggle.vue | Frontend | Infinite scrolling toggle button | REQ-GLOBALUI-009 |
ModalDialog.vue | Frontend | Modal with Escape key dismiss | REQ-KEYBOARD-002 |
v-hotkey | Frontend Directive | Keyboard shortcut binding | REQ-KEYBOARD-001, 002 |
3. Data Design
3.1 Entities
This domain does not own persistent entities. It consumes read-only data from AUTH, CLIENTCFG, and FEATURES.
| Entity | Owner | Usage in GLOBALUI |
|---|---|---|
users | AUTH | Role, display_name, logged_in_site, visible_sites |
features | FEATURES | Feature toggle states |
client_configurations | CLIENTCFG | Idle timeout duration |
sites | SITE | Site filtering by Cognito group |
See Database Reference for full schema.
3.2 Data Structures
User Role Indicator Mapping (Frontend)
interface RoleIndicatorDetails {
roleIndicator: string; // 'SA', 'J', 'S', 'CA', 'M'
circleBackgroundColor: string; // Hex color code
toolTip: string; // Tooltip text
}
const roleIndicatorDetailsMap: Record<UserRole, RoleIndicatorDetails> = {
SUPER_ADMIN: { roleIndicator: 'SA', circleBackgroundColor: '#000000', toolTip: 'Super Admin user' },
JUNIOR: { roleIndicator: 'J', circleBackgroundColor: '#B7B0FF', toolTip: 'Junior user' },
SENIOR: { roleIndicator: 'S', circleBackgroundColor: '#49D1A0', toolTip: 'Senior user' },
CLIENT_ADMIN: { roleIndicator: 'CA', circleBackgroundColor: '#FAA07A', toolTip: 'Client Admin user' },
MANAGER: { roleIndicator: 'M', circleBackgroundColor: '#FF3A8D', toolTip: 'Manager user' },
};
Notification Pagination (API Response)
interface PaginatedNotifications {
data: Notification[];
total: number;
to: number;
skip: number;
take: number;
}
interface NotificationParams {
skip: number; // Offset for pagination
take: number; // Number to fetch (10, 20, 30, 50)
}
Keyboard Shortcut Binding
interface HotkeyBinding {
[key: string]: {
keyup?: () => void;
keydown?: () => void;
};
}
// Example: Modal Escape key binding
const hotkeyBinding: HotkeyBinding = {
escape: {
keyup: () => closeModal()
}
};
3.3 State Transitions
This domain is stateless. All operations are request-scoped.
Exception: Idle timeout tracking is managed in-memory by the IdleJs library.
4. Interface Design
4.1 APIs Consumed
| Endpoint | Method | Purpose | Response Fields Used |
|---|---|---|---|
/ | GET | SPA entry point | HTML shell |
/api/features | GET | Fetch feature flags | { code: { is_enabled } } |
/api/features/:id | PATCH | Toggle feature | { is_enabled: boolean } |
/api/paginate-notifications | GET | Paginated notifications | { data, total, to } |
/api/unread-notifications | GET | Unread count | { unread: number } |
/api/client-configuration-settings | GET | Client config | { idle_timeout, ... } |
4.2 APIs Provided
This domain does not provide APIs to other domains. It serves frontend components and consumes existing APIs.
4.3 Events
| Event | Direction | Payload | Purpose |
|---|---|---|---|
NotificationRead | Pusher → Frontend | {} | Refresh notification list |
OtherDeviceLogout | Pusher → Frontend | {} | Force page reload |
UserAccountDeleted | Pusher → Frontend | {} | Force logout with message |
UserAccountDisabled | Pusher → Frontend | {} | Force logout with message |
feature-toggled | EventBus | {} | Sync feature flags |
5. Behavioral Design
5.1 Idle Timeout Warning Flow
5.2 Site Filtering by Cognito Group
Algorithm: Filter Visible Sites
Inputs:
- user: User - The authenticated user
- all_sites: Site[] - All sites in the system
Outputs:
- visible_sites: Site[] - Sites the user can access
Steps:
1. If user.cognito_group IS NOT NULL:
Return all_sites (user sees everything)
2. Else:
Return all_sites WHERE site.requires_cognito_group = false
Notes:
- Cognito group presence grants universal site access
- Sites can be marked as requiring Cognito group for visibility
Decision Logic
| User Has Cognito Group | Site Requires Cognito | Site Visible |
|---|---|---|
| Yes | Yes | Yes |
| Yes | No | Yes |
| No | Yes | No |
| No | No | Yes |
Precedence: User group checked first; site requirement checked only for users without group. Default: If no match, site is hidden.
5.3 Keyboard Shortcut Resolution
Algorithm: Resolve Keyboard Shortcut
Inputs:
- key_event: KeyboardEvent - The key press event
- active_element: Element - Currently focused DOM element
- bound_shortcuts: Map<string, Action> - Registered shortcuts
Outputs:
- executed: boolean - Whether an action was triggered
Steps:
1. If active_element is text input (input, textarea, contenteditable):
Return false (pass key to text input)
2. If key_event.key NOT IN bound_shortcuts:
Return false (ignore unbound key)
3. If modal or widget is already open AND key != 'Escape':
Return false (block additional modals)
4. Execute bound_shortcuts[key_event.key]
5. Return true
Notes:
- Escape key always works, even with modal open (closes it)
- Single-letter shortcuts (no modifier) for efficiency
- v-hotkey directive handles binding lifecycle
5.4 Notification Pagination
6. Error Handling
| Condition | Detection | Response | User Impact |
|---|---|---|---|
| Maintenance mode active | Laravel middleware | Redirect to maintenance page | Cannot access application |
| Session expired | 401 response | Redirect to login with message | Must re-authenticate |
| Idle timeout | IdleJs callback | Show countdown, then logout | Warning before logout |
| Account deleted/disabled | Pusher event | Force logout with message | Immediate termination |
| Feature API timeout | Network error | Use cached state | Stale feature flags |
7. Configuration
| Setting | Location | Default | Effect |
|---|---|---|---|
idle_timeout | client_configurations | 30 (minutes) | Time before idle warning |
show_evaluation_warning | client_configurations | false | Display pre-production warning |
paginator_per_page | user.settings | 20 or 'All' | Infinite scroll on/off |
sidebar_pinned | user.settings | true | Sidebar collapse behavior |
color_scheme | user.settings | 'system' | Light/dark mode |
See Configuration Reference for details.
8. Implementation Mapping
8.1 Code Locations
| Component | Type | Path |
|---|---|---|
| SpaController | Controller | code/app/Http/Controllers/SpaController.php |
| MaintenanceViewController | Controller | code/app/Http/Controllers/MaintenanceViewController.php |
| FeaturesController | Controller | code/app/Http/Controllers/FeaturesController.php |
| Feature | Model | code/app/Feature.php |
| AppLayout | Layout | code/resources/frontend/src/layouts/AppLayout.vue |
| AppSidebar | Component | code/resources/frontend/src/components/AppSidebar.vue |
| UserRoleIndicator | Component | code/resources/frontend/src/components/users/UserRoleIndicator.vue |
| Notifications | Component | code/resources/frontend/src/components/app-notifications/Notifications.vue |
| CountdownDialog | Component | code/resources/frontend/src/components/CountdownDialog.vue |
| ModalDialog | Component | code/resources/frontend/src/components/ModalDialog.vue |
| PaginationToggle | Component | code/resources/frontend/src/components/common/PaginationToggle.vue |
| Settings | View | code/resources/frontend/src/views/Settings.vue |
| v-hotkey | Plugin | code/resources/frontend/src/plugins/index.js |
8.2 Requirement Traceability
| REQ ID | Design Section | Code Location |
|---|---|---|
| REQ-GLOBALUI-001 | §5 (maintenance flow) | MaintenanceViewController.php |
| REQ-GLOBALUI-002 | §2.2 | AppSidebar.vue (appVersion computed) |
| REQ-GLOBALUI-003 | §5.1 | AppLayout.vue (logout message), logout.ts |
| REQ-GLOBALUI-004 | §5.1 | AppLayout.vue (IdleJs), CountdownDialog.vue |
| REQ-GLOBALUI-005 | §5.4 | Notifications.vue, NotificationPane.vue |
| REQ-GLOBALUI-006 | §2.2 | AppLayout.vue (user.display_name) |
| REQ-GLOBALUI-007 | §5.2 | AppLayout.vue (visibleSites), Site queries |
| REQ-GLOBALUI-008 | §3.2 | UserRoleIndicator.vue |
| REQ-GLOBALUI-009 | §2.2 | PaginationToggle.vue, FeaturesController.php |
| REQ-UI-001 | §2 | Responsive CSS in all Vue components |
| REQ-KEYBOARD-001 | §5.3 | v-hotkey directive usage across views |
| REQ-KEYBOARD-002 | §5.3 | ModalDialog.vue, CountdownDialog.vue (escape binding) |
9. Design Decisions
| Decision | Rationale | Alternatives Considered |
|---|---|---|
| Frontend-heavy implementation | Most requirements are UI concerns; keeps backend minimal | Backend rendering (rejected: slower, less interactive) |
| IdleJs library for idle detection | Well-tested, configurable, handles edge cases | Custom implementation (rejected: reinventing wheel) |
| v-hotkey directive for shortcuts | Declarative binding, component lifecycle management | Global event listener (rejected: harder to manage) |
| Single-letter shortcuts | Efficiency for power users, industry standard | Modifier keys (rejected: slower, but available as fallback) |
| Role indicator in header | Always visible, consistent location | Profile menu only (rejected: less discoverable) |
| Infinite scroll as user preference | Different users have different workflows | System-wide setting (rejected: inflexible) |
10. Related Documents
| Document | Relevant Sections |
|---|---|
| SRS: globalui.md | GLOBALUI requirements source |
| SRS: ui.md | UI requirements source |
| SRS: keyboard.md | KEYBOARD requirements source |
| SDS: Architecture | SPA architecture, Vue.js patterns |
| SDS: Security | Cognito authentication, session management |
| SDS: NOTIF Domain | Notification indicator subsystem |
| SDS: USERMGMT Domain | User role management |