localStorage: locationId, energyPercent, locationConfig

This commit is contained in:
Patrick Haßel 2025-11-20 12:57:08 +01:00
parent aa71616961
commit 20bb84da63
22 changed files with 542 additions and 229 deletions

View File

@ -1,14 +1,22 @@
<div class="MainMenu NoUserSelect"> <div class="MainMenu NoUserSelect">
<div class="MainMenuBar"> <div class="MainMenuBar">
<div class="MainMenuItem MainMenuButton" (click)="showDrawer = !showDrawer"> <div class="MainMenuItem MainMenuButton" (click)="showDrawer = !showDrawer">
<fa-icon [icon]="faBars"></fa-icon> <fa-icon [icon]="faBars"></fa-icon>
</div> </div>
<div class="MainMenuItem MainMenuTitle"> <div class="MainMenuItem MainMenuTitle">
{{ menuService.title }} {{ menuService.title }}
</div> </div>
<div class="MainMenuItem" routerLink="/Settings">
<fa-icon [icon]="faGears"></fa-icon>
</div>
@if (!ws.connected) { @if (!ws.connected) {
<div class="MainMenuItem MainMenuNotConnected">NICHT VERBUNDEN</div> <div class="MainMenuItem MainMenuNotConnected">NICHT VERBUNDEN</div>
} }
</div> </div>
</div> </div>

View File

@ -1,9 +1,10 @@
import {Routes} from '@angular/router'; import {Routes} from '@angular/router';
import {LocationList} from './location/list/location-list';
import {LocationDetail} from './location/detail/location-detail'; import {LocationDetail} from './location/detail/location-detail';
import {SettingsComponent} from './settings/settings-component';
export const routes: Routes = [ export const routes: Routes = [
{path: 'Location/:id', component: LocationDetail}, {path: 'Location/:id', component: LocationDetail},
{path: 'Location', component: LocationList}, {path: 'Location', component: LocationDetail},
{path: 'Settings', component: SettingsComponent},
{path: '**', redirectTo: '/Location'}, {path: '**', redirectTo: '/Location'},
]; ];

View File

@ -1,15 +1,17 @@
import {Component, OnDestroy, OnInit} from '@angular/core'; import {Component, OnDestroy, OnInit} from '@angular/core';
import {Router, RouterLinkActive, RouterOutlet} from '@angular/router'; import {Router, RouterLink, RouterLinkActive, RouterOutlet} from '@angular/router';
import {FaIconComponent} from '@fortawesome/angular-fontawesome'; import {FaIconComponent} from '@fortawesome/angular-fontawesome';
import {faBars} from '@fortawesome/free-solid-svg-icons'; import {faBars, faBookmark as faBookmarkSolid, faGear, faGears} from '@fortawesome/free-solid-svg-icons';
import {MenuService} from './menu-service'; import {MenuService} from './menu-service';
import {Location} from './location/Location'; import {Location} from './location/Location';
import {LocationService} from './location/location-service'; import {LocationService} from './location/location-service';
import {WebsocketService} from './common'; import {WebsocketService} from './common';
import {ConfigService} from './config.service';
import {faBookmark as faBookmarkRegular} from '@fortawesome/free-regular-svg-icons';
@Component({ @Component({
selector: 'app-root', selector: 'app-root',
imports: [RouterOutlet, FaIconComponent, RouterLinkActive], imports: [RouterOutlet, FaIconComponent, RouterLinkActive, RouterLink],
templateUrl: './app.html', templateUrl: './app.html',
styleUrl: './app.less' styleUrl: './app.less'
}) })
@ -23,6 +25,7 @@ export class App implements OnInit, OnDestroy {
constructor( constructor(
readonly locationService: LocationService, readonly locationService: LocationService,
readonly configService: ConfigService,
readonly menuService: MenuService, readonly menuService: MenuService,
readonly router: Router, readonly router: Router,
readonly ws: WebsocketService, readonly ws: WebsocketService,
@ -45,4 +48,11 @@ export class App implements OnInit, OnDestroy {
}) })
} }
protected readonly faBookmarkRegular = faBookmarkRegular;
protected readonly faBookmarkSolid = faBookmarkSolid;
protected readonly faGear = faGear;
protected readonly faGears = faGears;
} }

View File

