Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions client/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -121,12 +121,15 @@ export class AppComponent implements OnInit {
this.dialog.closeAll()
} else {
this.dialog.closeAll()
this.dialogRef = this.dialog.open(ProcessMonitorDialogComponent, {
const config = {
data: {
messages: this.processMonitorService.processes.map(process => process.description).reverse()
messages: this.processMonitorService.processes.map(process => process.description).reverse(),
cancellable: this.processMonitorService.processes.find(process => process.cancellable === false)?.cancellable,
cancelButtonDisplayDelay: this.processMonitorService.processes.find(process => process.cancelButtonDisplayDelay)?.cancelButtonDisplayDelay
},
disableClose: true
})
}
this.dialogRef = this.dialog.open(ProcessMonitorDialogComponent, config)
}
})
let appStartProcess = this.processMonitorService.start('init', "App starting...")
Expand Down
4 changes: 4 additions & 0 deletions client/src/app/case/components/case/case.component.css
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,7 @@ app-case-breadcrumb {
.text-right {
text-align: right;
}

.sync-status {
color:yellow;
}
1 change: 1 addition & 0 deletions client/src/app/case/components/case/case.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ <h1>
</h1>
<div secondary>
<span [innerHTML]="templateDescription|unsanitizeHtml" class="description"></span>
<span [innerHTML]="caseUpdated" class="sync-status"></span>
<div class="confirm-correct-case-prompt" *ngIf="caseService.openCaseConfirmed === false">
<paper-button class="button" (click)="onOpenCaseConfirmButtonClick()">Confirm</paper-button>
</div>
Expand Down
51 changes: 48 additions & 3 deletions client/src/app/case/components/case/case.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ import { ProcessMonitorService } from 'src/app/shared/_services/process-monitor.
import { _TRANSLATE } from 'src/app/shared/translation-marker';
import { MatDialog } from '@angular/material/dialog';
import { Subscription } from 'rxjs';
import {SyncCouchdbService} from "../../../sync/sync-couchdb.service";
import {AppConfigService} from "../../../shared/_services/app-config.service";
import {VariableService} from "../../../shared/_services/variable.service";

class CaseEventInfo {
caseEvents:Array<CaseEvent>;
Expand Down Expand Up @@ -37,14 +40,19 @@ export class CaseComponent implements AfterContentInit, OnDestroy {
window:any
caseService: CaseService
onOverlayCloseSubscription:Subscription
syncMessage: string = ""
caseUpdated: string = ""

constructor(
private route: ActivatedRoute,
private userService:UserService,
caseService: CaseService,
private processMonitorService:ProcessMonitorService,
public dialog: MatDialog,
private ref: ChangeDetectorRef
private ref: ChangeDetectorRef,
private appConfigService:AppConfigService,
private variableService: VariableService,
private syncCouchdbService:SyncCouchdbService
) {
ref.detach()
this.window = window
Expand All @@ -53,9 +61,45 @@ export class CaseComponent implements AfterContentInit, OnDestroy {
async ngAfterContentInit() {
// take over T.case.
window["T"].case = this.caseService
const process = this.processMonitorService.start('caseOpen', _TRANSLATE('Opening Case...'))
this.userRoles = await this.userService.getRoles()
const caseId = window.location.hash.split('/')[2]
this.syncMessage = ''
let process;
let onlineSync = false
const syncCaseIfOnline = await this.variableService.get('syncCaseIfOnline')
const appConfig = await this.appConfigService.getAppConfig()
if (appConfig.syncCaseIfOnline && syncCaseIfOnline) {
const online = window.navigator.onLine;
if (online) {
const opts = {
cancellable: false,
cancelButtonDisplayDelay: 10
}
process = this.processMonitorService.start('caseOpen', _TRANSLATE('Syncing and Opening Case...'), opts)
this.processMonitorService.change.subscribe((isDone) => {
if (isDone) {
// this.syncCouchdbService.cancel()
}
})
this.syncCouchdbService.syncMessage$.subscribe({
next: (progress) => {
if (progress) {
// this.syncMessage = progress.message || this.syncMessage
console.log(`progress message: ${progress.message} progress.pulled: ${progress.pulled}`)
if (progress.pulled) {
this.caseUpdated = "&nbsp;&nbsp;&nbsp;&nbsp; Case sync'd with server."
}
}
}
})
const pullReplicationStatus = await this.syncCouchdbService.pullStaleDocs([caseId], appConfig.groupId);
// this.processMonitorService.stop(process)
} else {
process = this.processMonitorService.start('caseOpen', _TRANSLATE('Opening Case...'))
}
} else {
process = this.processMonitorService.start('caseOpen', _TRANSLATE('Opening Case...'))
}
this.userRoles = await this.userService.getRoles()
// if (!this.caseService.case || caseId !== this.caseService.case._id) {
await this.caseService.load(caseId)
this.caseService.openCaseConfirmed = false
Expand All @@ -72,6 +116,7 @@ export class CaseComponent implements AfterContentInit, OnDestroy {
window.scrollTo(0, 0)
this.onOverlayCloseSubscription.unsubscribe()
})

this.processMonitorService.stop(process.id)
}

Expand Down
12 changes: 11 additions & 1 deletion client/src/app/case/services/case.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ import {Conflict} from "../classes/conflict.class";
import * as jsonpatch from "fast-json-patch";
import * as CryptoJS from 'crypto-js';
import { TangyFormResponse } from 'src/app/tangy-forms/tangy-form-response.class';
import {SyncCouchdbDetails, SyncCouchdbService, SyncSessionInfo} from "../../sync/sync-couchdb.service";
import PouchDB from 'pouchdb'
import {TangyFormsInfoService} from "../../tangy-forms/tangy-forms-info-service";
import {VariableService} from "../../shared/_services/variable.service";


@Injectable({
providedIn: 'root'
Expand Down Expand Up @@ -113,7 +118,10 @@ class CaseService {
private userService:UserService,
private appConfigService:AppConfigService,
private http:HttpClient,
private activityService:ActivityService
private activityService:ActivityService,
private syncCouchdbService: SyncCouchdbService,
private tangyFormsInfoService:TangyFormsInfoService,
private variableService: VariableService
) {
this.queryCaseEventDefinitionId = 'query-event';
this.queryEventFormDefinitionId = 'query-form-event';
Expand Down Expand Up @@ -1465,6 +1473,8 @@ class CaseService {
: (await this.tangyFormService.getResponse(formResponseId)).history
return history
}



}

Expand Down
28 changes: 26 additions & 2 deletions client/src/app/core/settings/settings/settings.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { HttpClient } from '@angular/common/http';
import { t } from 'tangy-form/util/t.js'
import {VariableService} from "../../../shared/_services/variable.service";
import {LanguagesService} from "../../../shared/_services/languages.service";
import {AppConfigService} from "../../../shared/_services/app-config.service";

@Component({
selector: 'app-settings',
Expand All @@ -18,17 +19,36 @@ export class SettingsComponent implements AfterContentInit {
languageCode = 'en'
usePouchDbLastSequenceTracking = false
selected = ''
syncCaseIfOnline = false

constructor(
private http: HttpClient,
private variableService: VariableService,
private languagesService:LanguagesService,
private appConfigService:AppConfigService
) { }

async ngAfterContentInit() {
this.languageCode = await this.variableService.get('languageCode')
this.usePouchDbLastSequenceTracking = await this.variableService.get('usePouchDbLastSequenceTracking')
this.selected = this.languageCode;
const translations = <Array<any>>await this.http.get('./assets/translations.json').toPromise();
const appConfig = await this.appConfigService.getAppConfig()
let syncCaseIfOnlineCheckbox;
this.syncCaseIfOnline = await this.variableService.get('syncCaseIfOnline')
if (appConfig.syncCaseIfOnline) {
if (typeof this.syncCaseIfOnline === 'undefined') {
this.syncCaseIfOnline = appConfig.syncCaseIfOnline
}
syncCaseIfOnlineCheckbox = `
<tangy-checkbox
value="${this.syncCaseIfOnline ? 'on' : ''}"
name="syncCaseIfOnline"
label="${t(` Sync case when opening a case.`)}"
>
</tangy-checkbox>
`
}
this.container.nativeElement.innerHTML = `
<tangy-form>
<tangy-form-item>
Expand All @@ -41,10 +61,10 @@ export class SettingsComponent implements AfterContentInit {
<tangy-checkbox
value="${this.usePouchDbLastSequenceTracking ? 'on' : ''}"
name="usePouchDbLastSequenceTracking"
label="${t(`Use PouchDB's last sequence tracking when syncing.`)}"
label="${t(` Use PouchDB's last sequence tracking when syncing.`)}"
>
</tangy-checkbox>

${syncCaseIfOnlineCheckbox}
<p>
${t('After submitting updated settings, you will be required to log in again.')}
</p>
Expand All @@ -60,6 +80,10 @@ export class SettingsComponent implements AfterContentInit {
? true
: false
await this.variableService.set('usePouchDbLastSequenceTracking', usePouchDbLastSequenceTracking)
const syncCaseIfOnline = response.inputsByName.syncCaseIfOnline.value
? true
: false
await this.variableService.set('syncCaseIfOnline', syncCaseIfOnline)
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')
})
Expand Down
5 changes: 4 additions & 1 deletion client/src/app/shared/_classes/app-config.class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ export class AppConfig {
initialBatchSize:number
// The max number of documents that will get written to disk during a sync. Tweak this down when using the SqlCipher encryption plugin to avoid database crashes.
writeBatchSize:number
// The number of documents processed in the changes feed per batch. This setting helps sites that experience crashes when indexing documents. Using this setting *will* slow sync optimization times.
changes_batch_size:number
// The number of IDs to read from the database at a time when doing a Comparison Sync.
compareLimit: number;
// List of views to skip optimization of after a sync.
Expand Down Expand Up @@ -102,12 +104,13 @@ export class AppConfig {

showQueries:boolean
showCaseReports:boolean
// Determines wether or not the Issues tab is shown on the case module's home screen.
// Determines whether the Issues tab should be shown on the case module's home screen.
showIssues:boolean
barcodeSearchMapFunction:string
// Determines if a "Create Issue" button appears when viewing submitted Event Forms.
allowCreationOfIssues:boolean
filterCaseEventScheduleByDeviceAssignedLocation:boolean = false
syncCaseIfOnline:boolean = false

//
// Tangerine Coach configuration.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@
</div>
<br>
<div id="actions">
<paper-button (click)="cancel()">Cancel</paper-button>
<paper-button (click)="cancel()" *ngIf="data.cancellable">Cancel</paper-button>
</div>
</mat-dialog-content>
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,54 @@ import { Component, Inject, Input, OnInit } from '@angular/core';
import { MatDialog, MAT_DIALOG_DATA } from '@angular/material/dialog';
import { _TRANSLATE } from '../../translation-marker';
import {ProcessMonitorService} from "../../_services/process-monitor.service";
// import { interval } from 'rxjs';
// import { take } from 'rxjs/operators';
import {timer, of, interval} from 'rxjs';
import {finalize, scan, take} from "rxjs/operators";

interface DialogData {
messages: Array<string>
cancellable: boolean
cancelButtonDisplayDelay: number
}

@Component({
selector: 'app-process-monitor-dialog',
templateUrl: 'process-monitor-dialog.component.html',
})
export class ProcessMonitorDialogComponent {
startTime: Date;
cancelButtonDisplayDelay: number;

constructor(
@Inject(MAT_DIALOG_DATA) public data: DialogData,
public processMonitorService: ProcessMonitorService,
public dialog: MatDialog
) {}

ngAfterContentInit() {
this.startTime = new Date()
this.cancelButtonDisplayDelay = this.data.cancelButtonDisplayDelay
if (this.data.cancellable === false && this.cancelButtonDisplayDelay && this.cancelButtonDisplayDelay > 0) {
console.log("Starting countdown for cancel button at " + this.startTime)
const counter$ = interval(1000); // rxjs creation operator - will fire every second
const numberOfSeconds = this.cancelButtonDisplayDelay
// credit: https://stackoverflow.com/a/65552351
const sub = counter$.pipe(
scan((accumulator, _current) => accumulator - 1, numberOfSeconds + 1),
take(numberOfSeconds + 1),
finalize(() => {
console.log('The cancel button should appear now.')
this.data.cancellable = true
})
)
sub.subscribe(next => {
console.log("Countdown to display Cancel button: " + next)
});
}

}

cancel() {
const confirmation = confirm(_TRANSLATE('Warning: Interrupting a process may lead to data corruption and data loss. Are you sure you want to continue?'))
if (confirmation) {
Expand Down
11 changes: 9 additions & 2 deletions client/src/app/shared/_services/process-monitor.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ export interface Process {
id:string
name:string
description:string
cancellable?:boolean
cancelButtonDisplayDelay?:number // in seconds
}

@Injectable({
Expand All @@ -30,11 +32,16 @@ class ProcessMonitorService {
? true
: false

start(name, description):Process {
start(name: { alpha: number, type: string } | string, description: string, opts?: {
cancellable?: boolean;
cancelButtonDisplayDelay?: number;
}) {
const process = <Process>{
id: UUID(),
name,
description
description,
cancellable: opts?.cancellable === false ? false : true,
cancelButtonDisplayDelay: opts?.cancelButtonDisplayDelay? opts?.cancelButtonDisplayDelay : null,
}

this.processes.push(process)
Expand Down
Loading