Skip to content

Commit

Permalink
Get settings and display motd (#168)
Browse files Browse the repository at this point in the history
* Get settings and display motd

* Disable registration

* rename to motd-ui
  • Loading branch information
jggoebel authored Jun 20, 2023
1 parent 0786e18 commit efbe59e
Show file tree
Hide file tree
Showing 7 changed files with 239 additions and 1 deletion.
9 changes: 9 additions & 0 deletions src/app/app.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,15 @@
</div>
</header>

<div
class="motd-container"
*ngIf="motd"
title="Click to close"
(click)="closeMotd()"
>
<p class="motd">{{ motd }}</p>
</div>

<div class="content-container">
<div class="content-area">
<router-outlet></router-outlet>
Expand Down
19 changes: 19 additions & 0 deletions src/app/app.component.scss
Original file line number Diff line number Diff line change
Expand Up @@ -137,3 +137,22 @@
}
}
}

.motd {
align-self: center;
margin-top: 0px;
text-align: center;
color: white;
}

.motd-container {
background-color: red;
margin-top: 0px;
width: 100%;
cursor: pointer;
}

.motd-close {
float: right;
position: relative;
}
16 changes: 16 additions & 0 deletions src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import { SettingsService } from './services/settings.service';
import { themes } from './scenario/terminal-themes/themes';
import { first } from 'rxjs/operators';
import { Context, ContextService } from './services/context.service';
import {
TypedInput,
TypedSettingsService,
} from './services/typedSettings.service';

