From 8271eb00ac87fd8384a59a591cbc122691a6d21f Mon Sep 17 00:00:00 2001 From: Karan Takalkar Date: Thu, 19 Nov 2020 12:03:12 +0530 Subject: [PATCH] feat: add support for runtime server url changes (#1271) Fixes: #786 Fixes: #1229 --- .../client-address-step.component.ts | 8 ++-- .../client-preview-step.component.ts | 2 +- src/app/login/login.component.html | 2 + src/app/login/login.component.ts | 5 +++ src/app/settings/settings.service.ts | 33 ++++++++++++++ .../server-selector.component.html | 8 ++++ .../server-selector.component.scss | 0 .../server-selector.component.spec.ts | 25 +++++++++++ .../server-selector.component.ts | 45 +++++++++++++++++++ src/app/shared/shared.module.ts | 5 ++- src/app/web-app.component.ts | 10 +++++ src/environments/.env.ts | 3 +- src/environments/environment.prod.ts | 5 ++- src/environments/environment.ts | 5 ++- 14 files changed, 145 insertions(+), 11 deletions(-) create mode 100644 src/app/shared/server-selector/server-selector.component.html create mode 100644 src/app/shared/server-selector/server-selector.component.scss create mode 100644 src/app/shared/server-selector/server-selector.component.spec.ts create mode 100644 src/app/shared/server-selector/server-selector.component.ts diff --git a/src/app/clients/client-stepper/client-address-step/client-address-step.component.ts b/src/app/clients/client-stepper/client-address-step/client-address-step.component.ts index 513e66712..0f03248d5 100644 --- a/src/app/clients/client-stepper/client-address-step/client-address-step.component.ts +++ b/src/app/clients/client-stepper/client-address-step/client-address-step.component.ts @@ -120,7 +120,7 @@ export class ClientAddressStepComponent { * @param {any} address Address */ getSelectedValue(fieldName: any, fieldId: any) { - return (this.clientTemplate.address[fieldName].find((fieldObj: any) => fieldObj.id === fieldId)); + return (this.clientTemplate.address[0][fieldName].find((fieldObj: any) => fieldObj.id === fieldId)); } /** @@ -133,7 +133,7 @@ export class ClientAddressStepComponent { controlName: 'addressTypeId', label: 'Address Type', value: address ? address.addressTypeId : '', - options: { label: 'name', value: 'id', data: this.clientTemplate.address.addressTypeIdOptions }, + options: { label: 'name', value: 'id', data: this.clientTemplate.address[0].addressTypeIdOptions }, order: 1, required: true }) : null); @@ -184,7 +184,7 @@ export class ClientAddressStepComponent { controlName: 'stateProvinceId', label: 'State / Province', value: address ? address.stateProvinceId : '', - options: { label: 'name', value: 'id', data: this.clientTemplate.address.stateProvinceIdOptions }, + options: { label: 'name', value: 'id', data: this.clientTemplate.address[0].stateProvinceIdOptions }, order: 8 }) : null); formfields.push(this.isFieldEnabled('countyDistrict') ? new InputBase({ @@ -198,7 +198,7 @@ export class ClientAddressStepComponent { controlName: 'countryId', label: 'Country', value: address ? address.countryId : '', - options: { label: 'name', value: 'id', data: this.clientTemplate.address.countryIdOptions }, + options: { label: 'name', value: 'id', data: this.clientTemplate.address[0].countryIdOptions }, order: 10 }) : null); formfields.push(this.isFieldEnabled('postalCode') ? new InputBase({ diff --git a/src/app/clients/client-stepper/client-preview-step/client-preview-step.component.ts b/src/app/clients/client-stepper/client-preview-step/client-preview-step.component.ts index 07efeece3..d8d63e684 100644 --- a/src/app/clients/client-stepper/client-preview-step/client-preview-step.component.ts +++ b/src/app/clients/client-stepper/client-preview-step/client-preview-step.component.ts @@ -30,7 +30,7 @@ export class ClientPreviewStepComponent { * @param {any} fieldId Field Id */ getSelectedValue(fieldName: any, fieldId: any) { - return (this.clientTemplate.address[fieldName].find((fieldObj: any) => fieldObj.id === fieldId)); + return (this.clientTemplate.address[0][fieldName].find((fieldObj: any) => fieldObj.id === fieldId)); } /** diff --git a/src/app/login/login.component.html b/src/app/login/login.component.html index 602f556c7..c3689fc89 100644 --- a/src/app/login/login.component.html +++ b/src/app/login/login.component.html @@ -34,6 +34,8 @@
+
+
diff --git a/src/app/login/login.component.ts b/src/app/login/login.component.ts index d31aedec7..7d0a0a844 100644 --- a/src/app/login/login.component.ts +++ b/src/app/login/login.component.ts @@ -11,6 +11,9 @@ import { Alert } from '../core/alert/alert.model'; /** Custom Services */ import { AlertService } from '../core/alert/alert.service'; +/** Environment Imports */ +import { environment } from '../../environments/environment'; + /** * Login component. */ @@ -21,6 +24,8 @@ import { AlertService } from '../core/alert/alert.service'; }) export class LoginComponent implements OnInit, OnDestroy { + public environment = environment; + /** True if password requires a reset. */ resetPassword = false; /** True if user requires two factor authentication. */ diff --git a/src/app/settings/settings.service.ts b/src/app/settings/settings.service.ts index 375da4f22..32703ba53 100644 --- a/src/app/settings/settings.service.ts +++ b/src/app/settings/settings.service.ts @@ -1,6 +1,9 @@ /** Angular Imports */ import { Injectable } from '@angular/core'; +/** Environment Imports */ +import { environment } from '../../environments/environment'; + /** * Settings Service */ @@ -27,6 +30,22 @@ export class SettingsService { localStorage.setItem('mifosXLanguage', JSON.stringify(language)); } + /** + * Sets server URL setting throughout the app. + * @param {string} url URL + */ + setServer(url: string) { + localStorage.setItem('mifosXServerURL', JSON.stringify(url)); + } + + /** + * Sets server URL setting throughout the app. + * @param {string[]} list List of default servers + */ + setServers(list: string[]) { + localStorage.setItem('mifosXServers', JSON.stringify(list)); + } + /** * Returns date format setting. */ @@ -41,4 +60,18 @@ export class SettingsService { return JSON.parse(localStorage.getItem('mifosXLanguage')); } + /** + * Returns list of default server + */ + get servers() { + return JSON.parse(localStorage.getItem('mifosXServers')); + } + + /** + * Returns server setting + */ + get server() { + return environment.baseApiUrl; + } + } diff --git a/src/app/shared/server-selector/server-selector.component.html b/src/app/shared/server-selector/server-selector.component.html new file mode 100644 index 000000000..d98c450d0 --- /dev/null +++ b/src/app/shared/server-selector/server-selector.component.html @@ -0,0 +1,8 @@ + + Server + + + {{ server }} + + + diff --git a/src/app/shared/server-selector/server-selector.component.scss b/src/app/shared/server-selector/server-selector.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/src/app/shared/server-selector/server-selector.component.spec.ts b/src/app/shared/server-selector/server-selector.component.spec.ts new file mode 100644 index 000000000..a28a27db5 --- /dev/null +++ b/src/app/shared/server-selector/server-selector.component.spec.ts @@ -0,0 +1,25 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; + +import { ServerSelectorComponent } from './server-selector.component'; + +describe('ServerSelectorComponent', () => { + let component: ServerSelectorComponent; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ ServerSelectorComponent ] + }) + .compileComponents(); + })); + + beforeEach(() => { + fixture = TestBed.createComponent(ServerSelectorComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/shared/server-selector/server-selector.component.ts b/src/app/shared/server-selector/server-selector.component.ts new file mode 100644 index 000000000..7267c49e9 --- /dev/null +++ b/src/app/shared/server-selector/server-selector.component.ts @@ -0,0 +1,45 @@ +/** Angular Imports */ +import { Component, OnInit } from '@angular/core'; +import { FormControl } from '@angular/forms'; + +/** Custom Services */ +import { SettingsService } from 'app/settings/settings.service'; + +/** + * Server Selector Component + */ +@Component({ + selector: 'mifosx-server-selector', + templateUrl: './server-selector.component.html', + styleUrls: ['./server-selector.component.scss'] +}) +export class ServerSelectorComponent implements OnInit { + + /** Server Settings. */ + servers: string[]; + + /** Server Setting */ + serverSelector = new FormControl(''); + + /** + * @param {SettingsService} settingsService Settings Service + */ + constructor(private settingsService: SettingsService) { } + + ngOnInit(): void { + this.servers = this.settingsService.servers; + this.serverSelector.patchValue(this.settingsService.server); + this.buildDependencies(); + } + + /** + * Subscribe to value changes. + */ + buildDependencies() { + this.serverSelector.valueChanges.subscribe((url: string) => { + this.settingsService.setServer(url); + window.location.reload(); // refreshes the environment.ts. + }); + } + +} diff --git a/src/app/shared/shared.module.ts b/src/app/shared/shared.module.ts index fff7447d1..ded7a5102 100644 --- a/src/app/shared/shared.module.ts +++ b/src/app/shared/shared.module.ts @@ -20,6 +20,7 @@ import { ErrorDialogComponent } from './error-dialog/error-dialog.component'; import { NotificationsTrayComponent } from './notifications-tray/notifications-tray.component'; import { SearchToolComponent } from './search-tool/search-tool.component'; import { KeyboardShortcutsDialogComponent } from './keyboard-shortcuts-dialog/keyboard-shortcuts-dialog.component'; +import { ServerSelectorComponent } from './server-selector/server-selector.component'; /** Custom Modules */ import { IconsModule } from './icons.module'; @@ -53,12 +54,14 @@ import { MaterialModule } from './material.module'; KeyboardShortcutsDialogComponent, ErrorDialogComponent, NotificationsTrayComponent, - SearchToolComponent + SearchToolComponent, + ServerSelectorComponent ], exports: [ FileUploadComponent, FooterComponent, LanguageSelectorComponent, + ServerSelectorComponent, ThemePickerComponent, NotificationsTrayComponent, SearchToolComponent, diff --git a/src/app/web-app.component.ts b/src/app/web-app.component.ts index 252023930..386d75e83 100644 --- a/src/app/web-app.component.ts +++ b/src/app/web-app.component.ts @@ -146,6 +146,16 @@ export class WebAppComponent implements OnInit { if (!localStorage.getItem('mifosXDateFormat')) { this.settingsService.setDateFormat('dd MMMM yyyy'); } + if (!localStorage.getItem('mifosXServers')) { + this.settingsService.setServers([ + 'https://dev.mifos.io', + 'https://demo.mifos.io', + 'https://staging.mifos.io', + 'https://mobile.mifos.io', + 'https://demo.fineract.dev', + 'https://localhost:8443' + ]); + } } logout() { diff --git a/src/environments/.env.ts b/src/environments/.env.ts index 6256dff56..34d9b36a8 100644 --- a/src/environments/.env.ts +++ b/src/environments/.env.ts @@ -1,3 +1,4 @@ export default { - 'npm_package_version': '0.0.0' + 'mifos_x_version': '0.0.0', + 'allow_switching_backend_instance': true }; diff --git a/src/environments/environment.prod.ts b/src/environments/environment.prod.ts index 9843d245b..ff288db37 100644 --- a/src/environments/environment.prod.ts +++ b/src/environments/environment.prod.ts @@ -3,9 +3,10 @@ import env from './.env'; export const environment = { production: true, - version: env.npm_package_version, + version: env.mifos_x_version, fineractPlatformTenantId: 'default', // For connecting to server running elsewhere update the tenant identifier - baseApiUrl: 'https://demo.fineract.dev', // For connecting to server running elsewhere update the base API URL + baseApiUrl: JSON.parse(localStorage.getItem('mifosXServerURL')) || 'https://demo.fineract.dev', // For connecting to server running elsewhere update the base API URL + allowServerSwitch: env.allow_switching_backend_instance, apiProvider: '/fineract-provider/api', apiVersion: '/v1', serverUrl: '', diff --git a/src/environments/environment.ts b/src/environments/environment.ts index 9722d2536..be1503bfb 100644 --- a/src/environments/environment.ts +++ b/src/environments/environment.ts @@ -8,9 +8,10 @@ import env from './.env'; export const environment = { production: false, - version: env.npm_package_version + '-dev', + version: env.mifos_x_version + '-dev', fineractPlatformTenantId: 'default', // For connecting to server running elsewhere update the tenant identifier - baseApiUrl: 'https://dev.mifos.io', // For connecting to server running elsewhere update the base API URL + baseApiUrl: JSON.parse(localStorage.getItem('mifosXServerURL')) || 'https://dev.mifos.io', // For connecting to server running elsewhere update the base API URL + allowServerSwitch: env.allow_switching_backend_instance, apiProvider: '/fineract-provider/api', apiVersion: '/v1', serverUrl: '',