Skip to content

Commit

Permalink
Merge branch 'make-client-about-page-customizable' into release/v3.30.2
Browse files Browse the repository at this point in the history
  • Loading branch information
esurface committed Dec 15, 2023
2 parents 939c7d9 + bd70f37 commit 0177c51
Show file tree
Hide file tree
Showing 75 changed files with 4,801 additions and 664 deletions.
54 changes: 30 additions & 24 deletions client/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -23,56 +23,62 @@

<paper-icon-button icon="more-vert" [matMenuTriggerFor]="appMenu" class="hamburger-menu"></paper-icon-button>
<mat-menu #appMenu="matMenu">
<button *ngIf="ready && appConfig && appConfig.kioskMode" (click)="kioskModeEnabled = true" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">screen_lock_landscape</mat-icon>
<span>{{'Kiosk Mode'|translate}}</span>
</button>
<button *ngIf="ready && !appConfig.hideProfile" routerLink="manage-user-profile" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">create</mat-icon>
<span>{{'Manage Profile'|translate}}</span>
<button *ngIf="isLoggedIn" mat-menu-item routerLink="/">
<mat-icon class="material-icons menu-tangy-location-list-icon">home</mat-icon>
<span>{{'Home'|translate}}</span>
</button>
<button *ngIf="!isLoggedIn" routerLink="" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">lock_open</mat-icon>
<span>{{'Login / Register'|translate}}</span>
</button>
<button *ngIf="isLoggedIn" routerLink="settings" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">settings</mat-icon>
<span>{{'Settings'|translate}}</span>
<button *ngIf="ready && appConfig && appConfig.kioskMode" (click)="kioskModeEnabled = true" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">screen_lock_landscape</mat-icon>
<span>{{'Kiosk Mode'|translate}}</span>
</button>
<button *ngIf="isLoggedIn" routerLink="/sync-records" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">autorenew</mat-icon>
<span>{{'Sync'|translate}}</span>
</button>
<button *ngIf="isLoggedIn" routerLink="/export-data" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">import_export</mat-icon>
<span>{{'Export Data'|translate}}</span>
</button>
<button mat-menu-item (click)="updateApp()" *ngIf="showUpdateAppLink">
<mat-icon class="material-icons menu-tangy-location-list-icon">cloud_download</mat-icon>
<span>{{'Update App'|translate}}</span>
</button>
<button mat-menu-item (click)="updateApp()" *ngIf="!showUpdateAppLink">
<mat-icon class="material-icons menu-tangy-location-list-icon">cloud_download</mat-icon>
<span>{{'Check for Update'|translate}}</span>
</button>
<button *ngIf="isLoggedIn" mat-menu-item routerLink="/maintenance">
<mat-icon class="material-icons menu-tangy-location-list-icon">build</mat-icon>
<span>{{'Maintenance'|translate}}</span>
<button *ngIf="ready && isLoggedIn && !appConfig.hideProfile" routerLink="manage-user-profile" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">create</mat-icon>
<span>{{'Manage Profile'|translate}}</span>
</button>
<button routerLink="settings" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">settings</mat-icon>
<span>{{'Settings'|translate}}</span>
</button>
<button routerLink="about" mat-menu-item>
<button *ngIf="ready && !appConfig.hideAbout" routerLink="about" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">info</mat-icon>
<span>{{'About'|translate}}</span>
</button>

<!-- Advanced Menu Items-->
<mat-divider *ngIf="isLoggedIn"></mat-divider>
<button *ngIf="isLoggedIn" mat-menu-item [matMenuTriggerFor]="advancedMenu">{{'Advanced'|translate}}
</button>
<mat-menu #advancedMenu="matMenu">
<button *ngIf="isLoggedIn" routerLink="/export-data" mat-menu-item>
<mat-icon class="material-icons menu-tangy-location-list-icon">import_export</mat-icon>
<span>{{'Export Data'|translate}}</span>
</button>
<button *ngIf="isLoggedIn" mat-menu-item routerLink="/maintenance">
<mat-icon class="material-icons menu-tangy-location-list-icon">build</mat-icon>
<span>{{'Maintenance'|translate}}</span>
</button>
</mat-menu>
<mat-divider *ngIf="isLoggedIn"></mat-divider>
<button *ngIf="isLoggedIn" mat-menu-item (click)="logout()">
<mat-icon class="material-icons menu-tangy-location-list-icon">exit_to_app</mat-icon>
<span>{{'Logout'|translate}}</span>
</button>

