Skip to content

Repository files navigation

uBeac IoT Platform: Admin Panel (admin.ubeac.io)

The first web front end of uBeac, built between late 2017 and 2018. It is two things in one codebase: an operator console for the platform's device catalog, teams, users and ingestion endpoints, and a UX lab where the dashboard, indoor floor-plan and map ideas that later shipped in the customer app were first prototyped.

Status: historical, published for reference. This app was superseded by the admin section of ui.ubeac.io and the operator controllers of api.ubeac.io. The admin API it was written against is not part of the public release, and its sign-in used an OAuth client and account routes that the released identity server doesn't have. With the public code, only the prototypes run, on built-in mock data. It is published under the MIT license. Read Known limitations and security notes before running it.

Repository What it is
api.ubeac.io .NET backend: ingestion hubs, processing workers, REST API, identity, real-time. Start there for the platform architecture and the comparison with other IoT platforms.
ui.ubeac.io Vue customer web app, which absorbed this panel's admin features
admin.ubeac.io (this repo) The first operator console and UX prototypes
OSMonitoring Edge agent: a computer's own sensors (CPU, memory, disks, network, temperatures) as a uBeac device
SBCGateway Edge agent: a Raspberry Pi as a BLE, Bluetooth and Wi-Fi scanning gateway

Contents

  1. At a glance
  2. Where it fits in uBeac's history
  3. Features: working and prototype
  4. Tech stack
  5. Architecture
  6. The generic CRUD pattern
  7. Authentication
  8. Domain model
  9. The prototypes
  10. Routes and backend endpoints
  11. Project structure
  12. Getting started
  13. Known limitations and security notes
  14. License

1. At a glance

Built About November 2017 to mid-2018 (design files are dated October 2017 to February 2018)
Framework Vue 2.4, Vuex 3, vue-router 2.7, webpack 3 (vue-cli webpack template)
UI Bootstrap 4 (beta) and bootstrap-vue 1.4, Highcharts 6, custom SVG gauges
Size 58 Vue components and about 11,000 lines of hand-written Vue, JavaScript and SCSS
Working features Catalog, team, endpoint and user management; endpoint message-log viewer
Prototypes Sensor-card dashboard, indoor floor-plan editor, geo map with drill-down

2. Where it fits in uBeac's history

flowchart LR
  subgraph Y2017["2017 to 2018"]
    ADM["admin.ubeac.io<br/>operator console and prototypes"]
    AAPI["Admin API<br/>adminapi.ubeac.io"]
    ING1["Ingestion and log service<br/>on Azure App Service"]
  end
  subgraph Y2018["2018 to 2020"]
    UI["ui.ubeac.io<br/>customer web app"]
    API["api.ubeac.io<br/>microservice backend"]
  end
  ADM -- "catalog admin moved to<br/>the web app's admin section" --> UI
  ADM -- "dashboard, floor plan and map<br/>ideas shipped as widgets" --> UI
  AAPI -- "replaced by uBeac.Api<br/>admin controllers" --> API
  ING1 -- "replaced by HttpHub, MqttHub<br/>and the worker pipeline" --> API
Loading

What carried forward:

  • The device catalog. The panel's Manufacturer → Gateway → Gateway Version chain became Manufacturer → Product → Firmware. The "processor code for this firmware version" field became the per-firmware decoder that the backend compiles at runtime, the core of uBeac's gateway support.
  • Indoor floor plans. The drag-and-drop floor-plan editor became the Floor widget and the floor-placement maps in the customer app.
  • Map drill-down. The geo map that zooms from a building footprint into its floor plan became the Buildings, Floors and Map features.
  • Sensor cards. The temperature, gas and light cards with SVG gauges became the Indicator widget and its library of animated indicators.
  • Conventions. The [controller]/[action] routes, the { data } response envelope, the File/Upload and File/Download/{id} endpoints and the IdentityServer login flow all continued in the later apps.

3. Features: working and prototype

Feature Status Backend
Sign in, sign up, forgot and reset password, sign out Worked against the original identity server (not the released one) Identity server
Manufacturers, gateway models and gateway versions (firmware) Working CRUD with logo and document uploads Admin API
Teams and ingestion endpoints Working CRUD; each endpoint shows its ingestion URL (the endpoint pages and the message log show different host names for it) Admin API
Users Working create and update with roles (Users, Admins) and admin password reset Admin API
IoT Hub message log Working: paged messages per endpoint, JSON viewer, auto-refresh (3, 5, 10 or 15 seconds, or a custom interval) Ingestion service
Sensor-card dashboard Prototype: 12 card types, drag to reorder Mock data
Floor-plan editor Prototype: drag sensors onto a plan, pan and zoom, "3D" view Mock data
Geo map Prototype: satellite and street layers, shape drawing, drill-down into the floor plan Demo shapes

