Skip to content

Commit

Permalink
Merge pull request #2975 from Tangerine-Community/2974_prcess_monitor…
Browse files Browse the repository at this point in the history
…ing_server

Implement on server the process-monitoring code from client PR #2825
  • Loading branch information
chrisekelley authored Oct 11, 2021
2 parents 9a63d35 + f6e51f0 commit 229fb7b
Show file tree
Hide file tree
Showing 11 changed files with 221 additions and 8 deletions.
33 changes: 33 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,38 @@
# What's new

## v3.19.2

__Fixes__
- Added process indicator when archiving, un-archiving, or deleting a case. Issue: [#2974](https://github.com/Tangerine-Community/Tangerine/issues/2974)

__Server upgrade instructions__

Reminder: Consider using the [Tangerine Upgrade Checklist](https://docs.tangerinecentral.org/system-administrator/upgrade-checklist.html) for making sure you test the upgrade safely.

```
cd tangerine
# Check the size of the data folder.
du -sh data
# Check disk for free space. Ensure there is at least 10GB + size of the data folder amount of free space in order to perform the upgrade.
df -h
# Turn off tangerine and database.
docker stop tangerine couchdb
# Create a backup of the data folder.
cp -r data ../data-backup-$(date "+%F-%T")
# Fetch the updates.
git fetch origin
git checkout v3.19.2
./start.sh v3.19.2
# Remove Tangerine's previous version Docker Image.
docker rmi tangerine/tangerine:v3.19.1
# Perform additional upgrades.
docker exec -it tangerine bash
# This will index all database views in all groups. It may take many hours if
# the project has a lot of data.
wedge pre-warm-views --target $T_COUCHDB_ENDPOINT
```


## v3.19.1

__Fixes__
Expand Down
3 changes: 2 additions & 1 deletion editor/src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,8 @@
</a>
</span>
</mat-toolbar>
<router-outlet></router-outlet>
<div #loadingUi class="tangerine-app-content mat-typography loading-ui-container" [hidden]="true"><loading-ui></loading-ui></div>
<router-outlet></router-outlet>
</mat-sidenav-content>
</mat-sidenav-container>
</div>
20 changes: 16 additions & 4 deletions editor/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { HttpClient } from '@angular/common/http';
import { TangyFormsInfoService } from './tangy-forms/tangy-forms-info-service';
import { TangyFormService } from './tangy-forms/tangy-form.service';
import { MenuService } from './shared/_services/menu.service';
import { Component, OnInit, ChangeDetectorRef, OnDestroy, ViewChild } from '@angular/core';
import {Component, OnInit, ChangeDetectorRef, OnDestroy, ViewChild, ElementRef} from '@angular/core';
import { Router } from '@angular/router';
import { TranslateService } from '@ngx-translate/core';
import { AuthenticationService } from './core/auth/_services/authentication.service';
Expand All @@ -17,6 +17,8 @@ import { _TRANSLATE } from './shared/_services/translation-marker';
import { NgxPermissionsService } from 'ngx-permissions';
import { CaseService } from './case/services/case.service';
import { Get } from 'tangy-form/helpers.js'
import {ProcessMonitorService} from "./shared/_services/process-monitor.service";
import {LoadingUiComponent} from "./core/loading-ui.component";

@Component({
selector: 'app-root',
Expand All @@ -38,7 +40,8 @@ export class AppComponent implements OnInit, OnDestroy {
isConfirmDialogActive = false;

@ViewChild('snav', {static: true}) snav: MatSidenav;

@ViewChild('loadingUi', { static: true }) loadingUi: ElementRef<LoadingUiComponent>;

private _mobileQueryListener: () => void;

constructor(
Expand All @@ -57,7 +60,8 @@ export class AppComponent implements OnInit, OnDestroy {
changeDetectorRef: ChangeDetectorRef,
media: MediaMatcher,
private appConfigService: AppConfigService,
private permissionService: NgxPermissionsService
private permissionService: NgxPermissionsService,
private processMonitorService:ProcessMonitorService
) {
translate.setDefaultLang('translation');
translate.use('translation');
Expand All @@ -82,7 +86,8 @@ export class AppComponent implements OnInit, OnDestroy {
case: caseService,
cases: casesService,
caseDefinition: caseDefinitionsService,
translate: window['t']
translate: window['t'],
process:processMonitorService
}
}

Expand Down Expand Up @@ -116,6 +121,13 @@ export class AppComponent implements OnInit, OnDestroy {
}
});
this.window.translation = await this.appConfigService.getTranslations();

this.processMonitorService.busy.subscribe((isBusy) => {
this.loadingUi.nativeElement.hidden = false
});
this.processMonitorService.done.subscribe((isDone) => {
this.loadingUi.nativeElement.hidden = true
});
}

ngOnDestroy(): void {
Expand Down
1 change: 1 addition & 0 deletions editor/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { MatIconModule } from '@angular/material/icon';
import { MatMenuModule } from '@angular/material/menu';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatToolbarModule } from '@angular/material/toolbar';
import './core/loading-ui.component'
import { NgxPermissionsModule } from 'ngx-permissions';
import { RouterModule } from '@angular/router';
export function HttpLoaderFactory(httpClient: HttpClient) {
Expand Down
9 changes: 9 additions & 0 deletions editor/src/app/case/components/case/case.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {Issue} from "../../classes/issue.class";
import {GroupIssuesService} from "../../../groups/services/group-issues.service";
import { _TRANSLATE } from 'src/app/shared/_services/translation-marker';
import { AuthenticationService } from 'src/app/core/auth/_services/authentication.service';
import {ProcessMonitorService} from "../../../shared/_services/process-monitor.service";

class CaseEventInfo {
caseEvents:Array<CaseEvent>;
Expand All @@ -34,6 +35,7 @@ export class CaseComponent implements AfterContentInit, OnDestroy {
issues:Array<Issue>
moment
groupId:string
process: any;

constructor(
private route: ActivatedRoute,
Expand All @@ -42,6 +44,7 @@ export class CaseComponent implements AfterContentInit, OnDestroy {
private ref: ChangeDetectorRef,
authenticationService: AuthenticationService,
private groupIssuesService:GroupIssuesService,
private processMonitorService: ProcessMonitorService
) {
ref.detach()
this.window = window
Expand Down Expand Up @@ -130,15 +133,19 @@ export class CaseComponent implements AfterContentInit, OnDestroy {
async archive() {
const confirmation = confirm(_TRANSLATE('Are you sure you want to archive this case?'))
if (confirmation) {
this.process = this.processMonitorService.start('archiving a case', 'Archiving a case.')
await this.caseService.archive()
this.processMonitorService.stop(this.process.id)
this.ref.detectChanges()
}
}

async unarchive() {
const confirmation = confirm(_TRANSLATE('Are you sure you want to unarchive this case?'))
if (confirmation) {
this.process = this.processMonitorService.start('unarchiving a case', 'Un-archiving a case.')
await this.caseService.unarchive()
this.processMonitorService.stop(this.process.id)
this.ref.detectChanges()
}
}
Expand All @@ -148,7 +155,9 @@ export class CaseComponent implements AfterContentInit, OnDestroy {
_TRANSLATE('Are you sure you want to delete this case? You will not be able to undo the operation')
);
if (confirmDelete) {
this.process = this.processMonitorService.start('deleting a case', 'Deleting a case.')
await this.caseService.delete()
this.processMonitorService.stop(this.process.id)
this.router.navigate(['groups', window.location.pathname.split('/')[2], 'data', 'cases'])
}
}
Expand Down
48 changes: 48 additions & 0 deletions editor/src/app/core/loading-ui.component.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import {LitElement, html, css} from 'lit-element';
import {customElement, property} from "lit-element/lib/decorators";
import '@polymer/paper-progress/paper-progress.js';

@customElement('loading-ui')
export class LoadingUiComponent extends LitElement {
static styles = css`
:host {
display: block;
}
.loading-text {
display: flex;
width: 50%;
height: 100px;
margin: auto;
margin-top: 200px;
border-radius: 10px;
border: 3px dashed #1c87c9;
align-items: center;
justify-content: center;
background: var(--primary-color);
color:white;
opacity: 100%;
font-size: x-large;
}
`;

render() {
return html`
<div class="loading-text" @click=${this.escape}>
<paper-progress indeterminate></paper-progress>
</div>
`;
}

escape() {
if (confirm(`${window['T'].translate('Please only leave this dialog if you believe there is an error in the application.')}`)) {
window['T'].process.clear()
}
}
}

declare global {
interface HTMLElementTagNameMap {
'loading-ui': LoadingUiComponent;
}
}

26 changes: 26 additions & 0 deletions editor/src/app/shared/_guards/process-guard.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {Injectable} from "@angular/core";
import {CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot} from "@angular/router";
import {Observable} from "rxjs";
import {ProcessMonitorService} from "../_services/process-monitor.service";
import {TangyFormsPlayerComponent} from "../../tangy-forms/tangy-forms-player/tangy-forms-player.component";

@Injectable()
export class ProcessGuard implements CanDeactivate<TangyFormsPlayerComponent> {
constructor(
private processMonitorService:ProcessMonitorService
) { }

canDeactivate(component: TangyFormsPlayerComponent,
currentRoute: ActivatedRouteSnapshot,
currentState: RouterStateSnapshot,
nextState?: RouterStateSnapshot): Observable<boolean>|Promise<boolean>|boolean {
// If no processes being busy
if (this.processMonitorService.processes.length > 0) {
return false;
} else {
return true;
}

}

}
58 changes: 58 additions & 0 deletions editor/src/app/shared/_services/process-monitor.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Subject } from 'rxjs';
import { v4 as UUID } from 'uuid';
import { Injectable } from '@angular/core';

interface Process {
id:string
name:string
description:string
}

@Injectable({
providedIn: 'root'
})
class ProcessMonitorService {

// When number of processes go from 0 to 1, this Subject will emit true.
busy = new Subject()
// When number of processes go to 0, this Subject will emit true.
done = new Subject()
// A list of the active processes.
processes:Array<Process> = []

constructor() {
}

hasNoProcesses = this.processes.length === 0
? true
: false

start(name, description):Process {
const process = <Process>{
id: UUID(),
name,
description
}

this.processes.push(process)
if (this.hasNoProcesses) {
this.busy.next(true)
}
return process
}

stop(pid:string) {
this.processes = this.processes.filter(process => process.id !== pid)
if (this.processes.length === 0) {
this.done.next(true)
}
}

clear() {
this.processes = []
this.done.next(true)
}

}

export { ProcessMonitorService };
6 changes: 5 additions & 1 deletion editor/src/app/shared/shared.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ import { HasSomePermissionsDirective } from '../core/auth/_directives/has-some-p
import { HasAllPermissionsDirective } from '../core/auth/_directives/has-all-permissions.directive';
import { DynamicTableComponent } from './_components/dynamic-table/dynamic-table.component';
import { MatMenuModule } from '@angular/material/menu';
import {ProcessMonitorService} from "./_services/process-monitor.service";
import {ProcessGuard} from "./_guards/process-guard.service";

@NgModule({
imports: [
Expand All @@ -29,7 +31,9 @@ import { MatMenuModule } from '@angular/material/menu';
providers: [
AppConfigService,
ServerConfigService,
LoginGuard
LoginGuard,
ProcessMonitorService,
ProcessGuard
],
exports: [
TranslateModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ import { TangyFormsInfoService } from 'src/app/tangy-forms/tangy-forms-info-serv
import { Component, ViewChild, ElementRef, Input } from '@angular/core';
import { _TRANSLATE } from '../../shared/translation-marker';
import { TangyFormService } from '../tangy-form.service';
const sleep = (milliseconds) => new Promise((res) => setTimeout(() => res(true), milliseconds))
import {ProcessMonitorService} from "../../shared/_services/process-monitor.service";

const sleep = (milliseconds) => new Promise((res) => setTimeout(() => res(true), milliseconds))

@Component({
selector: 'app-tangy-forms-player',
Expand Down Expand Up @@ -46,9 +47,12 @@ export class TangyFormsPlayerComponent {

window:any;
@ViewChild('container', {static: true}) container: ElementRef;
process: any;

constructor(
private tangyFormsInfoService:TangyFormsInfoService,
private tangyFormService: TangyFormService
private tangyFormService: TangyFormService,
private processMonitorService: ProcessMonitorService,
) {
this.window = window
}
Expand Down Expand Up @@ -136,6 +140,11 @@ export class TangyFormsPlayerComponent {
this.throttledSaveResponse(response)
})
}
formEl.addEventListener('before-submit', async (event) => {
if (this.preventSubmit) event.preventDefault()
this.process = this.processMonitorService.start('saving-a-tangy-form', 'Updating a form response.')
this.$submit.next(true)
})
formEl.addEventListener('submit', async (event) => {
if (this.preventSubmit) event.preventDefault()
while (this.throttledSaveFiring === true) {
Expand All @@ -148,6 +157,7 @@ export class TangyFormsPlayerComponent {
while (this.throttledSaveFiring === true) {
await sleep(1000)
}
this.processMonitorService.stop(this.process.id)
this.$afterSubmit.next(true)
})
formEl.addEventListener('resubmit', async (event) => {
Expand Down
11 changes: 11 additions & 0 deletions editor/src/styles/styles.scss
Original file line number Diff line number Diff line change
Expand Up @@ -306,3 +306,14 @@ mat-card-content > * {
.icon-list-item>mwc-icon{
color: var(--primary-color) !important;
}

.loading-ui-container {
position: fixed;
display: block;
height: 100%;
width: 100%;
opacity: 0.7;
background-color: #fff;
top: 0;
z-index: 100;
}

0 comments on commit 229fb7b

Please sign in to comment.