Skip to content
This repository has been archived by the owner on Oct 28, 2024. It is now read-only.

Commit

Permalink
Merge pull request #880 from bacongobbler/customizable-ui
Browse files Browse the repository at this point in the history
customizable UI
  • Loading branch information
bacongobbler authored Jun 14, 2022
2 parents 050dcce + fddd613 commit 8ff3b57
Show file tree
Hide file tree
Showing 14 changed files with 103 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/Web/ClientApp/angular.json
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
"src/assets"
],
"styles": [
"src/styles.css"
"src/styles.scss"
],
"scripts": []
}
Expand Down
3 changes: 3 additions & 0 deletions src/Web/ClientApp/src/app/_interfaces/app-config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export interface AppConfig {
title?: string;
}
33 changes: 33 additions & 0 deletions src/Web/ClientApp/src/app/_services/app-config.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
import { AppConfig } from "../_interfaces/app-config";

@Injectable({ providedIn: 'root' })
export class AppConfigService {
private config: any;

constructor(private readonly http: HttpClient) { }

load(defaults?: AppConfig): Promise<AppConfig> {
return new Promise<AppConfig>(resolve => {
this.http.get('/assets/config.json').subscribe(
{
next: (response) => {
console.log('using server-side configuration')
this.config = Object.assign({}, defaults || {}, response || {});
resolve(this.config);
},
error: () => {
console.log('using default configuration');
this.config = Object.assign({}, defaults || {});
resolve(this.config);
}
}
);
});
}

get title() : string {
return this.config.title;
}
}
42 changes: 31 additions & 11 deletions src/Web/ClientApp/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { NgModule } from "@angular/core";
import { RouterModule, Routes } from "@angular/router";
import { Injectable, NgModule } from "@angular/core";
import { Title } from "@angular/platform-browser";
import { RouterModule, RouterStateSnapshot, Routes, TitleStrategy } from "@angular/router";
import { environment } from "src/environments/environment";
import { LoginComponent } from "./components/account/login/login.component";
import { RegisterComponent } from "./components/account/register/register.component";
import { ListComponent } from "./components/application/list/list.component";
Expand All @@ -8,21 +10,39 @@ import { ChannelComponent } from "./components/channel/channel.component";
import { NotFoundComponent } from "./components/not-found/not-found.component";
import { StyleguideComponent } from "./components/styleguide/styleguide.component";
import { AuthGuard } from "./_helpers/auth.guard";
import { AppConfigService } from "./_services/app-config.service";

const routes: Routes = [
{ path: '404', component: NotFoundComponent },
{ path: 'channel/:id', component: ChannelComponent, canActivate: [AuthGuard] },
{ path: 'app/new', component: NewComponent, canActivate: [AuthGuard] },
{ path: 'login', component: LoginComponent },
{ path: 'register', component: RegisterComponent },
{ path: 'styleguide', component: StyleguideComponent },
{ path: '', component: ListComponent, canActivate: [AuthGuard] },
{ path: '**', redirectTo: '404' }
{ path: '404', component: NotFoundComponent, title: 'Not Found' },
{ path: 'channel/:id', component: ChannelComponent, canActivate: [AuthGuard], title: 'Overview' },
{ path: 'app/new', component: NewComponent, canActivate: [AuthGuard], title: 'Create a new App' },
{ path: 'login', component: LoginComponent, title: 'Log in' },
{ path: 'register', component: RegisterComponent , title: 'Sign up' },
{ path: 'styleguide', component: StyleguideComponent, title: 'Style Guide' },
{ path: '', component: ListComponent, canActivate: [AuthGuard], title: 'Dashboard' },
{ path: '**', redirectTo: '404' }
];

@Injectable()
export class TemplatePageTitleStrategy extends TitleStrategy {
constructor(private readonly title: Title, private readonly appConfigService: AppConfigService) {
super();
}

override updateTitle(routerState: RouterStateSnapshot) {
const title = this.buildTitle(routerState);
if (title !== undefined) {
this.title.setTitle(`${this.appConfigService.title} | ${title}`);
}
}
}

@NgModule({
imports: [RouterModule.forRoot(routes, { useHash: true })],
exports: [RouterModule]
exports: [RouterModule],
providers: [
{provide: TitleStrategy, useClass: TemplatePageTitleStrategy},
]
})

export class AppRoutingModule { }
5 changes: 4 additions & 1 deletion src/Web/ClientApp/src/app/app.component.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { Component } from '@angular/core';
import { AppConfigService } from './_services/app-config.service';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'Hippo';
constructor(private readonly appConfigService: AppConfigService) { }

title = this.appConfigService.title;
}
10 changes: 8 additions & 2 deletions src/Web/ClientApp/src/app/app.module.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NgModule } from '@angular/core';
import { APP_INITIALIZER, NgModule } from '@angular/core';
import { HttpClientModule, HTTP_INTERCEPTORS } from '@angular/common/http';
import { BrowserModule } from '@angular/platform-browser';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
Expand All @@ -20,11 +20,11 @@ import { NewComponent } from './components/application/new/new.component';
import { NewComponent as NewChannelComponent } from './components/channel/new/new.component';
import { ChannelComponent } from './components/channel/channel.component';
import { HealthCheckComponent } from './components/health-check/health-check.component';
import { environment } from './../environments/environment';
import { SettingsComponent } from './components/application/settings/settings.component';
import { LogsComponent } from './components/channel/logs/logs.component';
import { OverviewComponent } from './components/channel/overview/overview.component';
import { NgxJdenticonModule, JDENTICON_CONFIG } from 'ngx-jdenticon';
import { AppConfigService } from './_services/app-config.service';