@ -0,0 +1,106 @@
import {Injectable} from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class ConfigService {
private readonly LOCATION_ID_KEY = "locationId";
private readonly ENERGY_PERCENT_KEY = "energyPercent";
private readonly ENERGY_PERCENT_FALLBACK = false;
private readonly LOCATION_CONFIG_KEY = "locationConfig";
private readonly LOCATION_CONFIG_FALLBACK = false;
constructor() {
this._locationId = this.readNumberOrNull(this.LOCATION_ID_KEY);
this._energyPercent = this.readBoolean(this.ENERGY_PERCENT_KEY, this.ENERGY_PERCENT_FALLBACK);
this._locationConfig = this.readBoolean(this.LOCATION_CONFIG_KEY, this.LOCATION_CONFIG_FALLBACK);
}
private readNumberOrNull(key: string): number | null {
const value = this.read(key);
if (value === null) {
return null;
}
const number = parseInt(value);
return isNaN(number) ? null : number;
}
private readBoolean(key: string, fallback: boolean): boolean {
const value = this.read(key);
if (value === "true") {
return true;
}
if (value === "false") {
return false;
}
return fallback;
}
private read(key: string): string | null {
const value = localStorage.getItem(key);
console.log("LOAD", key, value);
return value;
}
private writeBoolean(key: string, value: boolean | null): void {
console.log("STORE", key, value);
if (value !== null && value !== undefined) {
localStorage.setItem(key, value + "");
} else {
localStorage.removeItem(key);
}
}
// locationId -----------------------------------------------------------------------------------
private _locationId: number | null = null;
get locationId(): number | null {
return this._locationId;
}
set locationId(value: number | null) {
this._locationId = value;
if (value !== null && value !== undefined) {
localStorage.setItem(this.LOCATION_ID_KEY, value + "");
} else {
localStorage.removeItem(this.LOCATION_ID_KEY);
}
}
// energyPercent -----------------------------------------------------------------------------------
private _energyPercent: boolean = this.ENERGY_PERCENT_FALLBACK;
get energyPercent(): boolean {
return this._energyPercent;
}
set energyPercent(value: boolean) {
this._energyPercent = value;
this.writeBoolean(this.ENERGY_PERCENT_KEY, value);
}
// locationConfig -----------------------------------------------------------------------------------
private _locationConfig: boolean = this.LOCATION_CONFIG_FALLBACK;
get locationConfig(): boolean {
return this._locationConfig;
}
set locationConfig(value: boolean) {
this._locationConfig = value;
if (value !== null && value !== undefined) {
localStorage.setItem(this.LOCATION_CONFIG_KEY, value + "");
} else {
localStorage.removeItem(this.LOCATION_CONFIG_KEY);
}
}
}

View File

@ -28,6 +28,7 @@
</ng-content> </ng-content>
</app-location-energy> </app-location-energy>
@if (configService.locationConfig) {
<div class="Section"> <div class="Section">
<div class="SectionHeading"> <div class="SectionHeading">
<div class="SectionHeadingText"> <div class="SectionHeadingText">
@ -189,3 +190,5 @@
</div> </div>
} }
}

View File