4. Tech stack

Purpose Libraries
Framework Vue 2.4.2, Vuex 3.0, vue-router 2.7 (history mode)
Build webpack 3.6, Babel 6, vue-loader 13, ESLint (standard) and stylelint inside webpack, favicons-webpack-plugin
UI Bootstrap 4.0 beta, bootstrap-vue 1.4, vue-awesome icons, Simple Line Icons
HTTP vue-resource 1.3 with interceptors; raw XMLHttpRequest for the identity server
Forms vee-validate 2.0, vue-picture-input, vue-datepicker
Charts Highcharts 6 (Highstock) with vue-highcharts; hand-built SVG gauges
Maps Leaflet 1.3 with Leaflet.Editable, OpenStreetMap, Bing and Google layers
Floor plan jQuery UI drag and drop, jquery.panzoom, vuedraggable
Feedback vue-notification, NProgress, vue-spinner, vue-breadcrumbs
Tests Karma, Mocha, Sinon-Chai, PhantomJS

5. Architecture

5.1 As built (2017 to 2018)

flowchart LR
  subgraph Browser["Browser: admin.ubeac.io"]
    PAGES["Pages and cards"]
    PROTO["Floor-plan editor and geo map"]
    STORE["Vuex store"]
    HTTP["vue-resource<br/>Bearer interceptor, 401 redirect"]
    MOCK[("src/mock")]
    PAGES --> STORE --> HTTP
    PAGES --> MOCK
    PROTO --> MOCK
  end
  IDS["Identity server<br/>idsrv.ubeac.io"]
  AAPI["Admin API<br/>adminapi.ubeac.io"]
  ING["Ingestion and log service<br/>Azure App Service"]
  DEV["Gateways and devices"]
  STORE -- "XHR: token, user info" --> IDS
  HTTP -- "catalog, teams, endpoints,<br/>users, files" --> AAPI
  HTTP -- "endpoint message log" --> ING
  DEV -- "JSON POST to /api/i/{shortUrl}" --> ING
Loading

5.2 Inside the app

flowchart TB
  MAIN["main.js<br/>plugins, interceptors, global components"] --> APP["App.vue<br/>progress bar, notifications, router-view"]
  MAIN --> ROUTER["router<br/>page title and token guard"]
  ROUTER --> PAGES
  subgraph PAGES["components/pages"]
    AUTH["auth/*"]
    CATALOG["manufacturer, gateway, gateway_version"]
    TENANCY["endpoint, myendpoint, team, user"]
    HUB["iothub (message log)"]
    PROTOS["Dashboard, Map, Leaf (prototypes)"]
  end
  PAGES --> PANEL["layout/Panel<br/>header, sidebar, breadcrumbs"]
  CATALOG --> MIXINS["mixins/page-grid.js, page-form.js"]
  CATALOG & TENANCY --> PARTIALS["partial/*<br/>grid header, empty state, delete button,<br/>file uploader, date pickers"]
  PROTOS --> CARDS["cards/*<br/>3 sensors x 4 variants, SVG gauges"]
  MIXINS --> STORE["store/modules/*<br/>base.js CRUD plus entity modules"]
  TENANCY --> STORE
  HUB --> STORE
Loading

6. The generic CRUD pattern

Most catalog pages are built from three reusable pieces: a Vuex base module that speaks the API's CRUD convention, a list-page mixin and a form-page mixin. A new entity needs only a store module that sets its API path and grid columns, plus two small page components.

classDiagram
  direction LR
  class BaseModule {
    base.js
    state: list, item, path
    all() GET path/getall
    getItem(id) GET path/GetById/id
    add(item) PUT path/Add
    update(item) POST path/Update
    remove(id) DELETE path/Remove
  }
  class ManufacturerModule {
    path = manufacturer
    gridFields
  }
  class GatewayModule {
    path = Gateway
    gridFields
  }
  class GatewayVersionModule {
    path = GatewayFirmware
    gridFields
  }
  class PageGrid {
    mixin page-grid.js
    loads the list on mount
    grid or table view
  }
  class PageForm {
    mixin page-form.js
    add or update by route id
    validation and file upload
  }
  BaseModule <|-- ManufacturerModule
  BaseModule <|-- GatewayModule
  BaseModule <|-- GatewayVersionModule
  PageGrid ..> BaseModule : dispatch all
  PageForm ..> BaseModule : dispatch getItem, add, update