</mat-menu>


</mat-toolbar>

<div class="tangerine-app-content mat-typography " [ngClass]="{'has-topbar': !kioskModeEnabled}">
<router-outlet *ngIf="ready"></router-outlet>
</div>
4 changes: 3 additions & 1 deletion client/src/app/core/about/about.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { CommonModule } from '@angular/common';

import { AboutRoutingModule } from './about-routing.module';
import { AboutComponent } from './about/about.component';
import { TangyFormsModule } from '../../tangy-forms/tangy-forms.module';

@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
declarations: [AboutComponent],
imports: [
CommonModule,
AboutRoutingModule
AboutRoutingModule,
TangyFormsModule
]
})
export class AboutModule { }
36 changes: 2 additions & 34 deletions client/src/app/core/about/about/about.component.html
Original file line number Diff line number Diff line change
@@ -1,35 +1,3 @@
<div class="container">
<h1>About Tangerine</h1>
<p>
Tangerine is open source software designed for Android mobile devices. Its primary use is to enable capture of students’ responses in oral reading and mathematics skills assessments as well as interview responses and field observations.
</p>
<p>
Using Tangerine improves data quality and the efficiency of data collection and analysis. The software simplifies the preparation and implementation of field work, reduces student assessment times, reduces measurement and data entry errors, and eliminates manual data entry from paper forms. Tangerine is optimized for offline data collection in low-bandwidth environments and features powerful sync and data backup options.
</p>
<p>
Tangerine was developed by <a href="https://rti.org" target="_blank">RTI International</a>starting in 2011 with RTI's own internal research funds. RTI redesigned Tangerine and developed a new codebase using latest technologies in 2017/2018 with funding support from Google.org. Tangerine is available to the public through an open-source GNU General Public License. You can host it on your own server and modify its code as needed. The only requirement is that if you share your modified version publicly, you also need to share the modified source code with the larger community.
</p>
<p>
Since 2011, Tangerine has been used by over 60 organization, in over 70 countries and 100 languages. While originally developed for education, Tangerine is increasingly used also for interviews and field observations in the health, governance, and agricultural sectors.
</p>
<p>
For more information on Tangerine see <a href="http://www.tangerinecentral.org" target="_blank">http://www.tangerinecentral.org</a>.
</p>
<p>
For questions about Tangerine, contact <a href="mailto:[email protected]">[email protected]</a>.
</p>
</div>
<paper-card heading="Device Info" class="info" *ngIf="ready">
<div class="card-content">
<div class="info-item"><label>Server URL:</label> {{info.serverUrl}}</div>
<div class="info-item"><label>Group Name:</label> {{info.groupName}}</div>
<div class="info-item"><label>Group ID:</label> {{info.groupId}}</div>
<div class="info-item"><label>Build Channel:</label> {{info.buildChannel}}</div>
<div class="info-item"><label>Build ID:</label> {{info.buildId}}</div>
<div class="info-item"><label>Device ID:</label> {{info.deviceId}}</div>
<div class="info-item"><label>Tangerine Version:</label> {{info.tangerineVersion}}</div>
<div class="info-item"><label>Version Tag:</label> {{info.versionTag}}</div>
<div class="info-item"><label>Assigned Location:</label> <span [innerHTML]="info.assignedLocation"></span></div>
<div class="info-item"><label>Encryption Level:</label> {{info.encryptionLevel}}</div>
</div>
</paper-card>
<app-tangy-forms-player #formPlayer [preventSubmit]="true"></app-tangy-forms-player>
</div>
27 changes: 13 additions & 14 deletions client/src/app/core/about/about/about.component.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { _TRANSLATE } from 'src/app/shared/translation-marker';
import { AppInfo, DeviceService } from './../../../device/services/device.service';
import { Component, OnInit } from '@angular/core';
import { Component, OnInit, ViewChild } from '@angular/core';
import { TangyFormsPlayerComponent } from './../../../tangy-forms/tangy-forms-player/tangy-forms-player.component';
import { Subject } from 'rxjs';

@Component({
selector: 'app-about',
Expand All @@ -9,20 +10,18 @@ import { Component, OnInit } from '@angular/core';
})
export class AboutComponent implements OnInit {

info:AppInfo
ready = false

constructor(
private deviceService:DeviceService
) { }
appConfig = window['appConfig']
@ViewChild('formPlayer', {static: true}) formPlayer: TangyFormsPlayerComponent
$afterSubmit = new Subject()

async ngOnInit() {
const info = this.deviceService.getAppInfo()
this.info = {
...info,
deviceId: info.deviceId ? info.deviceId.substr(0,6) : _TRANSLATE('Log in to see Device ID')
}
this.ready = true
this.formPlayer.formId = "about";
this.formPlayer.$beforeSubmit.subscribe(() => { this.closeAbout() });
this.formPlayer.render()
}

closeAbout() {
window.location.href = this.appConfig.homeUrl
}

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
<mat-tab-group>
<mat-tab label="{{'Export Backup'|translate}}">
<mat-tab label="{{'Export Data'|translate}}">
<ng-template matTabContent>
<div class="container">
<mat-card>
<div class="mat-card-header-text">
{{'Export Backup'|translate}}
{{'Export Data'|translate}}
</div>
<mat-card-content class="card-content">
<p>{{'Export Data creates a backup of all of your records and saves it to your device.'|translate}}</p>
Expand Down
16 changes: 16 additions & 0 deletions client/src/app/core/settings/settings/settings.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,21 @@ <h1>{{'Class Configuration'|translate}}</h1>
</p>
</span>
</div>
<div #container>
<paper-card heading="Device Info" class="info" *ngIf="ready">
<div class="card-content">
<div class="info-item"><label>Server URL:</label> {{info.serverUrl}}</div>
<div class="info-item"><label>Group Name:</label> {{info.groupName}}</div>
<div class="info-item"><label>Group ID:</label> {{info.groupId}}</div>
<div class="info-item"><label>Build Channel:</label> {{info.buildChannel}}</div>
<div class="info-item"><label>Build ID:</label> {{info.buildId}}</div>
<div class="info-item"><label>Device ID:</label> {{info.deviceId}}</div>
<div class="info-item"><label>Tangerine Version:</label> {{info.tangerineVersion}}</div>
<div class="info-item"><label>Version Tag:</label> {{info.versionTag}}</div>
<div class="info-item"><label>Assigned Location:</label> <span [innerHTML]="info.assignedLocation"></span></div>
<div class="info-item"><label>Encryption Level:</label> {{info.encryptionLevel}}</div>
</div>
</paper-card>
</div>


13 changes: 12 additions & 1 deletion client/src/app/core/settings/settings/settings.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {TangyFormsInfoService} from "../../../tangy-forms/tangy-forms-info-servi
import {ClassFormService} from "../../../class/_services/class-form.service";
import {_TRANSLATE} from "../../../shared/translation-marker";
import {TangyFormResponse} from "../../../tangy-forms/tangy-form-response.class";
import { AppInfo, DeviceService } from './../../../device/services/device.service';

@Component({
selector: 'app-settings',
Expand All @@ -26,6 +27,9 @@ export class SettingsComponent implements OnInit, AfterContentInit {
selected = ''
classes: any;
showClassConfig = false;
info:AppInfo
ready = false;

constructor(
private http: HttpClient,
private variableService: VariableService,
Expand All @@ -34,6 +38,7 @@ export class SettingsComponent implements OnInit, AfterContentInit {
private dashboardService: DashboardService,
private tangyFormsInfoService: TangyFormsInfoService,
private classFormService: ClassFormService,
private deviceService:DeviceService
) { }

async ngOnInit(): Promise<void> {
Expand All @@ -42,7 +47,6 @@ export class SettingsComponent implements OnInit, AfterContentInit {
this.showClassConfig = true;
await this.classFormService.initialize();
this.classes = await this.dashboardService.getMyClasses();
console.log("Got classes")
}
}

Expand Down Expand Up @@ -100,6 +104,13 @@ export class SettingsComponent implements OnInit, AfterContentInit {
alert(t('Settings have been updated. You will now be redirected to log in.'))
window.location.href = window.location.href.replace(window.location.hash, 'index.html')
})

const info = this.deviceService.getAppInfo()
this.info = {
...info,
deviceId: info.deviceId ? info.deviceId.substr(0,6) : _TRANSLATE('Log in to see Device ID')
}
this.ready = true;
}

async toggleClass(id) {
Expand Down
2 changes: 2 additions & 0 deletions client/src/app/shared/_classes/app-config.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,8 @@ export class AppConfig {
centrallyManagedUserProfile = false
// Hides the user profile link to edit when on the Device.
hideProfile = false
// Hides the about page.
hideAbout = false
// When using Sync Protocol 2 and associating a new Device Account with a Device User, setting this to true will show them all Device Users synced
// down to the Device rather than filtering those Device Users based on the single Device Assignment.
disableDeviceUserFilteringByAssignment:boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,14 @@ export class TangyFormsPlayerComponent implements OnInit {
@Input('preventSubmit') preventSubmit = false
@Input('metadata') metadata: any

$rendered = new Subject()
$beforeSubmit = new Subject()
$submit = new Subject()
$afterSubmit = new Subject()
$resubmit = new Subject()
$afterResubmit = new Subject()
$saved = new Subject()
// making these public allows parent components to subscribe to them.
public readonly $rendered = new Subject()
public readonly $beforeSubmit = new Subject()
public readonly $submit = new Subject()
public readonly $afterSubmit = new Subject()
public readonly $resubmit = new Subject()
public readonly $afterResubmit = new Subject()
public readonly $saved = new Subject()
rendered = false
_inject = {}

Expand Down
17 changes: 17 additions & 0 deletions content-sets/attendance/client/forms.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,23 @@
"filterByLocation" : true
}
},
{
"title": "About",
"src": "./assets/about/form.html",
"id": "about",
"customSyncSettings" : {
"pull" : false,
"enabled" : false,
"excludeIncomplete" : false,
"push" : false
},
"couchdbSyncSettings" : {
"pull" : true,
"enabled" : true,
"push" : true,
"filterByLocation" : true
}
},
{
"id": "form-internal-behaviour",
"type": "form",
Expand Down
27 changes: 27 additions & 0 deletions content-sets/case-module-starter/client/forms.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,31 @@
[
{
"id" : "about",
"src" : "./assets/about/form.html",
"description" : "User Profile",
"listed" : false,
"title" : "About",
"type" : "about",
"searchSettings" : {
"shouldIndex" : false,
"primaryTemplate" : "",
"secondaryTemplate" : "",
"variablesToIndex" : [
]
},
"customSyncSettings": {
"enabled": false,
"push": false,
"pull": false,
"excludeIncomplete":false
},
"couchdbSyncSettings": {
"enabled": true,
"filterByLocation": true,
"push": true,
"pull": true
}
},
{
"id" : "user-profile",
"src" : "./assets/user-profile/form.html",
Expand Down
27 changes: 27 additions & 0 deletions content-sets/case-module/client/forms.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,31 @@
[
{
"id" : "about",
"src" : "./assets/about/form.html",
"description" : "User Profile",
"listed" : false,
"title" : "About",
"type" : "about",
"searchSettings" : {
"shouldIndex" : false,
"primaryTemplate" : "",
"secondaryTemplate" : "",
"variablesToIndex" : [
]
},
"customSyncSettings": {
"enabled": false,
"push": false,
"pull": false,
"excludeIncomplete":false
},
"couchdbSyncSettings": {
"enabled": true,
"filterByLocation": true,
"push": true,
"pull": true
}
},
{
"id" : "user-profile",
"src" : "./assets/user-profile/form.html",
Expand Down
Loading

0 comments on commit 0177c51

Please sign in to comment.