@ -1,6 +1,6 @@
import {Component, Inject, LOCALE_ID, OnDestroy, OnInit} from '@angular/core'; import {Component, Inject, LOCALE_ID, OnDestroy, OnInit} from '@angular/core';
import {LocationService} from '../location-service'; import {LocationService} from '../location-service';
import {ActivatedRoute} from '@angular/router'; import {ActivatedRoute, Params, Router} from '@angular/router';
import {Location} from '../Location'; import {Location} from '../Location';
import {Text} from '../../shared/text/text'; import {Text} from '../../shared/text/text';
import {Number} from '../../shared/number/number'; import {Number} from '../../shared/number/number';
@ -14,6 +14,19 @@ import {Series} from '../../series/Series';
import {SeriesType} from '../../series/SeriesType'; import {SeriesType} from '../../series/SeriesType';
import {DateService} from '../../date.service'; import {DateService} from '../../date.service';
import {LocationPower} from '../power/location-power'; import {LocationPower} from '../power/location-power';
import {ConfigService} from '../../config.service';
export function paramNumberOrNull(params: Params, key: string): number | null {
const param = params[key];
if (param === null || param === undefined) {
return null;
}
const value = parseInt(param);
if (isNaN(value)) {
return null;
}
return value;
}
@Component({ @Component({
selector: 'app-location-detail', selector: 'app-location-detail',
@ -58,6 +71,8 @@ export class LocationDetail implements OnInit, OnDestroy {
readonly activatedRoute: ActivatedRoute, readonly activatedRoute: ActivatedRoute,
readonly menuService: MenuService, readonly menuService: MenuService,
readonly dateService: DateService, readonly dateService: DateService,
readonly configService: ConfigService,
readonly router: Router,
@Inject(LOCALE_ID) readonly locale: string, @Inject(LOCALE_ID) readonly locale: string,
) { ) {
this.datePipe = new DatePipe(locale); this.datePipe = new DatePipe(locale);
@ -65,7 +80,14 @@ export class LocationDetail implements OnInit, OnDestroy {
ngOnInit(): void { ngOnInit(): void {
this.locationService.id = null; this.locationService.id = null;
this.subs.push(this.activatedRoute.params.subscribe(params => this.locationService.id = params['id'] || null)); this.subs.push(this.activatedRoute.params.subscribe(params => {
const id = paramNumberOrNull(params, "id");
if (id === null && this.configService.locationId !== null) {
this.router.navigate(["Location/" + this.configService.locationId]);
return;
}
this.locationService.id = id;
}));
this.subs.push(this.locationService.location$.subscribe(this.onLocationChange)); this.subs.push(this.locationService.location$.subscribe(this.onLocationChange));
} }

View File

@ -14,10 +14,12 @@
<div class="SectionBody COLOR_FONT_PURCHASE"> <div class="SectionBody COLOR_FONT_PURCHASE">
{{ purchase.toValueString(null) }} {{ purchase.toValueString(null) }}
</div> </div>
@if (configService.energyPercent) {
<div class="SectionBody COLOR_FONT_PURCHASE percent"> <div class="SectionBody COLOR_FONT_PURCHASE percent">
{{ purchasePercentConsume.toValueString(null) }} {{ purchasePercentConsume.toValueString(null) }}
<sub class="subscript">Verbrauch</sub> <sub class="subscript">Verbrauch</sub>
</div> </div>
}
</div> </div>
<div class="Section4"> <div class="Section4">
@ -27,10 +29,12 @@
<div class="SectionBody COLOR_FONT_PRODUCE"> <div class="SectionBody COLOR_FONT_PRODUCE">
{{ produce.toValueString(null) }} {{ produce.toValueString(null) }}
</div> </div>
@if (configService.energyPercent) {
<div class="SectionBody COLOR_FONT_PRODUCE percent"> <div class="SectionBody COLOR_FONT_PRODUCE percent">
{{ producePercentConsume.toValueString(null) }} {{ producePercentConsume.toValueString(null) }}
<sub class="subscript">Verbrauch</sub> <sub class="subscript">Verbrauch</sub>
</div> </div>
}
</div> </div>
<div class="Section4"> <div class="Section4">
@ -40,6 +44,7 @@
<div class="SectionBody COLOR_FONT_SELF"> <div class="SectionBody COLOR_FONT_SELF">
{{ self.toValueString(null) }} {{ self.toValueString(null) }}
</div> </div>
@if (configService.energyPercent) {
<div class="SectionBody COLOR_FONT_SELF percent"> <div class="SectionBody COLOR_FONT_SELF percent">
{{ selfPercentConsume.toValueString(null) }} {{ selfPercentConsume.toValueString(null) }}
<sub class="subscript">Verbrauch</sub> <sub class="subscript">Verbrauch</sub>
@ -48,6 +53,7 @@
{{ selfPercentProduce.toValueString(null) }} {{ selfPercentProduce.toValueString(null) }}
<sub class="subscript">Produktion</sub> <sub class="subscript">Produktion</sub>
</div> </div>
}
</div> </div>
<div class="Section4"> <div class="Section4">
@ -66,6 +72,7 @@
<div class="SectionBody COLOR_FONT_DELIVER"> <div class="SectionBody COLOR_FONT_DELIVER">
{{ deliver.toValueString(null) }} {{ deliver.toValueString(null) }}
</div> </div>
@if (configService.energyPercent) {
<div class="SectionBody COLOR_FONT_DELIVER percent"> <div class="SectionBody COLOR_FONT_DELIVER percent">
{{ deliveryPercentConsume.toValueString(null) }} {{ deliveryPercentConsume.toValueString(null) }}
<sub class="subscript">Verbrauch</sub> <sub class="subscript">Verbrauch</sub>
@ -74,6 +81,7 @@
{{ deliveryPercentProduce.toValueString(null) }} {{ deliveryPercentProduce.toValueString(null) }}
<sub class="subscript">Produktion</sub> <sub class="subscript">Produktion</sub>
</div> </div>
}
</div> </div>
</div> </div>

View File

@ -1,4 +1,4 @@
import {AfterViewInit, Component, Input, OnDestroy, OnInit, signal} from '@angular/core'; import {AfterViewInit, Component, Input, OnDestroy, OnInit} from '@angular/core';
import {Location} from '../Location'; import {Location} from '../Location';
import {Series} from '../../series/Series'; import {Series} from '../../series/Series';
import {Next} from '../../common'; import {Next} from '../../common';
@ -8,6 +8,7 @@ import {SeriesService} from '../../series/series-service';
import {Subscription} from 'rxjs'; import {Subscription} from 'rxjs';
import {Value} from '../../series/Value'; import {Value} from '../../series/Value';
import EnergyCharts from './charts/energy-charts'; import EnergyCharts from './charts/energy-charts';
import {ConfigService} from '../../config.service';
@Component({ @Component({
selector: 'app-location-energy', selector: 'app-location-energy',
@ -20,8 +21,6 @@ import EnergyCharts from './charts/energy-charts';
}) })
export class LocationEnergy implements OnInit, AfterViewInit, OnDestroy { export class LocationEnergy implements OnInit, AfterViewInit, OnDestroy {
protected readonly signal = signal;
protected readonly Interval = Interval; protected readonly Interval = Interval;
private readonly subs: Subscription[] = []; private readonly subs: Subscription[] = [];
@ -75,6 +74,7 @@ export class LocationEnergy implements OnInit, AfterViewInit, OnDestroy {
constructor( constructor(
readonly pointService: PointService, readonly pointService: PointService,
readonly serieService: SeriesService, readonly serieService: SeriesService,
readonly configService: ConfigService,
) { ) {
// //
} }

View File

@ -1,7 +0,0 @@
<div class="List LocationList NoUserSelect">
@for (location of list; track location.id) {
<div class="ListItem Location" routerLink="/Location/{{location.id}}">
{{ location.name }}
</div>
}
</div>

View File

@ -1,35 +0,0 @@
import {Component, OnDestroy, OnInit} from '@angular/core';
import {LocationService} from '../location-service';
import {Location} from '../Location';
import {RouterLink} from '@angular/router';
import {MenuService} from '../../menu-service';
@Component({
selector: 'app-location-list',
imports: [
RouterLink
],
templateUrl: './location-list.html',
styleUrl: './location-list.less',
})
export class LocationList implements OnInit, OnDestroy {
protected list: Location[] = [];
constructor(
readonly locationService: LocationService,
readonly menuService: MenuService,
) {
//
}
ngOnInit(): void {
this.locationService.findAll(list => this.list = list);
this.menuService.title = "Orte";
}
ngOnDestroy(): void {
this.menuService.title = "";
}
}

View File

@ -25,9 +25,15 @@ export class LocationService extends CrudService<Location> {
} }
set id(id: number | null) { set id(id: number | null) {
if (this._id !== id) {
this._id = id; this._id = id;
this.fetch(); this.fetch();
} }
}
get id(): number | null {
return this._id;
}
private readonly fetch = () => { private readonly fetch = () => {
if (this._id === null) { if (this._id === null) {

View File

@ -1,7 +1,7 @@
<div class="Section3"> <div class="Section3">
<div class="SectionHeading"> <div class="SectionHeading">
<div class="SectionHeadingText"> <div class="SectionHeadingText">
Aktuelle Leistung Aktuell
</div> </div>
</div> </div>
<div class="SectionBody"> <div class="SectionBody">
@ -13,10 +13,12 @@
<div class="SectionBody COLOR_FONT_PURCHASE"> <div class="SectionBody COLOR_FONT_PURCHASE">
{{ location.powerPurchase?.value?.toValueString(dateService.now) }} {{ location.powerPurchase?.value?.toValueString(dateService.now) }}
</div> </div>
@if (configService.energyPercent) {
<div class="SectionBody COLOR_FONT_PURCHASE percent"> <div class="SectionBody COLOR_FONT_PURCHASE percent">
{{ location.powerPurchasePercentConsume.toValueString(dateService.now) }} {{ location.powerPurchasePercentConsume.toValueString(dateService.now) }}
<sub class="subscript">Verbrauch</sub> <sub class="subscript">Verbrauch</sub>
</div> </div>
}
</div> </div>
<div class="Section4"> <div class="Section4">
@ -26,10 +28,12 @@
<div class="SectionBody COLOR_FONT_PRODUCE"> <div class="SectionBody COLOR_FONT_PRODUCE">
{{ location.powerProduce?.value?.toValueString(dateService.now) }} {{ location.powerProduce?.value?.toValueString(dateService.now) }}
</div> </div>
@if (configService.energyPercent) {
<div class="SectionBody COLOR_FONT_PRODUCE percent"> <div class="SectionBody COLOR_FONT_PRODUCE percent">
{{ location.powerProducePercentConsume.toValueString(dateService.now) }} {{ location.powerProducePercentConsume.toValueString(dateService.now) }}
<sub class="subscript">Verbrauch</sub> <sub class="subscript">Verbrauch</sub>
</div> </div>
}
</div> </div>
<div class="Section4"> <div class="Section4">
@ -39,6 +43,7 @@
<div class="SectionBody COLOR_FONT_SELF"> <div class="SectionBody COLOR_FONT_SELF">
{{ location.powerSelf.toValueString(dateService.now) }} {{ location.powerSelf.toValueString(dateService.now) }}
</div> </div>
@if (configService.energyPercent) {
<div class="SectionBody COLOR_FONT_SELF percent"> <div class="SectionBody COLOR_FONT_SELF percent">
{{ location.powerSelfPercentConsume.toValueString(dateService.now) }} {{ location.powerSelfPercentConsume.toValueString(dateService.now) }}
<sub class="subscript">Verbrauch</sub> <sub class="subscript">Verbrauch</sub>
@ -47,6 +52,7 @@
{{ location.powerSelfPercentProduce.toValueString(dateService.now) }} {{ location.powerSelfPercentProduce.toValueString(dateService.now) }}
<sub class="subscript">Produktion</sub> <sub class="subscript">Produktion</sub>
</div> </div>
}
</div> </div>
<div class="Section4"> <div class="Section4">
@ -65,6 +71,7 @@
<div class="SectionBody COLOR_FONT_DELIVER"> <div class="SectionBody COLOR_FONT_DELIVER">
{{ location.powerDeliver?.value?.toValueString(dateService.now) }} {{ location.powerDeliver?.value?.toValueString(dateService.now) }}
</div> </div>
@if (configService.energyPercent) {
<div class="SectionBody COLOR_FONT_DELIVER percent"> <div class="SectionBody COLOR_FONT_DELIVER percent">
{{ location.powerDeliveryPercentConsume.toValueString(dateService.now) }} {{ location.powerDeliveryPercentConsume.toValueString(dateService.now) }}
<sub class="subscript">Verbrauch</sub> <sub class="subscript">Verbrauch</sub>
@ -73,6 +80,7 @@
{{ location.powerDeliveryPercentProduce.toValueString(dateService.now) }} {{ location.powerDeliveryPercentProduce.toValueString(dateService.now) }}
<sub class="subscript">Produktion</sub> <sub class="subscript">Produktion</sub>
</div> </div>
}
</div> </div>
</div> </div>

View File

@ -1,6 +1,7 @@
import {Component, Input} from '@angular/core'; import {Component, Input} from '@angular/core';
import {Location} from '../Location'; import {Location} from '../Location';
import {DateService} from '../../date.service'; import {DateService} from '../../date.service';
import {ConfigService} from '../../config.service';
@Component({ @Component({
selector: 'app-location-power', selector: 'app-location-power',
@ -15,6 +16,7 @@ export class LocationPower {
constructor( constructor(
readonly dateService: DateService, readonly dateService: DateService,
readonly configService: ConfigService,
) { ) {
// //
} }

View File

@ -0,0 +1,18 @@
<div
class="container NoUserSelect"
[ngClass]="classes()"
(mouseenter)="showPen = true"
(mouseleave)="showPen = false"
>
<select [(ngModel)]="model" (ngModelChange)="changed($event)">
<option [ngValue]="null">-</option>
@for (location of locations; track location.id) {
<option [ngValue]="location.id">
{{ location.name }}
</option>
}
</select>
@if (showPen) {
<fa-icon [icon]="faPen"></fa-icon>
}
</div>

View File

@ -0,0 +1,25 @@
.container {
display: flex;
.value {
flex: 1;
}
}
.container:hover {
background-color: #0002;
}
select {
all: unset;
width: 100%;
}
.invalid {
background-color: red !important;
}
.changed {
background-color: yellow !important;
}

View File

@ -0,0 +1,80 @@
import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core';
import {FaIconComponent} from '@fortawesome/angular-fontawesome';
import {FormsModule} from '@angular/forms';
import {NgClass} from '@angular/common';
import {faPen} from '@fortawesome/free-solid-svg-icons';
import {Location} from '../Location';
import {LocationService} from '../location-service';
import {DateService} from '../../date.service';
@Component({
selector: 'app-location-select',
imports: [
FaIconComponent,
FormsModule,
NgClass
],
templateUrl: './location-select.html',
styleUrl: './location-select.less',
})
export class LocationSelect implements OnInit {
protected readonly faPen = faPen;
private _initial: number | null = null;
@Input()
locations!: Location[];
@Input()
allowEmpty: boolean = true;
@Input()
filter: (location: Location) => boolean = () => true;
@Output()
readonly onChange = new EventEmitter<number | null>();
protected showPen: boolean = false;
protected model: number | null = null;
protected readonly Location = Location;
constructor(
readonly locationService: LocationService,
readonly dateService: DateService,
) {
//
}
ngOnInit(): void {
this.locationService.findAll(list => this.locations = list);
}
@Input()
set initial(value: number | null) {
this._initial = value;
this.reset();
}
private readonly reset = (): void => {
this.model = this._initial;
};
protected classes(): {} {
return {
"changed": this.model !== this._initial,
"invalid": !this.allowEmpty && this.model === null,
};
}
protected changed(id: number | null) {
if (this.allowEmpty || id !== null) {
this.onChange.emit(id);
} else {
this.reset();
}
}
}

View File

@ -16,10 +16,6 @@ select {
width: 100%; width: 100%;
} }
.unchanged {
background-color: lightgreen !important;
}
.invalid { .invalid {
background-color: red !important; background-color: red !important;
} }

View File

@ -78,7 +78,6 @@ export class SeriesSelect implements OnInit, OnDestroy {
protected classes(): {} { protected classes(): {} {
return { return {
"unchanged": this.model === this._initial,
"changed": this.model !== or(this._initial, i => i.id, null), "changed": this.model !== or(this._initial, i => i.id, null),
"invalid": !this.allowEmpty && this.model === null, "invalid": !this.allowEmpty && this.model === null,
}; };

View File

@ -0,0 +1,32 @@
<div class="Section3">
<div class="SectionHeading">
<div class="SectionHeadingText">
Favorit
</div>
</div>
<div>
<app-location-select [initial]="configService.locationId" (onChange)="configService.locationId = $event"></app-location-select>
</div>
</div>
<div class="Section3">
<div class="SectionHeading">
<div class="SectionHeadingText">
Anzeige
</div>
</div>
<div>
<div>
<label>
<input type="checkbox" #checkbox [checked]="configService.energyPercent" (change)="configService.energyPercent = checkbox.checked">
Energie Prozentsätze
</label>
</div>
<div>
<label>
<input type="checkbox" #checkbox [checked]="configService.locationConfig" (change)="configService.locationConfig = checkbox.checked">
Ort Konfiguration
</label>
</div>
</div>
</div>

View File

@ -0,0 +1,30 @@
import {Component} from '@angular/core';
import {LocationSelect} from '../location/select/location-select';
import {LocationService} from '../location/location-service';
import {Location} from '../location/Location'
import {ConfigService} from '../config.service';
import {config} from 'rxjs';
import {FormsModule} from '@angular/forms';
@Component({
selector: 'app-settings-component',
imports: [
LocationSelect,
FormsModule
],
templateUrl: './settings-component.html',
styleUrl: './settings-component.less',
})
export class SettingsComponent {
protected location: Location | null = null;
constructor(
readonly locationService: LocationService,
readonly configService: ConfigService,
) {
//
}
protected readonly config = config;
}

View File

@ -62,7 +62,8 @@ div {
} }
.Section3 { .Section3 {
border: 1px solid gray; border: 1px solid lightgray;
border-radius: 0.25em;
margin: 1em 0.5em 0.5em; margin: 1em 0.5em 0.5em;
padding: 0.5em; padding: 0.5em;
overflow: visible; overflow: visible;