UNPKG

@memberjunction/ng-shared

Version:

MemberJunction: MJ Explorer Angular Shared Package - utility functions and other reusable elements used across other MJ Angular packages within the MJ Explorer App - do not use outside of MJ Explorer.

209 lines 7.01 kB
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; import { RunView } from '@memberjunction/core'; import { UserInfoEngine } from '@memberjunction/core-entities'; import * as i0 from "@angular/core"; /** * Setting key for developer mode in MJ: User Settings entity */ const DEVELOPER_MODE_SETTING_KEY = 'Explorer.DeveloperMode'; /** * Service to manage Developer Mode functionality across Explorer apps. * * Developer Mode shows additional debugging tools and developer-focused * features in the UI. Only users with Developer, Admin, or System Administrator * roles can enable developer mode. * * Settings are persisted using the MJ: User Settings entity via UserInfoEngine. * * Usage: * ```typescript * constructor(private devMode: DeveloperModeService) {} * * async ngOnInit() { * await this.devMode.Initialize(userEntity); * * // Subscribe to changes * this.devMode.IsEnabled$.subscribe(enabled => { * this.showDevTools = enabled; * }); * } * ``` */ export class DeveloperModeService { _isEnabled$ = new BehaviorSubject(false); _isDeveloper$ = new BehaviorSubject(false); _initialized = false; _currentUser = null; // Role names that qualify as "developer" static DEVELOPER_ROLES = [ 'Developer', 'Admin', 'System Administrator', 'Integration' ]; /** * Observable for developer mode enabled state. * Emits whenever developer mode is toggled. */ get IsEnabled$() { return this._isEnabled$.asObservable(); } /** * Observable for whether user has developer role. * This determines if they CAN enable developer mode. */ get IsDeveloper$() { return this._isDeveloper$.asObservable(); } /** * Current enabled state (synchronous access) */ get IsEnabled() { return this._isEnabled$.value; } /** * Whether user has developer role (synchronous access) */ get IsDeveloper() { return this._isDeveloper$.value; } /** * Whether the service has been initialized */ get IsInitialized() { return this._initialized; } /** * Initialize service with current user. * Call this after login/authentication completes. */ async Initialize(user) { if (this._initialized) { return; } this._currentUser = user; // Check if user has a developer role const hasDeveloperRole = await this.CheckDeveloperRole(user); this._isDeveloper$.next(hasDeveloperRole); // Load saved preference from User Settings (only if user is a developer) if (hasDeveloperRole) { const savedState = await this.LoadSetting(); this._isEnabled$.next(savedState); } else { // Non-developers always have dev mode disabled this._isEnabled$.next(false); } this._initialized = true; } /** * Toggle developer mode on/off. * Only works if user has developer role. * @returns The new state, or false if user cannot enable dev mode */ async Toggle() { if (!this.IsDeveloper) { console.warn('Developer mode not available - user does not have Developer role'); return false; } const newState = !this.IsEnabled; this._isEnabled$.next(newState); await this.SaveSetting(newState); return newState; } /** * Enable developer mode (if user has developer role) */ async Enable() { if (this.IsDeveloper) { this._isEnabled$.next(true); await this.SaveSetting(true); } } /** * Disable developer mode */ async Disable() { this._isEnabled$.next(false); await this.SaveSetting(false); } /** * Reset the service (e.g., on logout) */ Reset() { this._isEnabled$.next(false); this._isDeveloper$.next(false); this._initialized = false; this._currentUser = null; } /** * Load the developer mode setting from User Settings entity */ async LoadSetting() { try { const engine = UserInfoEngine.Instance; const settingValue = engine.GetSetting(DEVELOPER_MODE_SETTING_KEY); return settingValue === 'true'; } catch (error) { console.warn('Failed to load developer mode setting:', error); return false; } } /** * Save the developer mode setting to User Settings entity */ async SaveSetting(enabled) { try { const engine = UserInfoEngine.Instance; await engine.SetSetting(DEVELOPER_MODE_SETTING_KEY, String(enabled)); } catch (error) { console.warn('Failed to save developer mode setting:', error); } } /** * Check if user has a developer role by querying User Roles entity */ async CheckDeveloperRole(user) { try { const rv = new RunView(); // Get user's roles via the User Roles junction table const userRolesResult = await rv.RunView({ EntityName: 'User Roles', ExtraFilter: `UserID='${user.ID}'`, ResultType: 'simple', Fields: ['RoleID'] }); if (!userRolesResult.Success || !userRolesResult.Results?.length) { return false; } const roleIds = userRolesResult.Results.map(ur => ur.RoleID); // Get the role names const rolesResult = await rv.RunView({ EntityName: 'Roles', ExtraFilter: `ID IN (${roleIds.map(id => `'${id}'`).join(',')})`, ResultType: 'simple', Fields: ['Name'] }); if (!rolesResult.Success || !rolesResult.Results?.length) { return false; } // Check if any role matches our developer roles (case-insensitive) const userRoleNames = rolesResult.Results.map(r => r.Name.toLowerCase()); return DeveloperModeService.DEVELOPER_ROLES.some(devRole => userRoleNames.includes(devRole.toLowerCase())); } catch (error) { console.error('Error checking developer role:', error); return false; } } static ɵfac = function DeveloperModeService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || DeveloperModeService)(); }; static ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: DeveloperModeService, factory: DeveloperModeService.ɵfac, providedIn: 'root' }); } (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(DeveloperModeService, [{ type: Injectable, args: [{ providedIn: 'root' }] }], null, null); })(); //# sourceMappingURL=developer-mode.service.js.map