export function apiConfigFactory(): Configuration {
const params: ConfigurationParameters = {
Expand Down Expand Up @@ -78,6 +78,12 @@ export function apiConfigFactory(): Configuration {
useValue: {
replaceMode: "observe"
}
},
{
provide: APP_INITIALIZER,
multi: true,
deps: [AppConfigService],
useFactory: (appConfigService : AppConfigService) => () => appConfigService.load()
}
],
bootstrap: [AppComponent]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<h1 class="title has-text-centered">Log in to <span class="has-text-primary">Hippo</span></h1>
<h1 class="title has-text-primary has-text-centered">Log in</h1>

<article *ngIf="error" class="message is-danger">
<div class="message-header">
Expand All @@ -16,7 +16,7 @@ <h1 class="title has-text-centered">Log in to <span class="has-text-primary">Hip
<div class="control has-icons-left has-icons-right">
<input type="text" formControlName="username"
[ngClass]="{ 'is-danger': submitted && f['username'].errors }"
class="input" placeholder="e.g. rhymenoceros" />
class="input" placeholder="Enter your username here" />
<div *ngIf="submitted && f['username'].errors" class="help is-danger">
<div *ngIf="f['username'].errors['required']">Username is required.</div>
</div>
Expand All @@ -28,7 +28,7 @@ <h1 class="title has-text-centered">Log in to <span class="has-text-primary">Hip
<div class="control has-icons-left">
<input type="password" formControlName="password"
[ngClass]="{ 'is-danger': submitted && f['password'].errors }"
class="input" placeholder="make it strong!" />
class="input" />
<div *ngIf="submitted && f['password'].errors" class="help is-danger">
<div *ngIf="f['password'].errors['required']">Password is required.</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<div class="control has-icons-left has-icons-right">
<input type="text" formControlName="username"
[ngClass]="{ 'is-danger': submitted && f['username'].errors }"
class="input" placeholder="e.g. rhymenoceros" />
class="input" />
<div *ngIf="submitted && f['username'].errors" class="help is-danger">
<div *ngIf="f['username'].errors['required']">Username is required.</div>
</div>
Expand All @@ -27,7 +27,7 @@
<div class="control has-icons-left">
<input type="password" formControlName="password"
[ngClass]="{ 'is-danger': submitted && f['password'].errors }"
class="input" placeholder="make it strong!" />
class="input" />
<div *ngIf="submitted && f['password'].errors" class="help is-danger">
<div *ngIf="f['password'].errors['required']">Password is required.</div>
<div *ngIf="f['password'].errors['minlength']">Password must be at least 6 characters long.</div>
Expand All @@ -43,7 +43,7 @@
<div class="control has-icons-left">
<input type="password" formControlName="passwordConfirm"
[ngClass]="{ 'is-danger': submitted && f['passwordConfirm'].errors }"
class="input" placeholder="make it strong!" />
class="input" />
<div *ngIf="submitted && f['passwordConfirm'].errors" class="help is-danger">
<div *ngIf="f['passwordConfirm'].errors['required']">Password is required.</div>
<div *ngIf="f['passwordConfirm'].errors['minlength']">Password must be at least 6 characters long.</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,11 @@
margin: 2rem 4rem;
font-size: 1.25rem;
}

.navbar-brand {
padding-left: 1rem;
}

.navbar-end {
padding-right: 1rem;
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<nav class="navbar" role="navigation" aria-label="main navigation">
<nav id="topbar" class="navbar" role="navigation" aria-label="main navigation">
<div class="navbar-brand">
<a class="navbar-item" routerLink="/">
<fa-icon [icon]="faHippo" size="2x"></fa-icon><h1 class="title">Hippo</h1>
<div class="logo">
<img src="/assets/logo.svg" alt="banner logo" />
</div>
</a>

<a role="button" class="navbar-burger" aria-label="menu" aria-expanded="false" data-target="hippoMenu">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Component, OnInit } from '@angular/core';
import { faHippo, faUser } from '@fortawesome/free-solid-svg-icons';
import { faUser } from '@fortawesome/free-solid-svg-icons';
import { SessionService } from 'src/app/_services/session.service';

@Component({
Expand All @@ -8,7 +8,6 @@ import { SessionService } from 'src/app/_services/session.service';
styleUrls: ['./navbar.component.css']
})
export class NavbarComponent implements OnInit {
faHippo = faHippo;
faUser = faUser;

constructor(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
<h1 class="title has-text-centered">Hippo is sad :'(</h1>

<p class="has-text-centered">The page you were looking for doesn't exist. Try searching for something else.</p>

<a href ng-click="goBack()"><p class="has-text-centered">Go back to the previous page</p></a>
3 changes: 3 additions & 0 deletions src/Web/ClientApp/src/assets/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"title": "Hippo"
}
3 changes: 1 addition & 2 deletions src/Web/ClientApp/src/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@
<html lang="en">
<head>
<meta charset="utf-8">
<title>Hippo</title>
<base routerLink="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<link rel="icon" type="image/x-icon" href="/assets/favicon.ico">
</head>
<body>
<app-root></app-root>
Expand Down

0 comments on commit 8ff3b57

Please sign in to comment.