Loading

List pages switch between a card grid and a table (the table is hidden on phones), show an empty state, and link each row to its edit page. Edit pages show audit fields (created and updated, by whom) and counts of related records.

7. Authentication

sequenceDiagram
  autonumber
  participant U as Operator
  participant SPA as Admin panel
  participant IDS as Identity server
  participant API as Admin API
  U->>SPA: email and password
  SPA->>IDS: POST connect/token (password grant, client AdminUIClientRO, scope AdminApi and others)
  IDS-->>SPA: access token, saved in localStorage
  SPA->>IDS: POST connect/userinfo and api/user/claims
  SPA->>API: requests with Authorization: Bearer token
  API-->>SPA: 401 when the token has expired
  SPA->>SPA: redirect to /login?redirecturl=...
Loading

The route guard only checks that a token exists. Roles are fetched but not used in the UI, so the API is the only gate for operator-only actions.

8. Domain model

The panel uses uBeac's early vocabulary. Each term maps to a later concept in the platform.

erDiagram
  MANUFACTURER ||--o{ GATEWAY : makes
  GATEWAY ||--o{ GATEWAYVERSION : "has versions"
  GATEWAYVERSION ||--o{ ENDPOINT : "used by"
  TEAM ||--o{ ENDPOINT : owns
  ENDPOINT ||--o{ LOGMESSAGE : receives
Loading
This panel Later in uBeac Notes
Manufacturer Manufacturer Name, website, logo
Gateway Product A hardware model, with manual and specification files
Gateway Version (GatewayFirmware) Firmware Release date and "processor code", which became the runtime-compiled decoder
Endpoint Gateway A team's ingestion URL. Here it is a short code (/api/i/{shortUrl}); later it became {namespace}.hub.ubeac.io/{gatewayUrl}
Team Team The tenant
Log message GatewayData A raw request received by an endpoint

9. The prototypes

9.1 Sensor-card dashboard

Twelve card components (src/components/cards/) cover three sensor types, temperature, gas and light, in four variants each:

Variant Shows
Basic A custom SVG gauge (thermometer, gas bar or sun) plus the value, optional humidity and a sparkline
Chart A titled Highcharts chart of recent history
Group A row of sensors, each with a gauge or sparkline
Log A table of readings with up, down and flat change indicators

Cards take data and settings props, and settings (chart type, theme, details) are deep-merged over defaults. The dashboard lets you reorder cards by dragging in edit mode. The card designs follow a spec in graphic/carts.fw.png, and src/mock/cards.js documents the payload each card expects.

9.2 Floor-plan editor

src/components/partial/Map/Map.vue (route /map) is an interactive editor for placing sensors on a building floor plan:

  • Drag sensors from a palette onto an SVG floor plan. Drop positions are stored as percentages, corrected for the current zoom.
  • Pan and zoom with the mouse wheel or buttons; pins resize with the zoom level.
  • Hover a pin to remove it, move it or open a detail view with a large gauge.
  • Switch floors, search pins and adjust pin and map scale.
  • An "experimental 3D view" tilts the plan into an isometric perspective with CSS transforms.

9.3 Geo map with drill-down

src/components/pages/Leaf.vue (route /geo) shows a Leaflet map with OpenStreetMap, Bing and Google satellite layers. Users can draw markers, lines, polygons, rectangles and circles. Clicking a building footprint zooms in and fades into the floor-plan editor (the same sample plan for every shape).

flowchart LR
  WORLD["Geo map<br/>OpenStreetMap, Bing, Google"] -- "click a building footprint" --> ZOOM["Zoom to the shape"]
  ZOOM -- "fade in" --> PLAN["Floor-plan editor<br/>for that building"]
  PLAN -- "select a floor" --> PINS["Sensor pins with gauges<br/>(mock values)"]
Loading

10. Routes and backend endpoints

10.1 Routes

Area Paths
Authentication /login, /signup, /forgot_password, /reset_password, /change_password, /logout, /profile
Catalog /manufacturers, /manufacturers/:id, /gateways, /gateways/:id, /gatewayversion, /gatewayversion/:id
Tenancy /team, /team/:id, /endpoint, /endpoint/:id, /myendpoint, /myendpoint/:id, /users, /users/:id, /users/changepassword/:id
Message log /iothub/:id
Prototypes / (dashboard), /map (floor plan), /geo (geo map)
Other /setting, /kitchensink, * (not found)

:id is an entity ID, or new to create one.

10.2 Backend endpoints

The admin API and the log service below belong to uBeac's first backend, which is not part of the public release.

Service Endpoints
Admin API {entity}/getall, {entity}/GetById/{id}, {entity}/Add (PUT), {entity}/Update (POST), {entity}/Remove (DELETE) for manufacturer, Gateway, GatewayFirmware, Endpoint and Team; Endpoint/GetWithDependencies, Gateway/GetbyManufacturerId/{id}, GatewayFirmware/GetbyGatewayId/{id}; api/admin/* for users; File/Upload, File/Download/{id}
Log service GET /i/{shortUrl}?pageNumber&rowCount&fromDate&toDate
Identity server connect/token, connect/userinfo, api/user/claims, api/user/register, api/user/forgotpassword, api/user/resetpassword, api/user/logout

11. Project structure

admin.ubeac.io/
├── build/                  webpack 3 configuration and dev server
├── config/                 Environment settings (dev server on port 60001)
├── graphic/                Design sources: logo, card designs, dashboard mockups (Illustrator, Fireworks)
├── static/                 Vendored libraries (panzoom, Leaflet.Editable, Prism), icons, sample floor plans
├── src/
│   ├── main.js             Plugins, HTTP interceptors, global components
│   ├── config.js           API base URL, validation and progress-bar settings
│   ├── router/             Routes and the auth guard
│   ├── store/modules/      base.js CRUD, entity modules, auth, iothub, layout
│   ├── components/
│   │   ├── pages/          One folder per feature
│   │   ├── cards/          Sensor cards, SVG gauges, chart configs
│   │   ├── partial/        Shared UI, including the floor-plan editor (Map/)
│   │   └── layout/         Page shell
│   ├── mixins/             page-grid.js and page-form.js
│   ├── mock/               Mock data for the prototypes and payload conventions
│   └── sass/               Global, page, component and card styles
├── test/                   Karma unit test set-up
└── index.html              Loads Leaflet, jQuery UI and map providers from CDNs

12. Getting started

nvm use 8          # node-sass 4.7 and webpack 3 need an older Node.js; 8 LTS was current then
npm install
npm run dev        # http://localhost:60001
npm run build      # production build to dist/
  • The prototypes (/, /map, /geo) run on mock data. The route guard requires a token, so set any value for token in the browser's localStorage to open them without signing in.
  • The admin API base URL is in src/config.js and the identity server URL in src/store/modules/auth.js, but host names are also hard-coded in FileUploader.vue, the endpoint pages, store/modules/iothub.js and Iothub.vue. The data pages need the original admin API, which is not included.
  • The Bing and Google layers on the geo map need your own keys (src/components/pages/Leaf.vue and the Google Maps script in index.html).
  • There is no lockfile, so npm install resolves the version ranges fresh; expect to pin a few packages.

13. Known limitations and security notes

This is an early prototype, published for its design history.

  • Secrets. The OAuth client secret and the Bing Maps key were replaced with placeholders before publication. Treat any value from an earlier copy as compromised.
  • OAuth flow. The panel uses the resource-owner password grant with a client secret in the browser, keeps tokens in localStorage, and doesn't revoke them on logout.
  • Plain HTTP. API and identity URLs use http://.
  • Unpinned CDN scripts. index.html loads several scripts without version pins or integrity hashes, some over plain HTTP or from hosts that no longer exist, including cdn.polyfill.io, a domain that was later compromised. Remove or vendor them before serving this app.
  • Debug leftovers. The login code logs its request payload, including the password, to the browser console.
  • Incomplete features. Self-service password change is a stub, the message-log date filters aren't wired, list pages don't refresh after an edit, and the only unit test imports a component that doesn't exist.
  • End-of-life stack. Vue 2.4, webpack 3, Bootstrap 4 beta, PhantomJS and node-sass are all long past support.

14. License

MIT

About

Admin UI for uBeac Project

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages