Skip to content

Commit

Permalink
feat(frontend): make environment tag configurable (#135)
Browse files Browse the repository at this point in the history
* feat(frontend): make environemt tag configurable

resolves #100

* fix(build): fix build errors

- Angular AoT needs variables in module to be foldable

* test(frontend-unit):  Fix Unit tests

* chore(format): fix missing semicolon

* chore(refactor): improve clarity of the statement

* fix(frontend-navigation): add return statement
  • Loading branch information
DanielHabenicht authored Aug 9, 2019
1 parent 594ce5e commit 10d47be
Show file tree
Hide file tree
Showing 19 changed files with 106 additions and 112 deletions.
2 changes: 2 additions & 0 deletions Phonebook.Demo/values.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ contactEmail: &contactEmail '[email protected]'
ravenUrl: 'undefined'
employeePictureEndpoint: 'undefined'
assetsEndpoint: 'https://demo-phonebook.me/assets'
environment: 'preview'
environmentTag: 'demo'

frontend:
replicaCount: 1
Expand Down
2 changes: 2 additions & 0 deletions Phonebook.Frontend/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ services:
dockerfile: Dockerfile
environment:
DEBUG: 'true'
ENVIRONMENT: 'development'
ENVIRONMENT_TAG: 'docker'
BASE_URL: 'http://localhost/'
SERVER_NAME: 'localhost'
CONTACT_URL: 'https://example.com'
Expand Down
3 changes: 2 additions & 1 deletion Phonebook.Frontend/globals.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
var ENV = {
employeePicturesEndpoint: 'https://employee-pictures.example.com'
employeePicturesEndpoint: 'https://employee-pictures.example.com',
environment: 'production'
};
4 changes: 1 addition & 3 deletions Phonebook.Frontend/src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import { DashboardComponent } from 'src/app/pages/dashboard/dashboard.component'
import { SettingsModule } from 'src/app/pages/settings/settings.module';
import { UserPagesModule } from 'src/app/pages/users/user-pages.module';
import { ApiModule } from 'src/app/services/api/api.module';
import { EnvironmentService } from 'src/app/services/environment.service';
import { MailService } from 'src/app/services/mail.service';
import { ReleaseInfoService } from 'src/app/services/release-info.service';
import { ServiceWorkerService } from 'src/app/services/service-worker.service';
Expand Down Expand Up @@ -105,8 +104,7 @@ declare const require;
ReleaseInfoService,
ThemeService,
I18n,
ColumnTranslate,
EnvironmentService
ColumnTranslate
],
bootstrap: [AppComponent]
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Location } from '@angular/common';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { TestBed } from '@angular/core/testing';
import { Environment, EnvironmentService } from 'src/app/services/environment.service';
import { FeatureFlagService } from './feature-flag.service';

