+
+
About
+
+ MAGE is a dynamic, secure, mobile situational awareness and field data collection platform that supports
+ low-bandwidth and disconnected users. MAGE can integrate with existing command centers and common operating
+ pictures or stand alone as a complete, mission-ready solution. The MAGE mobile app on iOS and Android
+ allows agents in the field to create and share geo-tagged observations with attached photos, videos,
+ audio, and form data. MAGE's data collection forms are easily tailored to suit any team and mission with
+ custom form fields and map symbologies. In addition to data collection, the MAGE mobile app can optionally
+ report field agents' locations at regular intervals to the MAGE server. The MAGE server's web app provides
+ a common operating picture of field agents' observations and latest reported locations.
+
+
+
-
-
Iconography
-
The icons used throughout the app come from Font Awesome
+
+
+
+
API
+
+ Browse and try the MAGE API live with
Swagger UI. Swagger interactive documentation will modify MAGE data via API calls; please be careful with
POST/PUT/DELETE operations.
+
+
+
System
+
Server Version {{mageVersion.major}}.{{mageVersion.minor}}.{{mageVersion.micro}}
+
Node Version {{nodeVersion}}
+
MongoDB Version {{mongoVersion}}
+
+
+
+
Acknowledgements
+
+
+
Authentication is locked down by
+
Passport
+
+
+
+
+
\ No newline at end of file
diff --git a/web-app/src/app/about/about.component.scss b/web-app/src/app/about/about.component.scss
index e69de29bb..933ea63b3 100644
--- a/web-app/src/app/about/about.component.scss
+++ b/web-app/src/app/about/about.component.scss
@@ -0,0 +1,37 @@
+@use '@angular/material' as mat;
+@import "variables.scss";
+
+.content {
+ width: 50vw;
+ margin: 0 auto;
+ padding: 32px 0;
+ display: flex;
+ flex-direction: column;
+ gap: 32px;
+}
+
+.mat-h1 {
+ color: mat.get-color-from-palette($app-primary);
+}
+
+.container {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+ justify-content: center;
+}
+
+.title {
+ margin-left: 16px;
+}
+
+.app-store {
+ display: flex;
+ flex-direction: row;
+ gap: 16px;
+ align-items: center;
+}
+
+.app-store-icon {
+ height: 48px;
+}
\ No newline at end of file
diff --git a/web-app/src/app/about/about.component.ts b/web-app/src/app/about/about.component.ts
index 467967886..856add689 100644
--- a/web-app/src/app/about/about.component.ts
+++ b/web-app/src/app/about/about.component.ts
@@ -1,5 +1,6 @@
import { Component, Inject, OnInit } from '@angular/core';
import { ApiService } from '../api/api.service';
+import { Router } from '@angular/router';
@Component({
selector: 'about',
@@ -19,6 +20,7 @@ export class AboutComponent implements OnInit {
mongoVersion: string
constructor(
+ private router: Router,
@Inject(ApiService) public apiService: ApiService
) {}
@@ -31,4 +33,8 @@ export class AboutComponent implements OnInit {
this.mongoVersion = api.environment.mongodbVersion;
})
}
+
+ onBack(): void {
+ this.router.navigate(['map']);
+ }
}
diff --git a/web-app/src/app/app.module.ts b/web-app/src/app/app.module.ts
index 96d6f3767..a75ff963c 100644
--- a/web-app/src/app/app.module.ts
+++ b/web-app/src/app/app.module.ts
@@ -171,10 +171,12 @@ import { PollingIntervalComponent } from './preferences/polling-interval/polling
import { TimeFormatComponent } from './preferences/time-format/time-format.component';
import { TimeZoneComponent } from './preferences/time-zone/time-zone.component';
import { CoordinateSystemComponent } from './preferences/coordinate-system/coordinate-system.component';
+import { AboutComponent } from './about/about.component';
@NgModule({
declarations: [
AppComponent,
+ AboutComponent,
NavigationComponent,
ZoomComponent,
AddObservationComponent,
diff --git a/web-app/src/app/event/event.service.ts b/web-app/src/app/event/event.service.ts
index a1dca848d..edfdf9983 100644
--- a/web-app/src/app/event/event.service.ts
+++ b/web-app/src/app/event/event.service.ts
@@ -69,7 +69,8 @@ export class EventService {
}
onEventChanged(event: any) {
- event.added.forEach((added: any) => {
+ const { added = [], removed = [], foo = [] } = event
+ added.forEach((added: any) => {
if (!this.eventsById[added.id]) {
this.eventsById[added.id] = (JSON.parse(JSON.stringify(added)));
@@ -83,7 +84,7 @@ export class EventService {
this.fetchFeeds(added);
})
- event.removed.forEach((removed: any) => {
+ removed.forEach((removed: any) => {
this.observationsChanged({ removed: Object.values(this.eventsById[removed.id].filteredObservationsById) });
this.usersChanged({ removed: Object.values(this.eventsById[removed.id].filteredUsersById) });
this.layersChanged({ removed: Object.values(this.eventsById[removed.id].layersById) }, removed);
diff --git a/web-app/src/app/navigation/navigation.component.html b/web-app/src/app/navigation/navigation.component.html
index 8991f3010..c04d49683 100644
--- a/web-app/src/app/navigation/navigation.component.html
+++ b/web-app/src/app/navigation/navigation.component.html
@@ -1,7 +1,7 @@