myowjaYOY/ngx-admin
April 19, 2026
April 2026
This document is organized to serve multiple audiences. Use the following guide to navigate to the sections most relevant to your role.
| Stakeholder | Recommended Sections |
|---|---|
| Executives and project managers | Section 4: Executive Summary, Section 5: Stakeholders & Concerns, Section 13: Quality Attributes, Section 14: Risks & Technical Debt |
| Developers joining the team | Section 4: Executive Summary, Section 7: Solution Strategy, Section 8: Building Block View, Section 9: Runtime View, Section 10: Data Flow & State Management, Section 15: Glossary |
| Frontend engineers working on features | Section 8: Building Block View, Section 9: Runtime View, Section 10: Data Flow & State Management, Section 11: Cross-Cutting Concerns, Section 12: Architecture Decisions |
| Architects evaluating the system | All sections |
| QA engineers and testers | Section 9: Runtime View, Section 11: Cross-Cutting Concerns, Section 13: Quality Attributes, Section 14: Risks & Technical Debt |
| Security reviewers | Section 11: Cross-Cutting Concerns, Section 12: Architecture Decisions, Section 14: Risks & Technical Debt |
ngx-admin is a feature-rich Angular-based administrative dashboard application built on the Nebular UI component library. The application serves as both a production-ready admin panel template and a comprehensive component showcase, providing end users with dashboards for IoT/smart-home monitoring, e-commerce analytics, data visualization, form management, map exploration, and rich-text editing. Its primary users are developers who adopt it as a starting point for building Angular admin interfaces, as well as end users of applications built on top of it.
The application is structured as a single-page application (SPA) using Angular 15 with a module-based architecture. Navigation is managed entirely by the Angular Router, with feature sections organized into route groups (/dashboard, /e-commerce, /forms, /tables, /charts, /maps, /extra-components, /modal-overlays, /ui-features, /editors, /miscellaneous). The Nebular UI framework (@nebular/theme) provides the design system, theming engine, layout components, and overlay services. Data visualization is handled by a combination of Apache ECharts (via ngx-echarts), Chart.js, D3.js, and @swimlane/ngx-charts. Interactive maps are powered by Leaflet (via @asymmetrik/ngx-leaflet) and the Angular Google Maps integration.
The most significant architectural characteristic of ngx-admin is its abstract service layer: all data-fetching contracts are defined as Angular abstract classes, with concrete implementations injected via the Angular dependency injection system. This pattern cleanly separates the UI from the data source, allowing the demo application to use in-memory mock services while enabling production adopters to substitute real HTTP-backed implementations. A second defining characteristic is the Nebular theming system, which drives not only UI component appearance but also chart colors, map styles, and responsive breakpoint behavior — all components subscribe to NbThemeService to remain synchronized with the active theme.
This Architecture Overview covers 100 screens of the ngx-admin application. The screens assessed and their routes are:
Editors (/editors), Contacts (/dashboard/contacts), Electricity (/dashboard/electricity), Kitten (/dashboard/kitten), Rooms (/dashboard/rooms), Traffic (/dashboard/traffic), Country Orders (/e-commerce/country-orders), Chart (/e-commerce/country-orders/chart), Back Side (/e-commerce/traffic-reveal-card/back-side), Map (/e-commerce/country-orders/map), Progress Section (/e-commerce/progress-section), Traffic Reveal Card (/e-commerce/traffic-reveal-card), Legend Chart (/e-commerce/legend-chart), Front Side (/e-commerce/profit-card/front-side), Traffic Cards Header (/e-commerce/traffic-reveal-card/traffic-cards-header), User Activity (/e-commerce/user-activity), Calendar Kit (/extra-components/calendar-kit), Chat (/extra-components/chat), Progress Bar (/extra-components/progress-bar), Form Inputs (/extra-components/form-inputs), Day Cell (/extra-components/calendar/day-cell), Month Cell (/extra-components/calendar-kit/month-cell), Nebular Select (/extra-components/form-inputs/nebular-select), Extra Components (/extra-components), Alert (/extra-components/alert), Visitors Analytics (/e-commerce/visitors-analytics), Spinner In Buttons (/extra-components/spinner/spinner-in-buttons), Maps (/maps), Spinner Color (/extra-components/spinner/spinner-color), Leaflet (/maps/leaflet), Pages (/pages), Tables (/tables), Dashboard (/dashboard), Icons (/ui-features/icons), E Commerce (/e-commerce), Footer (/@theme/components/footer), Chart Panel Header (/e-commerce/charts-panel/chart-panel-header), Spinner (/extra-components/spinner), Chart Panel Summary (/e-commerce/charts-panel/chart-panel-summary), Player (/dashboard/rooms/player), Header (/@theme/components/header), Calendar (/extra-components/calendar), Form Layouts (/forms/form-layouts), Window Form (/modal-overlays/window/window-form), Room Selector (/dashboard/rooms/room-selector), Ui Features (/ui-features), Traffic Bar (/e-commerce/traffic-reveal-card/front-side/traffic-bar), Spinner In Tabs (/extra-components/spinner/spinner-in-tabs), Interactive Progress Bar (/extra-components/progress-bar/interactive-progress-bar), Datepicker (/forms/datepicker), Form Inputs (/forms/form-inputs), Charts (/e-commerce/charts-panel/charts), Bubble (/maps/bubble), Profit Card (/e-commerce/profit-card), Slide Out (/e-commerce/slide-out), Back Side (/e-commerce/profit-card/back-side), Smart Table (/tables/smart-table), Typography (/ui-features/typography), Modal Overlays (/modal-overlays), Visitors Statistics (/e-commerce/visitors-analytics/visitors-statistics), Ckeditor (/editors/ckeditor), Grid (/ui-features/grid), Echarts (/charts/echarts), Not Found (/miscellaneous/not-found), Visitors Analytics Chart (/e-commerce/visitors-analytics/visitors-analytics-chart), Tiny Mce (/editors/tiny-mce), Front Side (/e-commerce/earning-card/front-side), Electricity Chart (/dashboard/electricity/electricity-chart), Search Fields (/ui-features/search-fields), Dialog Name Prompt (/modal-overlays/dialog/dialog-name-prompt), Tooltip (/modal-overlays/tooltip), Search Map (/maps/search-map), Map (/maps/search-map/map), Window (/modal-overlays/window), Dialog (/modal-overlays/dialog), Miscellaneous (/miscellaneous), Gmaps (/maps/gmaps), Popovers (/modal-overlays/popovers), Search (/maps/search-map/search), Tree Grid (/tables/tree-grid), Showcase Dialog (/modal-overlays/dialog/showcase-dialog), Toastr (/modal-overlays/toastr), Search Input (/@theme/components/search-input), Tiny Mce (/@theme/components/tiny-mce), Status Card (/dashboard/status-card), Front Side (/e-commerce/traffic-reveal-card/front-side), Earning Card (/e-commerce/earning-card), Solar (/dashboard/solar), Security Cameras (/dashboard/security-cameras), Temperature Dragger (/dashboard/temperature/temperature-dragger), Charts (/charts), Chartjs (/charts/chartjs), Temperature (/dashboard/temperature), D3 (/charts/d3), Back Side (/e-commerce/earning-card/back-side), Charts Panel (/e-commerce/charts-panel), Forms (/forms), Weather (/dashboard/weather), Buttons (/forms/buttons), Spinner Sizes (/extra-components/spinner/spinner-sizes).
Components, patterns, and features not included in the assessed documentation are outside the scope of this document.
Generated by DocAgent — automated codebase documentation analysis. Subject matter expert review is recommended before distribution.
| Stakeholder | Role | Key Concerns |
|---|---|---|
| End Users | Operators of dashboards built on ngx-admin | Performance, usability, visual consistency across themes, data accuracy |
| Frontend Developers | Engineers building features on top of the template | Code maintainability, clear patterns, ease of adding new screens and data sources |
| Architects / Tech Leads | Evaluators and maintainers of the overall system design | Separation of concerns, scalability of the abstract service pattern, dependency management |
| QA Engineers | Testers validating functionality and regressions | Predictable state transitions, error handling coverage, testability of components |
| Security Reviewers | Auditors of the application's security posture | Authentication enforcement, XSS prevention, safe handling of user-generated content |
| Project Managers | Stakeholders tracking delivery and risk | Technical debt, dependency currency, risk areas |
The following quality goals are derived from patterns consistently observed across the 100 assessed screens:
NbThemeService, ensuring that theme changes propagate uniformly across charts, maps, UI components, and layout elements.NbMediaBreakpointsService, ensuring the UI adapts to different viewport sizes.The ngx-admin application is a client-side Angular SPA. Everything inside the system boundary is JavaScript/TypeScript code running in the user's browser. The system boundary encompasses the Angular application bundle, the Nebular UI framework, all charting libraries, and the Angular Router. Outside the boundary are: the backend API services that concrete *Data service implementations would call (not included in the assessed code), external CDNs for editor libraries, external tile servers for maps, and the Google Maps Platform.
[Diagram: System Context — show the ngx-admin Angular SPA as a central box; connect it to: Backend API (outbound, HTTPS/REST, data for dashboards), OpenStreetMap Tile Server (outbound, HTTPS, map tiles), Google Maps Platform (outbound, HTTPS/JS SDK, geocoding and map rendering), Spotify CDN (outbound, HTTPS, audio preview files), CKEditor CDN (outbound, HTTPS, editor script), TinyMCE Assets (local static, HTTP, editor skin/plugins), External Media CDNs (outbound, HTTPS, chat demo images and GIFs)]
| External System | Direction | Protocol | Purpose |
|---|---|---|---|
| Backend API (abstract — concrete implementation not provided) | Outbound | HTTPS/REST (inferred from HttpClient usage in map service) |
Provides data for all dashboard widgets, e-commerce analytics, and table content via concrete *Data service implementations |
OpenStreetMap Tile Server ({s}.tile.openstreetmap.org) |
Outbound | HTTP (currently; should be HTTPS) | Renders map tiles for the Leaflet map screen |
GeoJSON Asset (assets/leaflet-countries/countries.geo.json) |
Internal static | HTTP GET | Provides world country polygon data for the Country Orders map |
World Map Asset (assets/map/world.json) |
Internal static | HTTP GET | Provides world GeoJSON for the Bubble map ECharts visualization |
| Google Maps Platform | Outbound | HTTPS/JS SDK | Renders the Google Maps screen and provides Places Autocomplete for the Search Map |
Spotify CDN (p.scdn.co) |
Outbound | HTTPS | Streams audio preview files for the Rooms/Player widget |
CKEditor CDN (cdn.ckeditor.com) |
Outbound | HTTPS | Loads the CKEditor 4 rich-text editor library |
TinyMCE Skin Assets (assets/skins/lightgray) |
Internal static | HTTP GET | Provides the TinyMCE editor skin CSS and assets |
| External Media CDNs (Gifer, Tenor, Picsum, etc.) | Outbound | HTTPS | Provides demo images and GIFs for the Chat screen bot replies |
Akveo Attribution Link (akveo.page.link) |
Outbound | HTTPS | Firebase Dynamic Link in the Footer component |
The following technology choices are directly evidenced in the package.json manifest and the assessed screen documentation.
| Layer | Technology | Version | Notes |
|---|---|---|---|
| Framework | Angular | 15.2.x | Module-based architecture; Angular Router for navigation |
| Language | TypeScript | ~4.9.5 | Compiled to ES2022 target |
| UI Component Library | @nebular/theme |
11.0.1 | Primary design system; provides layout, theming, overlays, calendar, chat, smart-table wrappers |
| Nebular Auth | @nebular/auth |
11.0.1 | Authentication module (route guards expected but not directly observed in assessed screens) |
| Nebular Security | @nebular/security |
11.0.1 | Role-based access control module |
| Charting — ECharts | echarts + ngx-echarts |
4.9.0 / 4.2.2 | Primary charting library for complex visualizations (line, bar, pie, scatter, geo) |
| Charting — Chart.js | chart.js + angular2-chartjs |
2.7.1 / 0.4.1 | Secondary charting library |
| Charting — D3 | (D3 library, inferred from route) | [Not documented — WHO: Frontend lead; WHAT: Which D3 version and wrapper is used for the /charts/d3 screen; WHERE: Section 7.1 Technology Stack table, D3 row] |
Used for D3 chart screen |
| Charting — ngx-charts | @swimlane/ngx-charts |
^14.0.0 | Additional charting option |
| Maps — Leaflet | leaflet + @asymmetrik/ngx-leaflet |
1.2.0 / 3.0.1 | Interactive geographic maps |
| Maps — Google Maps | @angular/google-maps |
^12.2.13 | Google Maps integration |
| Rich Text — CKEditor | ckeditor + ng2-ckeditor |
4.7.3 / ~1.2.9 | CKEditor 4 WYSIWYG editor |
| Rich Text — TinyMCE | tinymce |
4.5.7 | TinyMCE WYSIWYG editor (loaded via global script) |
| Data Grid | ng2-smart-table |
^1.6.0 | Smart table with inline CRUD |
| Reactive Programming | rxjs |
6.6.2 | Observable-based async data management throughout |
| CSS Preprocessor | SCSS (node-sass) | ^4.14.1 | Component-scoped stylesheets |
| Linting | ESLint + @angular-eslint |
15.2.1 | Enforces ngx prefix for components and directives |
| Testing | Karma + Jasmine | ~6.3.19 / ~3.6.0 | Unit and integration testing |
| E2E Testing | Protractor | ~7.0.0 | End-to-end testing |
| Documentation | Compodoc | 1.0.1 | API documentation generation |
The application is organized as an Angular module-based SPA with a hierarchical route structure. The top-level PagesComponent acts as the authenticated shell, rendering the sidebar navigation (nb-menu) and a <router-outlet> for feature modules. Feature sections are organized as route groups, each with a shell component that contains only a <router-outlet>:
/pages
/dashboard → DashboardComponent (shell) → child widgets
/e-commerce → ECommerceComponent (shell) → child widgets
/forms → FormsComponent (shell) → child screens
/tables → TablesComponent (shell) → child screens
/charts → ChartsComponent (shell) → child screens
/maps → MapsComponent (shell) → child screens
/extra-components → ExtraComponentsComponent (shell) → child screens
/modal-overlays → ModalOverlaysComponent (shell) → child screens
/ui-features → UiFeaturesComponent (shell) → child screens
/editors → EditorsComponent (shell) → child screens
/miscellaneous → MiscellaneousComponent (shell) → child screens
The @theme directory contains globally shared layout components (Header, Footer, Search Input, TinyMCE wrapper) that are part of the application shell rather than any specific feature route.
Abstract Service / Dependency Injection for Data — All data-fetching contracts are defined as Angular abstract classes (e.g., UserData, ElectricityData, CountryOrderData). Components depend on the abstract class; concrete implementations are registered in Angular modules. This is the primary data access pattern across all 100 assessed screens.
Router Shell Components — Feature sections use empty shell components (containing only <router-outlet>) to define route namespaces without adding any UI or logic overhead. Observed in: EditorsComponent, ExtraComponentsComponent, MapsComponent, TablesComponent, ChartsComponent, FormsComponent, ModalOverlaysComponent, UiFeaturesComponent, MiscellaneousComponent.
Theme-Reactive Components — Components subscribe to NbThemeService.getJsTheme() or NbThemeService.onThemeChange() to receive theme variables and update their visual state reactively. This pattern is applied to all chart components, the Dashboard, the Header, the Room Selector, and many widget components.
Presentational / Container Component Split — Data-fetching logic is concentrated in container components (e.g., CountryOrdersComponent, VisitorsAnalyticsComponent), while child components (e.g., CountryOrdersChartComponent, VisitorsStatisticsComponent) receive data via @Input() and emit events via @Output().
ECharts Partial Update Pattern — Chart components initialize the full ECharts options object on first load, then use echartsInstance.setOption() with only changed properties on subsequent data updates, avoiding full chart re-initialization.
forkJoin for Parallel Data Fetching — Multiple data sources required simultaneously are fetched in parallel using RxJS forkJoin, preventing partial renders. Observed in: ContactsComponent, ElectricityComponent, VisitorsAnalyticsComponent, TemperatureComponent, ChartsPanelComponent.
| Quality Goal | Architectural Approach |
|---|---|
| Maintainability | Abstract service classes decouple UI from data source; Nebular theming centralizes visual configuration; ESLint enforces naming conventions |
| Extensibility | Angular DI allows new concrete service implementations without modifying components; router shell pattern allows new child routes without modifying parent components |
| Visual Consistency | All components subscribe to NbThemeService; chart colors, map styles, and UI component variants are all driven by the same theme variable namespace |
| Responsiveness | NbMediaBreakpointsService provides a shared breakpoint map; components subscribe to NbThemeService.onMediaQueryChange() for reactive layout adjustments |
| Subscription Lifecycle Correctness | takeWhile(() => this.alive) pattern is used consistently (though with known limitations — see Section 14); takeUntil(destroy$) is used in some newer components (e.g., SecurityCamerasComponent) |
[Diagram: Building Block View — show the following containers: Angular SPA (browser), with internal components: Pages Shell, Feature Modules (Dashboard, E-Commerce, Forms, Tables, Charts, Maps, Extra Components, Modal Overlays, UI Features, Editors, Miscellaneous), @theme Shell Components (Header, Footer, Search Input, TinyMCE), Core Data Services (abstract classes), Nebular UI Framework, ECharts/ngx-echarts, Leaflet/ngx-leaflet, Google Maps. Show dependency arrows from Feature Modules to Core Data Services, from all components to Nebular UI Framework, from chart components to ECharts, from map components to Leaflet and Google Maps.]
| Container | Responsibility | Technology |
|---|---|---|
| Angular SPA (Browser) | Entire client-side application; routing, rendering, state management | Angular 15, TypeScript, SCSS |
| Pages Shell | Authenticated application shell; renders sidebar navigation and top-level router outlet | PagesComponent, NbMenuComponent, ngx-one-column-layout |
| Feature Modules | Route-grouped feature areas (Dashboard, E-Commerce, Forms, Tables, Charts, Maps, Extra Components, Modal Overlays, UI Features, Editors, Miscellaneous) | Angular feature modules, each with a shell component and child route components |
| @theme Shell Components | Globally shared layout components not tied to a specific route | HeaderComponent, FooterComponent, SearchInputComponent, TinyMceComponent |
| Core Data Services | Abstract class contracts for all data fetching; concrete implementations injected via Angular DI | Angular abstract classes in src/app/@core/data/ |
| Core Utility Services | Shared application utilities | LayoutService (layout resize events), AnalyticsService |
| Nebular UI Framework | Design system, theming engine, UI components, overlay services | @nebular/theme 11.0.1 |
| ECharts Visualization | Complex chart rendering (line, bar, pie, scatter, geo) | echarts 4.9.0, ngx-echarts 4.2.2 |
| Leaflet Maps | Interactive geographic map rendering | leaflet 1.2.0, @asymmetrik/ngx-leaflet 3.0.1 |
| Google Maps | Google Maps rendering and Places Autocomplete | @angular/google-maps 12.2.13 |
| Rich Text Editors | WYSIWYG editing | CKEditor 4 (CDN), TinyMCE 4.5.7 (local assets) |
/dashboard)| Component | Responsibility |
|---|---|
DashboardComponent |
Container; fetches solar data, resolves theme-based card configurations, renders status cards and solar widget |
StatusCardComponent |
Presentational; renders a single ON/OFF toggleable device status card with icon transclusion |
SolarComponent |
Presentational; renders a donut ECharts chart for solar energy consumption; receives chartValue via @Input() |
ElectricityComponent |
Container; fetches electricity list and chart data in parallel via forkJoin; manages time period selection |
ElectricityChartComponent |
Presentational; renders a dual-series smooth line ECharts chart; receives data via @Input() |
RoomsComponent |
Container; manages room selection state, player expand/collapse, responsive breakpoint, and dark theme detection |
RoomSelectorComponent |
Presentational; renders an SVG floor plan with interactive room areas; emits selectEvent on room click |
PlayerComponent |
Presentational; manages a native HTMLAudioElement for audio playback; uses PlayerService for static playlist |
ContactsComponent |
Container; fetches contacts and recent users in parallel via forkJoin |
TrafficComponent |
Container; fetches traffic chart data; renders ngx-traffic-chart child |
TemperatureComponent |
Container; fetches temperature and humidity data in parallel via forkJoin |
TemperatureDraggerComponent |
Interactive SVG widget; renders a custom arc-based drag slider for temperature/humidity control |
SecurityCamerasComponent |
Container; fetches camera list; manages single/grid view toggle and responsive action size |
WeatherComponent |
Shell (empty class body; template not assessed) |
/e-commerce)| Component | Responsibility |
|---|---|
ECommerceComponent |
Shell (empty class body; template not assessed) |
CountryOrdersComponent |
Container; fetches category labels and per-country order data; manages map selection and responsive card sizing |
CountryOrdersChartComponent |
Presentational ECharts bar chart; receives data, labels, maxValue, countryName via @Input() |
CountryOrdersMapComponent |
Interactive Leaflet map; fetches GeoJSON from static asset; renders country polygons with selection/hover states |
ECommerceChartsPanelComponent |
Container; fetches orders chart, profit chart, and summary data; manages period selection and tab switching |
OrdersChartComponent |
Presentational ECharts multi-line area chart; receives ordersChartData via @Input() |
ProfitChartComponent |
Presentational ECharts grouped bar chart; receives profitChartData via @Input() |
ChartPanelHeaderComponent |
Presentational; renders period selector and chart legend; emits periodChange via @Output() |
ChartPanelSummaryComponent |
Presentational; renders a list of {title, value} summary items via @Input() |
TrafficRevealCardComponent |
Container; manages front/back card flip and period-based traffic data fetching |
TrafficFrontCardComponent |
Presentational; renders traffic list data (date, value, delta, comparison) via @Input() |
TrafficBarChartComponent |
Presentational ECharts bar chart; receives data, labels, formatter via @Input() |
TrafficBarComponent |
Leaf presentational; renders a single traffic bar comparison row via @Input() |
TrafficCardsHeaderComponent |
Presentational; renders period toggle controls; emits periodChange via @Output() |
ECommerceVisitorsAnalyticsComponent |
Container; fetches inner line, outer line, and pie chart data in parallel via forkJoin |
VisitorsAnalyticsChartComponent |
Presentational ECharts dual-line area chart; receives chartData via @Input() |
VisitorsStatisticsComponent |
Presentational ECharts concentric donut chart; receives value via @Input() |
ECommerceLegendChartComponent |
Leaf presentational; renders a color-coded legend from legendItems @Input() |
ProgressSectionComponent |
Container; fetches progress info data; renders progress bars |
ProfitCardComponent |
Container; manages front/back card flip state |
StatsCardFrontComponent |
Presentational; renders animated bar chart from ProfitBarAnimationChartData |
StatsCardBackComponent |
Presentational; renders bar chart from StatsBarData |
EarningCardComponent |
Container; manages front/back card flip state |
EarningCardFrontComponent |
Presentational ECharts live-update line chart; receives liveUpdateChartData via @Input() |
EarningCardBackComponent |
Presentational ECharts pie chart; receives values and defaultSelectedCurrency via @Input() |
SlideOutComponent |
Container; manages visitors statistics panel visibility toggle |
UserActivityComponent |
Container; fetches user activity data by period |
/maps)| Component | Responsibility |
|---|---|
MapsComponent |
Shell (router outlet only) |
LeafletComponent |
Presentational; renders a static OpenStreetMap Leaflet map centered on a hardcoded coordinate |
BubbleMapComponent |
Container; fetches world GeoJSON and theme config; renders ECharts geo scatter (bubble) map |
SearchMapComponent |
Container; manages searched position state; coordinates SearchComponent and MapComponent |
SearchComponent |
Interactive; integrates Google Maps Places Autocomplete; emits PositionModel via @Output() |
MapComponent |
Presentational; renders a map centered on searchedPosition @Input(); uses browser Geolocation API on init |
GmapsComponent |
Presentational; renders a Google Maps instance centered on a hardcoded coordinate |
/modal-overlays)| Component | Responsibility |
|---|---|
ModalOverlaysComponent |
Shell (router outlet only) |
DialogComponent |
Container; demonstrates NbDialogService with component dialogs, template dialogs, and return-value handling |
ShowcaseDialogComponent |
Dialog content; receives title via @Input(); closes via NbDialogRef |
DialogNamePromptComponent |
Dialog content; collects a name string; returns it via NbDialogRef.close(name) |
WindowComponent |
Container; demonstrates NbWindowService with template and component windows |
WindowFormComponent |
Window content; renders a two-field form; closes via NbWindowRef |
ToastrComponent |
Container; demonstrates NbToastrService with configurable toast notifications |
PopoversComponent |
Container; demonstrates NbPopover directive with component and template content |
TooltipComponent |
Shell (empty class body; template not assessed) |
| Component | Responsibility |
|---|---|
HeaderComponent |
Application header; manages theme switching, sidebar toggle, responsive user display, and user menu |
FooterComponent |
Application footer; renders static attribution and social links |
SearchInputComponent |
Collapsible search input; emits search string via @Output() on each keystroke |
TinyMceComponent |
TinyMCE editor wrapper; initializes editor on host element; emits content via @Output() on keyup |
| Building Block | Type | Used By | Responsibility |
|---|---|---|---|
NbThemeService |
Nebular Service | Dashboard, E-Commerce widgets, Charts, Maps, Header, Room Selector, Typography, Chart Panel Header, all chart components | Provides reactive theme variables and media query breakpoint change events |
NbMediaBreakpointsService |
Nebular Service | RoomsComponent, CountryOrdersComponent, SecurityCamerasComponent, TypographyComponent, HeaderComponent, ChartPanelHeaderComponent | Provides the static breakpoints map for responsive layout decisions |
LayoutService |
Internal Utility Service | All ECharts chart components (OrdersChart, ProfitChart, ElectricityChart, VisitorsAnalyticsChart, EarningCardFront, VisitorsStatistics, CountryOrdersChart, TrafficBarChart) | Broadcasts debounced layout size change events for chart resize |
UserData (abstract) |
Core Data Service | ContactsComponent, HeaderComponent | Provides user contacts and current user data |
ElectricityData (abstract) |
Core Data Service | ElectricityComponent, ElectricityChartComponent (indirectly) | Provides electricity list and chart data |
CountryOrderData (abstract) |
Core Data Service | CountryOrdersComponent | Provides country order categories and per-country data |
CountryOrdersMapService |
Concrete Service | CountryOrdersMapComponent | Fetches GeoJSON from assets/leaflet-countries/countries.geo.json via HttpClient |
TrafficChartData (abstract) |
Core Data Service | TrafficComponent | Provides traffic chart numeric data |
TrafficListData (abstract) |
Core Data Service | TrafficRevealCardComponent, TrafficFrontCardComponent | Provides traffic list data by period |
TrafficBarData (abstract) |
Core Data Service | TrafficRevealCardComponent | Provides traffic bar chart data by period |
VisitorsAnalyticsData (abstract) |
Core Data Service | ECommerceVisitorsAnalyticsComponent | Provides inner line, outer line, and pie chart data |
OrdersProfitChartData (abstract) |
Core Data Service | ECommerceChartsPanelComponent | Provides orders chart, profit chart, and summary data |
StatsProgressBarData (abstract) |
Core Data Service | ProgressSectionComponent | Provides progress info data |
StatsBarData (abstract) |
Core Data Service | StatsCardBackComponent | Provides bar chart numeric data |
ProfitBarAnimationChartData (abstract) |
Core Data Service | StatsCardFrontComponent | Provides animated profit bar chart data |
SolarData (abstract) |
Core Data Service | DashboardComponent | Provides solar energy numeric stream |
TemperatureHumidityData (abstract) |
Core Data Service | TemperatureComponent | Provides temperature and humidity data |
SecurityCamerasData (abstract) |
Core Data Service | SecurityCamerasComponent | Provides camera list data |
UserActivityData (abstract) |
Core Data Service | UserActivityComponent | Provides user activity data by period |
SmartTableData (abstract) |
Core Data Service | SmartTableComponent | Provides smart table row data |
PlayerService |
Internal Service | PlayerComponent | Provides static in-memory playlist and random track selection |
ChatService |
Internal Service | ChatComponent | Provides static message loading and bot reply matching |
NbDialogService |
Nebular Service | DialogComponent | Opens dialog overlays with component or template content |
NbWindowService |
Nebular Service | WindowComponent | Opens window overlays with component or template content |
NbToastrService |
Nebular Service | ToastrComponent | Renders configurable toast notifications |
NbMenuService |
Nebular Service | NotFoundComponent, HeaderComponent | Provides home navigation |
NbSidebarService |
Nebular Service | HeaderComponent | Controls sidebar open/close state |
NbIconLibraries |
Nebular Service | IconsComponent | Provides icon pack registration and retrieval |
NbDateService |
Nebular Service | CalendarComponent, CalendarKitMonthCellComponent, DatepickerComponent | Provides date arithmetic utilities |
Participants: Angular Router, Feature Shell Component, Container Component, Abstract Data Service, Concrete Data Service, NbThemeService, Template
Sequence:
/dashboard/electricity).ElectricityComponent.ElectricityData (concrete implementation) and NbThemeService into the component constructor.forkJoin([electricityService.getListData(), electricityService.getChartData()]).takeWhile(() => this.alive).NbThemeService.getJsTheme() is subscribed to; the current theme name is assigned to currentTheme.forkJoin source observables complete, the subscriber fires: listData and chartData are assigned to component properties.ElectricityChartComponent) receive data via @Input() bindings and render their visualizations.Error path: If either observable in the forkJoin errors, the entire forkJoin terminates without emitting. No error callback is registered in the component; listData and chartData remain undefined. The template renders with empty/undefined bindings, likely showing a blank or broken UI with no user-facing error message.
[Diagram: Sequence — Page Load and Data Hydration: User → Router → ElectricityComponent constructor → forkJoin(getListData, getChartData) → Concrete Service → (data returned) → component properties assigned → change detection → template re-renders → ElectricityChartComponent receives @Input]
Participants: CountryOrdersMapComponent, CountryOrdersComponent, CountryOrderData (abstract service), CountryOrdersChartComponent
Sequence:
CountryOrdersMapComponent.click event handler fires; selectFeature(featureLayer) is called.selectEvent.emit(featureLayer.feature.properties.name) emits the country name string to the parent.CountryOrdersComponent.selectCountryById(countryName) is called.this.countryName = countryName is set.countryOrderService.getCountriesCategoriesData(countryName) is called; the returned observable is subscribed to with takeWhile(() => this.alive).this.countryData = data is assigned.countryName and countryData to CountryOrdersChartComponent via @Input() bindings.CountryOrdersChartComponent.ngOnChanges() fires; echartsInstance.setOption() is called with the new series data (partial update).Error path: If getCountriesCategoriesData() errors, no error handler is present; countryData remains at its previous value. The chart continues to display the previously selected country's data without any user notification.
[Diagram: Sequence — User Selects a Country on the Map]
Participants: HeaderComponent, NbThemeService, All subscribed components (chart components, DashboardComponent, RoomsComponent, RoomSelectorComponent, TypographyComponent, etc.)
Sequence:
HeaderComponent.HeaderComponent.changeTheme(themeName) calls NbThemeService.changeTheme(themeName).NbThemeService updates its internal theme state and emits on onThemeChange() and getJsTheme() observables.NbThemeService.getJsTheme() receive the new theme configuration object.ElectricityChartComponent, ProfitChartComponent) call their setOptions(eTheme) method, rebuilding the full ECharts options object with new theme colors.options binding change and re-renders the chart with the new color scheme.DashboardComponent updates statusCards by looking up the new theme name in statusCardsByThemes.RoomSelectorComponent updates hideGrid based on whether the new theme is 'corporate'.HeaderComponent updates currentTheme via the onThemeChange() subscription.Error path: If a component's theme subscription errors, that component's visual state may become inconsistent with the active theme. No error handling is present in any observed theme subscription.
[Diagram: Sequence — User Changes the Application Theme]
Participants: TrafficCardsHeaderComponent, TrafficRevealCardComponent, TrafficListData (abstract), TrafficBarData (abstract), TrafficFrontCardComponent, TrafficBarChartComponent
Sequence:
'month') in TrafficCardsHeaderComponent.changePeriod('month') is called; type is updated locally.periodChange.emit('month') fires, propagating the new period to TrafficRevealCardComponent.TrafficRevealCardComponent.setPeriodAngGetData('month') is called.period is updated to 'month'.getTrafficFrontCardData('month') calls trafficListService.getTrafficListData('month'); result is subscribed to with takeWhile(() => this.alive).getTrafficBackCardData('month') calls trafficBarService.getTrafficBarData('month'); result is subscribed to with takeWhile(() => this.alive).'month' period.trafficListData and trafficBarData are assigned.TrafficFrontCardComponent and TrafficBarChartComponent via @Input() bindings.Error path: No error handling is present on either subscription. If either service call fails, the corresponding child component retains its previous data without any user notification.
[Diagram: Sequence — User Submits a Period Change on a Dashboard Widget]
Participants: DialogComponent, NbDialogService, DialogNamePromptComponent, NbDialogRef
Sequence:
DialogComponent.open3() is called; NbDialogService.open(DialogNamePromptComponent) is invoked.DialogNamePromptComponent, and injects a NbDialogRef instance into it.onClose observable is subscribed to: name => name && this.names.push(name).DialogNamePromptComponent.submit(name) calls this.ref.close(name).name on the onClose observable.name is truthy, it is pushed to this.names.DialogComponent template.Error path: If the user clicks Cancel, this.ref.close() is called with no argument; undefined is emitted on onClose. The guard name && this.names.push(name) prevents undefined from being added to the list.
[Diagram: Sequence — Modal Dialog Opens and Returns a Value]
[Diagram: Data Flow — show abstract service classes receiving data from concrete implementations (mock or HTTP), flowing into container components, which pass data via @Input() to presentational components; show NbThemeService as a cross-cutting observable feeding into all chart and layout components; show user interactions flowing back up via @Output() events and method calls]
The application uses the following data sources, as evidenced across the 100 assessed screens:
| Source Type | Examples | Notes |
|---|---|---|
| In-memory mock data | PlayerService (playlist), ChatService (messages, bot replies), SmartTableData (user records) |
Hardcoded static arrays; no network request |
| Static JSON assets | assets/leaflet-countries/countries.geo.json, assets/map/world.json |
Fetched via HttpClient.get() on component init |
| Abstract service observables | All *Data abstract classes (UserData, ElectricityData, CountryOrderData, etc.) |
Concrete implementations not provided in assessed code; may be HTTP-backed or mock |
| Browser platform APIs | navigator.geolocation.getCurrentPosition (MapComponent) |
One-time async call on ngOnInit |
| Nebular theme service | NbThemeService.getJsTheme(), NbThemeService.onThemeChange(), NbThemeService.onMediaQueryChange() |
In-memory reactive streams; no network request |
| Google Maps Places API | google.maps.places.Autocomplete (SearchComponent) |
Browser-managed; SDK handles network requests internally |
| External CDNs | CKEditor CDN, Spotify CDN, media CDNs | Browser-managed resource loads |
ngx-admin uses component-local state as its primary state management approach. There is no global state store (no NgRx, Akita, or similar). State is managed as class-level properties on Angular component instances. The following patterns are observed:
listData, chartData, cameras).@Input() bindings and emit events via @Output().flipped, revealed, isSingleView, loading) is held as simple boolean class properties.type, period) is held as string class properties, often with a corresponding types array for the available options.NbThemeService (Nebular's internal state) and accessed reactively via observables.The typical data transformation pipeline for a data-fetching screen is:
Abstract Service Observable
→ (forkJoin or direct subscribe)
→ Component class property assignment
→ Angular change detection
→ @Input() binding to child component
→ Child component ngOnChanges / ngAfterViewInit
→ ECharts setOption() / Leaflet layer update / template render
For theme-driven chart styling:
NbThemeService.getJsTheme()
→ config.variables.[namespace]
→ setOptions(eTheme) method
→ ECharts options object construction (with LinearGradient, color tokens)
→ [options] binding on echarts directive
→ Chart render
No data transformation libraries (e.g., lodash, date-fns) are directly imported in the assessed component files. Transformations are performed inline using native JavaScript array methods (map, filter, find, Math.round, parseInt).
HttpClient interceptor-based caching is observed across any of the 100 assessed screens.localStorage, sessionStorage, cookies, or IndexedDB access is present in any assessed component.NbThemeService's in-memory state and persists for the lifetime of the browser session (until page refresh).Data is not shared between screens via a global store. The following mechanisms are used for cross-component data sharing within a screen:
@Input() / @Output() bindings — Primary mechanism for parent-to-child data flow and child-to-parent event propagation within a screen.NbThemeService is injected by both container and child chart components).NbDialogRef / NbWindowRef — Used to pass data into and receive return values from overlay components.Observed pattern: Across all 100 assessed screens, there is no consistent error handling strategy for observable subscriptions. The dominant pattern is the absence of error handling:
forkJoin subscriptions in ContactsComponent, ElectricityComponent, VisitorsAnalyticsComponent, TemperatureComponent, and ChartsPanelComponent have no catchError operator and no error callback in .subscribe().TrafficComponent, ProgressSectionComponent, UserActivityComponent, StatsCardBackComponent, and StatsCardFrontComponent similarly have no error handling.CountryOrdersMapService uses HttpClient.get() with no catchError; a 404 or network failure leaves the map blank with no user feedback.Consequence: When a data service observable errors, the component silently retains its initial undefined state. No error message, toast notification, or fallback UI is shown to the user.
Exception: DialogComponent.open3() uses the onClose observable's truthy guard (name && this.names.push(name)) to handle the case where the dialog is cancelled (returns undefined), but this is a UI flow guard, not an error handler.
Observed pattern: No authentication or authorization logic is implemented within any of the 100 assessed component files. All components explicitly note that security is "delegated to Angular route guards at the routing module level."
The package.json includes @nebular/auth (11.0.1) and @nebular/security (11.0.1), indicating that authentication and role-based access control infrastructure is present in the application. However, the specific guard configurations, protected routes, and role definitions are not visible in the assessed screen documentation.
[Not documented — WHO: Backend/security lead; WHAT: Which routes have CanActivate guards applied, which roles are defined in @nebular/security, and how the auth token is stored and refreshed; WHERE: Section 11.2 Authentication & Authorization, after the paragraph above]
Observed pattern: Loading and empty state handling is inconsistent across screens:
undefined and rely on *ngIf or Angular's safe navigation operator (?.) in the template to prevent rendering before data arrives. The template files were not provided for most screens, so the exact implementation cannot be confirmed.SpinnerComponent and its variants are demonstrated as UI showcase screens).Inconsistency: ChatComponent initializes messages synchronously from a static array, so it has no loading state. SpinnerInButtonsComponent and SpinnerComponent use setTimeout to simulate loading states for demonstration purposes only.
Observed pattern: The Nebular UI framework (@nebular/theme) is the exclusive UI component library used across all assessed screens. The following Nebular components appear consistently:
nb-card, nb-card-header, nb-card-body, ngx-one-column-layoutnb-menu, nb-tabset, nb-tabnb-select, nb-option, nb-input (via nbInput directive), nb-datepickerNbDialogService, NbWindowService, NbToastrService, NbPopover directivenb-tree-grid, ng2-smart-table (third-party, Nebular-compatible)nb-icon (Eva icons), Ionicons font classes, Font Awesome font classesNbCalendarComponent, NbCalendarDayPickerComponent, NbCalendarRangeComponentThe ngx- component selector prefix is enforced by ESLint (@angular-eslint/component-selector rule with prefix: "ngx"), ensuring all application-defined components are distinguishable from Nebular components.
Observed pattern: Form validation is not implemented in any of the 100 assessed screens. The form showcase screens (FormLayoutsComponent, FormInputsComponent, NebularFormInputsComponent, ButtonsComponent, DatepickerComponent) are static demonstrations with no bound form controls or validation logic. WindowFormComponent renders uncontrolled inputs with no validation. DialogNamePromptComponent collects a name string with no length or format validation.
[Not documented — WHO: Frontend lead; WHAT: Whether Angular Reactive Forms or Template-Driven Forms with validation are used in any non-assessed screens; WHERE: Section 11.5 Validation Approach]
No observability SDK is identified in the available project context. The package.json manifest does not include any error tracking (e.g., Sentry), APM (e.g., Datadog, New Relic), or analytics (e.g., Google Analytics, Mixpanel) packages as dependencies. The AnalyticsService referenced in LayoutService wraps a ga global variable (Google Analytics Universal Analytics), but this service is not injected into any of the 100 assessed component files and its configuration is not visible in the assessed documentation.
The following performance patterns are consistently applied across the assessed screens:
LayoutService.onSafeChangeLayoutSize() applies debounceTime(350) before emitting layout change events. All ECharts chart components subscribe to this observable to trigger resizeChart(), preventing excessive resize calls during window drag operations. Applied in: OrdersChartComponent, ProfitChartComponent, ElectricityChartComponent, VisitorsAnalyticsChartComponent, EarningCardFrontComponent, VisitorsStatisticsComponent, CountryOrdersChartComponent, TrafficBarChartComponent.echartsInstance.setOption() with only changed properties on data updates, rather than rebuilding the full options object. Applied in: CountryOrdersChartComponent, ProfitChartComponent, OrdersChartComponent, EarningCardFrontComponent, TrafficBarChartComponent.shareReplay in LayoutService: The layoutSizeChange$ Subject uses shareReplay({ refCount: true }), multicasting layout events to all chart subscribers without re-executing the source.ChangeDetectionStrategy.OnPush in IconsComponent: The only component in the assessed set that explicitly applies OnPush change detection, appropriate given its static data initialized at construction time.forkJoin for parallel fetching: Prevents sequential waterfall data loading on screens requiring multiple data sources.Inconsistency: The vast majority of components use Angular's default CheckAlways change detection strategy. ChangeDetectionStrategy.OnPush is applied only to IconsComponent across the 100 assessed screens.
The following cross-cutting concerns are architecturally significant by their absence:
ErrorHandler override, no catchError in HTTP interceptors, and no error callback in any observable subscription is observed. This is a significant gap for production use.ngx-translate, or similar library is present in package.json or referenced in any assessed component.pace-js in package.json), and no standardized empty-state component are observed.TrafficRevealCardComponent, UserActivityComponent, and ChartsPanelComponent trigger immediate service calls with no debounce, allowing rapid successive calls.@nebular/theme (version 11.0.1) is used as the exclusive UI component library across all screens.NbThemeService), and Angular-native components. The @nebular/auth and @nebular/security packages extend it with authentication and RBAC infrastructure.nb-* components across the entire codebase.UserData, ElectricityData, CountryOrderData) in src/app/@core/data/. Components depend on the abstract class token; concrete implementations are registered in Angular modules.ngx-echarts) is the primary charting library for all complex visualizations. Chart.js (angular2-chartjs) and @swimlane/ngx-charts are also present but used for simpler or alternative chart types.ngx-echarts Angular wrapper provides directive-based integration with [options] and [merge] bindings.ngAfterViewInit → theme subscription → setOptions() → echartsInstance.setOption() for updates). The global echarts object is accessed directly for echarts.graphic.LinearGradient, bypassing TypeScript type safety.forkJoin is used to combine multiple observables and wait for all to complete before updating component state.forkJoin prevents partial renders where one data panel appears before another, ensuring a consistent initial state. It is semantically correct for one-shot HTTP-style observables.forkJoin errors or never completes, the entire combined observable fails silently (no error handler is present). This is a known risk documented in Section 14.takeWhile(() => this.alive) pattern is used as the primary subscription cleanup mechanism across the majority of assessed screens. alive is a boolean class property initialized to true and set to false in ngOnDestroy().Subscription objects and calling .unsubscribe() explicitly, reducing boilerplate.takeWhile evaluates the predicate on every emission, meaning the subscription is not immediately cancelled when ngOnDestroy fires — it completes on the next emission after alive becomes false. For high-frequency observables, this can result in one additional emission being processed after destruction. The takeUntil(destroy$) pattern (used in SecurityCamerasComponent and HeaderComponent) is more reliable and is the modern Angular recommendation. The inconsistency between the two patterns across the codebase is documented as technical debt in Section 14.EditorsComponent, MapsComponent, FormsComponent) whose template contains only <router-outlet></router-outlet> and whose class body is empty.NbThemeService.getJsTheme() and extract chart-specific color tokens from config.variables.[namespace] (e.g., config.variables.electricity, config.variables.profit, config.variables.countryOrders). No chart colors are hardcoded.undefined colors. The delay(1) operator applied in several chart components' ngAfterViewInit is a workaround for Angular change detection timing issues.@asymmetrik/ngx-leaflet) is used for the Country Orders map and the basic Leaflet showcase. The CountryOrdersMapComponent fetches GeoJSON from a static asset and uses L.geoJSON() to render country polygons.ngx-leaflet. It supports GeoJSON rendering, custom styling, and event handling natively.http:// (not https://), which will cause mixed-content blocking in production HTTPS environments. The attribution field is set to '...', violating OpenStreetMap's attribution requirements. Both are documented as risks in Section 14.NbDialogService and NbWindowService are used exclusively for all overlay management. Components and templates are passed as content; NbDialogRef and NbWindowRef are injected into overlay content components for lifecycle control.onClose observable pattern enables clean return-value handling.NbDialogRef and NbWindowRef injection pattern requires overlay content components to be registered as Angular entry components (or use ivy component factories).PlayerService (hardcoded playlist with Spotify CDN URLs), ChatService (hardcoded messages and bot reply rules), SmartTableData (hardcoded user records), and the BubbleMapComponent (hardcoded country population data).npm install.PlayerService are external dependencies that may break if Spotify removes the preview files. The ChatService.reply() method mutates the shared botReplies array directly, causing permanent session-level state corruption for bot reply URLs. Both are documented as risks in Section 14.| Quality Attribute | Current State | Evidence | Risk Level |
|---|---|---|---|
| Maintainability | Good — abstract service pattern cleanly separates UI from data; Nebular theming centralizes visual configuration; ESLint enforces naming conventions | Abstract *Data classes in src/app/@core/data/; ngx- prefix enforced by ESLint; all chart colors sourced from NbThemeService |
Low |
| Extensibility | Good — new screens can be added as child routes without modifying shell components; new data providers can be registered without modifying components | Router shell pattern observed in 11 feature sections; Angular DI abstract service pattern | Low |
| Visual Consistency | Good — all components subscribe to NbThemeService; theme changes propagate uniformly |
Theme subscription observed in Dashboard, Header, all chart components, Room Selector, Typography, Chart Panel Header | Low |
| Responsiveness | Good — breakpoint-aware layout decisions use NbMediaBreakpointsService consistently |
Observed in RoomsComponent, CountryOrdersComponent, SecurityCamerasComponent, TypographyComponent, HeaderComponent | Low |
| Reliability | Poor — no error handling on any observable subscription; silent failures leave UI in broken state | No catchError or error callback observed in any of the 100 assessed screens |
High |
| Performance | Moderate — debounced resize and ECharts partial updates are applied consistently; no OnPush change detection on most components; no client-side caching |
debounceTime(350) in LayoutService; echartsInstance.setOption() partial updates; only IconsComponent uses OnPush |
Medium |
| Security | Poor — no authentication enforcement in any component; XSS risks from CKEditor output and ECharts tooltip formatter; HTTP (not HTTPS) tile URL; missing rel="noopener noreferrer" on target="_blank" links |
Footer component target="_blank" without rel; Leaflet tile URL uses http://; CKEditor output not sanitized; TrafficBarChartComponent formatter input not sanitized |
High |
| Testability | Moderate — abstract service pattern enables easy mocking in unit tests; no OnPush on most components simplifies change detection testing; no test files assessed |
Abstract service pattern; empty class bodies on shell components are trivially testable | Medium |
| Usability | Good — Nebular provides a consistent, accessible design system; responsive breakpoint handling is applied; four theme variants are supported | Nebular component usage across all screens; breakpoint-aware layouts; theme switching in Header | Low |
| ID | Category | Description | Severity | Recommendation |
|---|---|---|---|---|
| R-1 | Architectural Risk | No error handling on observable subscriptions. All forkJoin and individual service subscriptions across the 100 assessed screens have no catchError operator and no error callback. Observable errors cause silent UI failures with no user feedback. |
High | Add a catchError operator to all service subscriptions. Implement a global Angular ErrorHandler to catch unhandled errors. Consider a centralized error notification pattern using NbToastrService. |
| R-2 | Security | Leaflet tile URL uses http:// (not https://). The LeafletComponent hardcodes http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png. In production HTTPS environments, browsers will block this as mixed content, causing all map tiles to fail. |
High | Change the tile URL to https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png. |
| R-3 | Security | Missing rel="noopener noreferrer" on target="_blank" links. The FooterComponent renders five anchor tags with target="_blank" but no rel attribute, exposing the application to reverse tabnapping attacks. |
Medium | Add rel="noopener noreferrer" to all target="_blank" anchor elements in FooterComponent. |
| R-4 | Security | CKEditor output is not sanitized. CKEditorComponent renders user-provided rich HTML content. If this content is rendered via [innerHTML] elsewhere in the application, it is an XSS vector. |
High | Sanitize CKEditor output using Angular's DomSanitizer or a server-side HTML sanitizer before storing or rendering the content. |
| R-5 | Security | ECharts tooltip formatter input is not sanitized. TrafficBarChartComponent accepts a formatter: string @Input() and passes it directly to ECharts as a tooltip formatter. If this string originates from untrusted data, it could be an XSS vector within the chart tooltip. |
Medium | Validate or allowlist the formatter input before passing it to ECharts. |
| R-6 | Security | OpenStreetMap attribution is missing. LeafletComponent sets attribution: '...', violating OpenStreetMap's tile usage policy which requires displaying © OpenStreetMap contributors. |
Medium | Set the correct attribution string: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'. |
| R-7 | Technical Debt | Inconsistent subscription cleanup pattern. The majority of components use takeWhile(() => this.alive), while SecurityCamerasComponent and HeaderComponent use the more reliable takeUntil(destroy$) pattern. takeWhile may process one additional emission after ngOnDestroy fires. |
Medium | Standardize on takeUntil(destroy$) with a Subject<void> across all components. Consider using the @ngneat/until-destroy library or Angular's built-in DestroyRef (Angular 16+). |
| R-8 | Technical Debt | takeWhile subscription not applied to forkJoin in several components. TemperatureComponent and StatsCardFrontComponent initiate forkJoin subscriptions in the constructor without takeWhile or takeUntil, meaning in-flight requests are not cancelled if the component is destroyed before they complete. |
Medium | Apply takeWhile(() => this.alive) or takeUntil(destroy$) to all forkJoin subscriptions. |
| R-9 | Technical Debt | ChatService.reply() mutates shared botReplies array. The method directly mutates botReply.reply.files[0].url and botReply.reply.text on entries in the module-level botReplies constant, causing permanent session-level state corruption for subsequent bot replies. |
Medium | Return a deep copy of the reply object rather than mutating the source array. Use JSON.parse(JSON.stringify(botReply.reply)) or a structured clone. |
| R-10 | Technical Debt | StatsCardFrontComponent never sets alive = false. The alive boolean is declared and used with takeWhile, but ngOnDestroy is not implemented, meaning alive is never set to false. The subscription to ProfitBarAnimationChartData.getChartData() is never unsubscribed. |
High | Implement ngOnDestroy() in StatsCardFrontComponent and set this.alive = false. |
| R-11 | Technical Debt | TrafficComponent stores currentTheme but never uses it. The component subscribes to NbThemeService.getJsTheme() and stores the theme name in currentTheme, but this value is never used in the template or passed to ngx-traffic-chart. The subscription is active but inert. |
Low | Either use currentTheme to pass theme information to ngx-traffic-chart, or remove the subscription entirely. |
| R-12 | Technical Debt | TrafficComponent type selector not wired to data fetch. The nb-select dropdown for period selection (week, month, year) is bound to type, but changing type does not trigger a new call to getTrafficChartData(). The chart always displays data for the initial period. |
Medium | Wire the (selectedChange) event of the nb-select to a method that re-fetches data with the new period. |
| R-13 | Technical Debt | DashboardComponent has a type annotation error. statusCards is declared as string but holds a CardSettings[] array at runtime. This bypasses TypeScript's type checking. |
Low | Change the type annotation to CardSettings[]. |
| R-14 | Technical Debt | Hardcoded Spotify CDN URLs in PlayerService. Audio preview URLs point to https://p.scdn.co/mp3-preview/.... If Spotify removes these files, the player will silently fail. |
Medium | Move audio URLs to a configurable data source (e.g., environment.ts or a backend API) rather than hardcoding them in the service. |
| R-15 | Technical Debt | CountryOrdersChartComponent hardcodes maxValue="20". The chart's y-axis maximum is always 20 regardless of actual data values. If any country's order data exceeds 20, the chart will clip or misrepresent the data. |
Medium | Make maxValue dynamic, computed from the maximum value in the data array, or make it a configurable @Input() with a sensible default. |
| R-16 | Technical Debt | Outdated dependency versions. Several dependencies are significantly behind current releases: chart.js 2.7.1 (current: 4.x), ng2-ckeditor ~1.2.9 (unmaintained), @asymmetrik/ngx-leaflet 3.0.1 (current: 7.x), tinymce 4.5.7 (current: 6.x/7.x), angular2-chartjs 0.4.1 (unmaintained). |
Medium | Audit and update dependencies. Replace unmaintained packages (ng2-ckeditor, angular2-chartjs) with maintained alternatives. |
| R-17 | Architectural Risk | No client-side caching. Every navigation to a screen re-fetches all data. For screens with expensive data fetches (e.g., GeoJSON assets, analytics data), this results in unnecessary network requests and latency. | Medium | Implement HTTP interceptor caching for static assets, or introduce a data-fetching library (e.g., @ngrx/data, TanStack Query for Angular) for API responses. |
| R-18 | Documentation Gap | Concrete service implementations not assessed. All *Data abstract classes have concrete implementations registered in Angular modules, but these implementations are not included in the assessed documentation. Actual API endpoints, HTTP methods, status code handling, and database queries are unknown. |
Medium | Document the concrete service implementations in a separate API integration document. Ensure the concrete services include proper error handling and retry logic. |
| Term | Definition |
|---|---|
| Status Card | A dashboard widget displaying the on/off state of a smart-home device (e.g., Light, Roller Shades, Wireless Audio, Coffee Maker). Rendered by StatusCardComponent. |
| Traffic Reveal Card | A dashboard widget with a front face showing traffic list data and a back face showing a traffic bar chart, toggled by a flip animation. |
| Profit Card | An e-commerce widget with a front face showing profit metrics and a back face showing a profit breakdown chart. |
| Earning Card | An e-commerce widget with a front face showing a live-updating earnings line chart and a back face showing an earnings pie chart. |
| Country Orders | An e-commerce feature displaying order statistics per country, combining an interactive Leaflet map with a bar chart. |
| Visitors Analytics | An e-commerce feature displaying website visitor metrics using a dual-line chart, a pie chart, and a legend. |
| Charts Panel | An e-commerce feature displaying orders and profit data in a tabbed ECharts chart panel with a period selector. |
| Progress Section | An e-commerce feature displaying KPI metrics as progress bars with titles, values, and descriptions. |
| Solar Energy Consumption | A dashboard widget displaying the percentage of solar energy consumed as a donut ECharts chart. |
| Room Selector | A dashboard widget rendering an SVG floor plan with interactive room areas for the Rooms/Player feature. |
| PositionModel | A data model holding lat and lng coordinates, used by the Search Map feature to communicate selected locations. |
| TrafficList | A data model representing traffic metrics for a time period: date, value, delta (direction and magnitude), and comparison (previous/next period). |
| TrafficBar | A data model representing traffic bar chart data: numeric data array, string labels array, and a tooltip formatter string. |
| ProfitChart | A data model for the profit bar chart: chartLabel (x-axis labels) and data (three series of numeric arrays for Canceled, Payment, All orders). |
| OrdersChart | A data model for the orders line chart: chartLabel (x-axis labels) and linesData (multiple series of numeric arrays). |
| OutlineData | A data model for the visitors analytics outer line chart: { label: string, value: number }. |
| CardSettings | A data model for dashboard status cards: title, iconClass, and type (Nebular component status). |
| Electricity | A data model for electricity category summaries: title, active flag, and months array (each with month, delta, down, kWatts, cost). |
| Camera | A data model for security camera entries: title and source (video stream URL). |
| NgxLegendItemColor | An enum constraining legend icon colors to five values: green, purple, light-purple, blue, yellow. |
| Term | Definition |
|---|---|
| Abstract Service Pattern | The architectural pattern used throughout ngx-admin where data-fetching contracts are defined as Angular abstract classes and concrete implementations are registered via Angular's dependency injection system. Enables swapping data sources without modifying UI components. |
| Router Shell Component | An Angular component whose template contains only <router-outlet> and whose class body is empty. Used to define route namespaces for feature sections without adding UI or logic overhead. |
| NbThemeService | The Nebular UI framework's central theming service. Provides reactive observables for theme changes (onThemeChange()), media query breakpoint changes (onMediaQueryChange()), and the current theme's JavaScript variable map (getJsTheme()). |
| NbMediaBreakpointsService | A Nebular service providing a static map of breakpoint names to pixel widths, used for responsive layout decisions. |
| LayoutService | An internal application utility service that broadcasts debounced layout size change events via an RxJS Subject. Consumed by all ECharts chart components to trigger resizeChart(). |
| forkJoin | An RxJS operator that subscribes to multiple observables simultaneously and emits a single array of results only when all source observables have completed. Used for parallel data fetching in ngx-admin. |
| takeWhile | An RxJS operator that completes a subscription when a predicate function returns false. Used in ngx-admin as takeWhile(() => this.alive) for subscription lifecycle management. Less reliable than takeUntil because the predicate is evaluated on each emission rather than immediately on a signal. |
| takeUntil | An RxJS operator that completes a subscription when a notifier observable emits. Used with a Subject<void> (destroy$) as the more reliable alternative to takeWhile for subscription cleanup. |
| ECharts Partial Update | The pattern of calling echartsInstance.setOption() with only the changed portions of the ECharts configuration (e.g., only series data), rather than replacing the full options object. Avoids full chart re-initialization on data updates. |
| ngx-echarts | An Angular wrapper library for Apache ECharts that provides the echarts attribute directive, enabling declarative chart binding via [options] and [merge] inputs and (chartInit) event output. |
| NbDialogRef | A Nebular class representing a reference to an open dialog overlay. Injected into dialog content components; provides close(result?) to dismiss the dialog and onClose observable to receive the result in the opener. |
| NbWindowRef | A Nebular class representing a reference to an open window overlay. Injected into window content components; provides close() to dismiss the window. |
| LocalDataSource | A ng2-smart-table class that holds table data in memory and provides sorting, filtering, and pagination operations without network requests. |
| NbCalendarCell | A Nebular interface contract for custom calendar cell components, requiring select: EventEmitter<Date> and selectedValue: Date properties. |
| combineLatest | An RxJS operator that subscribes to multiple observables and emits an array of their latest values whenever any source observable emits. Used in CountryOrdersMapComponent and BubbleMapComponent to combine GeoJSON data with theme configuration. |
| ngx-admin | The name of this application — an open-source Angular admin dashboard template built by Akveo on the Nebular UI framework. |
| Eva Icons | The SVG icon pack bundled with Nebular (@nebular/eva-icons), providing filled and outline variants of common UI icons. Rendered via the nb-icon component. |
| Nebular | The Angular UI component library (@nebular/theme) built by Akveo on the Eva Design System. Provides the design system, theming engine, layout components, form controls, overlays, and data display components used throughout ngx-admin. |
| ngcc | The Angular Compatibility Compiler, run as a postinstall script to compile Nebular and other Angular libraries to Ivy-compatible format. |
| Ivy | Angular's current rendering engine (introduced in Angular 9), which provides improved tree-shaking, faster compilation, and better debugging. ngx-admin targets Ivy via the postinstall ngcc step. |