describe('FeatureFlagService', () => {
Expand All @@ -14,11 +13,7 @@ describe('FeatureFlagService', () => {
TestBed.configureTestingModule({
schemas: [NO_ERRORS_SCHEMA],
imports: [HttpClientTestingModule],
providers: [
FeatureFlagService,
{ provide: Location, useClass: LocationMock },
{ provide: EnvironmentService, useClass: MockEnviromentService }
]
providers: [FeatureFlagService, { provide: Location, useClass: LocationMock }]
}).compileComponents();
httpMock = TestBed.get(HttpTestingController);
featureFlagServiceTest = TestBed.get(FeatureFlagService);
Expand Down Expand Up @@ -103,9 +98,3 @@ class LocationMock {
return '/' + url;
}
}

class MockEnviromentService {
public getEnvironment(): Environment {
return Environment.production;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { HttpClient } from '@angular/common/http';
import { EventEmitter, Injectable } from '@angular/core';
import { combineLatest, ConnectableObservable, Observable, of } from 'rxjs';
import { catchError, map, publishReplay, startWith } from 'rxjs/operators';
import { Environment, EnvironmentService } from 'src/app/services/environment.service';
import { Environment } from 'src/environments/EnvironmentInterfaces';
import { runtimeEnvironment } from 'src/environments/runtime-environment';

@Injectable()
export class FeatureFlagService {
Expand All @@ -13,11 +14,7 @@ export class FeatureFlagService {
};
private flagOverwriteEmitter: EventEmitter<any> = new EventEmitter<any>();

constructor(
private httpClient: HttpClient,
private location: Location,
private environmentService: EnvironmentService
) {}
constructor(private httpClient: HttpClient, private location: Location) {}

/**
* Returns the Feature Flags.
Expand Down Expand Up @@ -69,7 +66,7 @@ export class FeatureFlagService {
}
// Flags with 0 are disabled by default, but can be enabled by the user
if (value === 0) {
if (this.environmentService.getEnvironment() === Environment.production) {
if (runtimeEnvironment.environment === Environment.production) {
return false;
} else {
return true;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { Environment, EnvironmentService } from 'src/app/services/environment.service';
import { RuntimeEnvironmentInterface } from 'src/environments/EnvironmentInterfaces';
import { Environment, RuntimeEnvironmentInterface } from 'src/environments/EnvironmentInterfaces';
import { runtimeEnvironment } from 'src/environments/runtime-environment';

@Component({
Expand All @@ -11,9 +10,9 @@ import { runtimeEnvironment } from 'src/environments/runtime-environment';
export class PageInformationComponent implements OnInit {
public isPreview: boolean = true;
public runtimeEnvironment: RuntimeEnvironmentInterface = runtimeEnvironment;
constructor(private environmentService: EnvironmentService) {}
constructor() {}

public ngOnInit() {
this.isPreview = this.environmentService.getEnvironment() === Environment.production ? false : true;
this.isPreview = runtimeEnvironment.environment === Environment.production ? false : true;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { MatCardModule } from '@angular/material/card';
import { MatListModule } from '@angular/material/list';
import { RouterModule, Routes } from '@angular/router';
import { PageInformationComponent } from 'src/app/pages/page-information/page-information.component';
import { EnvironmentService } from 'src/app/services/environment.service';
import { FeedbackDrawerModule } from 'src/app/shared/directives/feedback-drawer/feedback-drawer.module';

const routes: Routes = [
Expand All @@ -25,6 +24,6 @@ const routes: Routes = [
MatListModule,
FeedbackDrawerModule
],
providers: [EnvironmentService]
providers: []
})
export class PageInformationModule {}
37 changes: 0 additions & 37 deletions Phonebook.Frontend/src/app/services/environment.service.ts

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -82,19 +82,10 @@
>
<span
class="beta-tag mat-headline pb-hide-below-small"
*ngIf="environmentService.getEnvironment() == Environment.preview"
i18n="NavigationBar|Tag on Application Name@@navigationBarApplicationNameTag"
>Preview</span
>
<span
class="beta-tag mat-headline pb-hide-below-small"
*ngIf="environmentService.getEnvironment() == Environment.local"
>Dev</span
>
<span
class="version pb-hide-below-small"
*ngIf="environmentService.getEnvironment() != Environment.local"
*ngIf="currentEnvironment != Environment.production"
>{{ getEnvironmentTag() }}</span
>
<span class="version pb-hide-below-small" *ngIf="currentEnvironment != Environment.development">
v{{ version }}</span
>
</button>
Expand Down Expand Up @@ -172,10 +163,8 @@
<!-- Dummy for Layout -->
</div>
<div>
<span *ngIf="environmentService.getEnvironment() != Environment.local">
<span *ngIf="environment.production">Prod</span><span *ngIf="!environment.production">Dev</span> - v{{
version
}}
<span *ngIf="currentEnvironment != Environment.development">
<span>{{ getEnvironmentTag() }}</span> - v{{ version }}
-
<a href="https://github.com/T-Systems-MMS/phonebook/commit/{{ versionHashLong }}">{{ versionHashShort }}</a>
</span>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { Component, OnInit, OnDestroy } from '@angular/core';
import { environment } from 'src/environments/environment';
import { Person } from 'src/app/shared/models';
import { untilComponentDestroyed } from 'ng2-rx-componentdestroyed';
import { VERSION, HASH_SHORT, HASH_LONG } from 'src/environments/version';
import { EnvironmentInterface } from 'src/environments/EnvironmentInterfaces';
import { CurrentUserService } from 'src/app/services/api/current-user.service';
import { EnvironmentService, Environment } from 'src/app/services/environment.service';
import { Router, NavigationEnd } from '@angular/router';
import { Component, OnDestroy, OnInit } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { TableSettingsDialog } from 'src/app/modules/table/dialogs/table-settings-dialog/table-settings.dialog';
import { of, Observable } from 'rxjs';
import { NavigationEnd, Router } from '@angular/router';
import { I18n } from '@ngx-translate/i18n-polyfill';
import { Select } from '@ngxs/store';
import { TableState } from 'src/app/shared/states';
import { untilComponentDestroyed } from 'ng2-rx-componentdestroyed';
import { Observable } from 'rxjs';
import { filter, map } from 'rxjs/operators';
import { I18n } from '@ngx-translate/i18n-polyfill';
import { FeatureFlagService } from 'src/app/modules/feature-flag/feature-flag.service';
import { TableSettingsDialog } from 'src/app/modules/table/dialogs/table-settings-dialog/table-settings.dialog';
import { CurrentUserService } from 'src/app/services/api/current-user.service';
import { Person } from 'src/app/shared/models';
import { TableState } from 'src/app/shared/states';
import { environment } from 'src/environments/environment';
import { Environment, EnvironmentInterface } from 'src/environments/EnvironmentInterfaces';
import { runtimeEnvironment } from 'src/environments/runtime-environment';
import { HASH_LONG, HASH_SHORT, VERSION } from 'src/environments/version';

@Component({
selector: 'app-navigation',
Expand All @@ -28,6 +28,7 @@ export class NavigationComponent implements OnInit, OnDestroy {
public versionHashLong: typeof HASH_LONG = HASH_LONG;
public environment: EnvironmentInterface = environment;
public Environment: typeof Environment = Environment;
public currentEnvironment: Environment = runtimeEnvironment.environment;

@Select(TableState.resultCount)
public tableResultCount$: Observable<number>;
Expand All @@ -36,7 +37,6 @@ export class NavigationComponent implements OnInit, OnDestroy {
public currentUser: Person | null = null;
constructor(
private currentUserService: CurrentUserService,
public environmentService: EnvironmentService,
private router: Router,
public dialog: MatDialog,
public i18n: I18n,
Expand Down Expand Up @@ -93,6 +93,23 @@ export class NavigationComponent implements OnInit, OnDestroy {
);
}

public getEnvironmentTag(): string {
if (runtimeEnvironment.environmentTag === '') {
switch (this.currentEnvironment) {
case Environment.development:
return 'dev';
case Environment.preview:
return 'preview';
case Environment.production:
return 'prod';
default:
return 'not set';
}
} else {
return runtimeEnvironment.environmentTag;
}
}

public navigateToOwnProfile() {
if (this.currentUser != null) {
this.router.navigateByUrl(`/user/${this.currentUser.Id}`);
Expand Down
6 changes: 3 additions & 3 deletions Phonebook.Frontend/src/app/shared/error/error.module.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
import { ErrorHandler, ModuleWithProviders, NgModule } from '@angular/core';
import * as Raven from 'raven-js';
import { environment } from 'src/environments/environment.debug';
import { Environment } from 'src/environments/EnvironmentInterfaces';
import { runtimeEnvironment } from 'src/environments/runtime-environment';
import { VERSION } from 'src/environments/version';

if (runtimeEnvironment.ravenURL) {
try {
Raven.config(runtimeEnvironment.ravenURL, {
autoBreadcrumbs: true,
environment: environment.production ? 'production' : 'preview',
environment: runtimeEnvironment.environment.toString(),
release: VERSION,
sanitizeKeys: ['currentUserName', 'userName'],
shouldSendCallback: function(data) {
Expand All @@ -27,7 +27,7 @@ export class GlobalErrorHandler implements ErrorHandler {
return;
}

if (environment.production) {
if (runtimeEnvironment.environment !== Environment.development) {
// App is in Production
if (runtimeEnvironment.ravenURL) {
// Raven enabled
Expand Down
28 changes: 27 additions & 1 deletion Phonebook.Frontend/src/environments/EnvironmentInterfaces.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
export interface EnvironmentInterface {
/**
* Switch for defining the current Environment
* Determines if this is a production build or not.
* Should only be used as a last resort for AoT-Compilation errors.
*/
production: boolean;
/**
Expand All @@ -14,6 +15,14 @@ export interface EnvironmentInterface {
}

export interface RuntimeEnvironmentInterface {
/**
* The Environment Tag is displayed right next to the title of the page, e.g. "preview", "dev"
*/
readonly environmentTag: string;
/**
* The Environment the app is living in, by default it is development
*/
readonly environment: Environment;
/**
* The URL to the Raven Instance, in order to report Bugs.
* If set to null Raven does not get activated.
Expand Down Expand Up @@ -41,3 +50,20 @@ export interface RuntimeEnvironmentInterface {
**/
roomPlanningToolUrl: string | null;
}

export enum Environment {
/**
* Local or pr-preview environment - unstable.
*/
development = 'development',
/**
* An Environment that might have Bugs and has Preview Features enabled by default
* e.g. Early adopters or Staging Environment
*/
preview = 'preview',
/**
* An Environment that is stable.
* Preview features can be enabled by the user himself.
*/
production = 'production'
}
4 changes: 3 additions & 1 deletion Phonebook.Frontend/src/environments/runtime-environment.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { RuntimeEnvironmentInterface } from 'src/environments/EnvironmentInterfaces';
import { Environment, RuntimeEnvironmentInterface } from 'src/environments/EnvironmentInterfaces';

declare const ENV: RuntimeEnvironmentInterface;
export const runtimeEnvironment: RuntimeEnvironmentInterface = {
environment: ENV.environment.toString() !== '${ENVIRONMENT}' ? ENV.environment : Environment.development,
environmentTag: ENV.environmentTag !== '${ENVIRONMENT_TAG}' ? ENV.environmentTag : '',
ravenURL: ENV.ravenURL !== '${RAVEN_URL}' ? ENV.ravenURL : null,
employeePicturesEndpoint:
ENV.employeePicturesEndpoint !== '${EMPLOYEE_PICTURES_ENDPOINT}' ? ENV.employeePicturesEndpoint : 'TODO',
Expand Down
2 changes: 2 additions & 0 deletions Phonebook.Frontend/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
<title>Phonebook</title>
<script>
window.ENV = {
environment: '${ENVIRONMENT}',
environmentTag: '${ENVIRONMENT_TAG}',
ravenURL: '${RAVEN_URL}',
employeePicturesEndpoint: '${EMPLOYEE_PICTURES_ENDPOINT}',
oldEmployeePictureEndpoint: '${OLD_EMPLOYEE_PICTURE_ENDPOINT}',
Expand Down
4 changes: 3 additions & 1 deletion Phonebook.Frontend/src/main.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { Environment } from 'src/environments/EnvironmentInterfaces';
import { runtimeEnvironment } from 'src/environments/runtime-environment';
import { migrate } from 'src/migration/Migration';
import { AppModule } from './app/app.module';
import { environment } from './environments/environment';

environment.migrationLevel = migrate();

if (environment.production) {
if (runtimeEnvironment.environment !== Environment.development) {
enableProdMode();
}

Expand Down
Loading

0 comments on commit 10d47be

Please sign in to comment.