@Component({
selector: 'app-root',
Expand Down Expand Up @@ -71,6 +75,7 @@ export class AppComponent implements OnInit {
];

public themes = themes;
public motd = '';

constructor(
private helper: JwtHelperService,
Expand All @@ -80,6 +85,7 @@ export class AppComponent implements OnInit {
private config: AppConfigService,
private settingsService: SettingsService,
private contextService: ContextService,
private typedSettingsService: TypedSettingsService,
) {
this.config.getLogo(this.logo).then((obj: string) => {
ClarityIcons.add({
Expand Down Expand Up @@ -174,6 +180,12 @@ export class AppComponent implements OnInit {
} else this.disableDarkMode();
}
});

this.typedSettingsService
.get('public', 'motd-ui')
.subscribe((typedInput: TypedInput) => {
this.motd = typedInput?.value ?? '';
});
}

public logout() {
Expand Down Expand Up @@ -361,4 +373,8 @@ export class AppComponent implements OnInit {
public disableDarkMode() {
document.body.classList.remove('darkmode');
}

public closeMotd() {
this.motd = '';
}
}
2 changes: 2 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import { GargantuaClientFactory } from './services/gargantua.service';
import { GuacTerminalComponent } from './scenario/guacTerminal.component';
import { IdeWindowComponent } from './scenario/ideWindow.component';
import { ContextService } from './services/context.service';
import { TypedSettingsService } from './services/typedSettings.service';

export function tokenGetter() {
return localStorage.getItem('hobbyfarm_token');
Expand Down Expand Up @@ -121,6 +122,7 @@ export function jwtOptionsFactory() {
AppConfigService,
ProgressService,
ContextService,
TypedSettingsService,
{
provide: APP_INITIALIZER,
useFactory: appInitializerFn,
Expand Down
2 changes: 1 addition & 1 deletion src/app/login/login.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
</clr-tab-content>
</ng-template>
</clr-tab>
<clr-tab>
<clr-tab *ngIf="!globalRegistrationDisabled">
<button clrTabLink id="register">Register</button>
<clr-tab-content id="register-content" *clrIfActive>
<div class="login-group">
Expand Down
14 changes: 14 additions & 0 deletions src/app/login/login.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { Component } from '@angular/core';
import { ActivatedRoute, Router } from '@angular/router';
import { AppConfigService } from '../app-config.service';
import { UserService } from '../services/user.service';
import {
TypedInput,
TypedSettingsService,
} from '../services/typedSettings.service';

@Component({
selector: 'app-login',
Expand All @@ -16,6 +20,8 @@ export class LoginComponent {

public registrationDisabled = false;

public globalRegistrationDisabled = true;

private Config = this.config.getConfig();
public logo;
public background;
Expand All @@ -26,13 +32,21 @@ export class LoginComponent {
private router: Router,
private config: AppConfigService,
private userService: UserService,
private typedSettingsService: TypedSettingsService,
) {
if (this.Config.login && this.Config.login.logo) {
this.logo = this.Config.login.logo;
}
if (this.Config.login && this.Config.login.background) {
this.background = 'url(' + this.Config.login.background + ')';
}

this.typedSettingsService
.get('public', 'registration-disabled')
.subscribe((typedInput: TypedInput) => {
console.log(typedInput);
this.globalRegistrationDisabled = typedInput.value ?? true;
});
}

public register() {
Expand Down
178 changes: 178 additions & 0 deletions src/app/services/typedSettings.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
import { Injectable } from '@angular/core';
import { map, tap } from 'rxjs/operators';
import {
extractResponseContent,
GargantuaClientFactory,
} from './gargantua.service';
import { of } from 'rxjs';

export class PreparedSettings {
name: string;
value: any;
scope: string;
group: string;
// Following is corresponding to property.Property
dataType: 'string' | 'integer' | 'float' | 'boolean';
valueType: 'scalar' | 'array' | 'map';
displayName?: string;
// Following represents SettingValidation
}

export class PreparedScope {
name: string;
displayName: string;
}

export enum TypedInputType {
STRING,
INTEGER,
FLOAT,
BOOLEAN,
// COLOR or other possible custom input types
}

export enum TypedInputRepresentation {
SCALAR,
ARRAY,
MAP,
}

export enum FormGroupType {
LIST, // Display all settings in a grouped list
TABS, // Group form inputs, display groups in horizontal tabs (default)
TABS_VERTICAL, // Group form inputs, display groups in vertical tabs
}

export class TypedInput {
id: string; // id as of the metadata.name
name: string; // Display name of the input
category: string; // Category e.g. General, Provisioning etc.
type: TypedInputType;
representation: TypedInputRepresentation;
value: any;
}

@Injectable()
export class TypedSettingsService {
constructor(private gcf: GargantuaClientFactory) {}
private garg = this.gcf.scopedClient('/setting');
private scopeGarg = this.gcf.scopedClient('/scope');

private cachedTypedInputList: Map<string, Map<string, TypedInput>> =
new Map();

// Maps TypedInput representation to corresponding string
private typedInputRepresentationList: TypedInputRepresentation[] = [
TypedInputRepresentation.ARRAY,
TypedInputRepresentation.MAP,
TypedInputRepresentation.SCALAR,
];
private typedInputRepresentationStringList: string[] = [
'array',
'map',
'scalar',
];

// Maps TypedInput type to corresponding string
private typedInputDataTypeList: TypedInputType[] = [
TypedInputType.STRING,
TypedInputType.BOOLEAN,
TypedInputType.FLOAT,
TypedInputType.INTEGER,
];
private typedInputDataTypeStringList: string[] = [
'string',
'boolean',
'float',
'integer',
];

public get(scope: string, setting: string) {
if (this.cachedTypedInputList && this.cachedTypedInputList.has(scope)) {
const scopedSettings = this.cachedTypedInputList.get(scope)!;
if (scopedSettings.has(setting)) {
return of(scopedSettings.get(setting) ?? ({} as TypedInput));
} else {
return of({} as TypedInput);
}
} else {
return this.list(scope).pipe(
tap((typedInputs: TypedInput[]) => {
const m: Map<string, TypedInput> = new Map();
typedInputs.forEach((typedSetting) => {
m.set(typedSetting.id, typedSetting);
});
this.cachedTypedInputList.set(scope, m);
}),
map((typedInputs) => {
return (
typedInputs.find((typedInput) => {
return typedInput.id === setting;
}) ?? ({} as TypedInput)
);
}),
);
}
}

public list(scope: string) {
return this.garg.get('/list/' + scope).pipe(
map(extractResponseContent),
map((pList: PreparedSettings[]) => {
if (!pList) {
return [];
}
return this.buildTypedInputList(pList);
}),
);
}

public listScopes() {
return this.scopeGarg.get('/list').pipe(
map(extractResponseContent),
map((pList: PreparedScope[]) => {
return pList ?? [];
}),
);
}

private buildTypedInputList(pList: PreparedSettings[]) {
const settings: TypedInput[] = [];

pList.forEach((preparedSetting: PreparedSettings) => {
const typedInputRepresentationIndex =
this.typedInputRepresentationStringList.indexOf(
preparedSetting.valueType,
);
const representation: TypedInputRepresentation =
this.typedInputRepresentationList[
typedInputRepresentationIndex == -1
? 0
: typedInputRepresentationIndex
];

const typedInputTypeIndex = this.typedInputDataTypeStringList.indexOf(
preparedSetting.dataType,
);
const inputType: TypedInputType =
this.typedInputDataTypeList[
typedInputTypeIndex == -1 ? 0 : typedInputTypeIndex
];

const setting = {
id: preparedSetting.name,
name:
preparedSetting.displayName == ''
? preparedSetting.name
: preparedSetting.displayName,
category: preparedSetting.group,
representation: representation,
type: inputType,
value: preparedSetting.value,
} as TypedInput;

settings.push(setting);
});
return settings;
}
}

0 comments on commit efbe59e

Please sign in to comment.