Skip to content

Commit

Permalink
feat: add download/upload button also for settings
Browse files Browse the repository at this point in the history
  • Loading branch information
adlerre committed Jan 31, 2025
1 parent 7b0451f commit cb9c784
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 32 deletions.
2 changes: 1 addition & 1 deletion ui/src/app/components/obdStates.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
</div>
<form novalidate (ngSubmit)="onSubmit(form)" [formGroup]="form">
<ng-container *ngFor="let state of states.controls; let i = index">
<fieldset [formGroup]="state" id="state-{{ i }}" class="mt-0">
<fieldset [formGroup]="state" id="state-{{ i }}" class="mt-0 pt-3">
<div class="row">
<div class="col-sm-10 pe-md-0">
<div class="row mb-2">
Expand Down
30 changes: 3 additions & 27 deletions ui/src/app/components/obdStates.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
OBDState,
OBDStateType,
ReadFunctions,
stripEmptyProps,
ValueFormatFunctions,
ValueTypes
} from "../definitions";
Expand Down Expand Up @@ -307,7 +308,7 @@ export class OBDStatesComponent implements OnInit {
}

generateDownload() {
const theJSON = JSON.stringify(this.stripEmptyProps(this.states.value));
const theJSON = JSON.stringify(stripEmptyProps(this.states.value));
this.downloadHref = this.sanitizer
.bypassSecurityTrustUrl("data:text/json;charset=UTF-8," + encodeURIComponent(theJSON));
}
Expand All @@ -330,7 +331,7 @@ export class OBDStatesComponent implements OnInit {

onSubmit({value, valid}: { value: { states: Array<OBDState> }, valid: boolean }) {
if (valid) {
const states: Array<OBDState> = this.stripEmptyProps(value.states);
const states: Array<OBDState> = stripEmptyProps(value.states);
this.$api.updateStates(states).subscribe({
next: () => {
this.toast.show({
Expand All @@ -349,31 +350,6 @@ export class OBDStatesComponent implements OnInit {
}
}

private stripEmptyProps(arr: any): any {
for (const i in arr) {
if (typeof arr[i] === "object") {
if (arr[i]) {
for (const k in arr[i]) {
if (typeof arr[i][k] === "string" && (arr[i][k] === "" || arr[i][k] === null)) {
delete arr[i][k];
} else if (typeof arr[i][k] === "object") {
arr[i][k] = this.stripEmptyProps(arr[i][k]);
if (!arr[i][k]) {
delete arr[i][k];
}
}
}
} else {
delete arr[i];
}
} else if (typeof arr[i] === "string" && (arr[i] === "" || arr[i] === null)) {
delete arr[i];
}
}

return arr;
}

private jumpTo(id: string) {
setTimeout(() => {
const top = document.getElementById(id)?.offsetTop;
Expand Down
16 changes: 14 additions & 2 deletions ui/src/app/components/settings.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,21 @@
</ng-template>

<div id="settings">
<div class="d-flex my-2 justify-content-end">
<div class="btn-group">
<a class="btn btn-primary" [href]="downloadHref" download="settings.json" (click)="generateDownload()">&#8675;
Download</a>
<div class="btn btn-secondary p-0">
<label for="states-upload" class="d-inline-block py-1 px-2">&#8673; Upload</label>
<input type="file" id="states-upload" name="states-upload" accept="application/json"
(change)="onFileChange($event)" [hidden]="true"
>
</div>
</div>
</div>
<form novalidate (ngSubmit)="onSubmit(form)" [formGroup]="form">
@if (hasBattery) {
<fieldset [formGroup]="general">
<fieldset [formGroup]="general" class="mt-0">
<legend>General</legend>
<div class="row mb-2">
<label for="sleepTimeout" class="col-sm-2 control-label">Auto sleep timeout (sec)</label>
Expand All @@ -48,7 +60,7 @@
</div>
</fieldset>
}
<fieldset [formGroup]="wifi">
<fieldset [formGroup]="wifi" [ngClass]="{'mt-0': !hasBattery}" >
<legend>WiFi Access Point</legend>
<div class="row mb-2">
<label for="ssid" class="col-sm-2 control-label">SSID</label>
Expand Down
29 changes: 27 additions & 2 deletions ui/src/app/components/settings.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ import {
MQTTProtocol,
NetworkMode,
OBD2Protocol,
Settings
Settings,
stripEmptyProps
} from "../definitions";
import { NgbTypeahead, NgbTypeaheadSelectItemEvent } from "@ng-bootstrap/ng-bootstrap";
import {
Expand All @@ -45,6 +46,7 @@ import {
Subject
} from "rxjs";
import { ToastService } from "../services/toast.service";
import { DomSanitizer } from "@angular/platform-browser";

@Component({
selector: "ui-settings",
Expand Down Expand Up @@ -87,6 +89,8 @@ export class SettingsComponent implements OnInit {

click$ = new Subject<string>();

downloadHref: any;

protected readonly dataIntervals = dataIntervals;

protected readonly diagnosticIntervals = diagnosticIntervals;
Expand All @@ -95,7 +99,7 @@ export class SettingsComponent implements OnInit {

protected readonly locationIntervals = locationIntervals;

constructor(private $api: ApiService, private toast: ToastService) {
constructor(private $api: ApiService, private sanitizer: DomSanitizer, private toast: ToastService) {
this.general = new FormGroup({
sleepTimeout: new FormControl<number>(5 * 60, Validators.min(60)),
sleepDuration: new FormControl<number>(60 * 60, Validators.min(300)),
Expand Down Expand Up @@ -212,6 +216,27 @@ export class SettingsComponent implements OnInit {
}
}

generateDownload() {
const theJSON = JSON.stringify(stripEmptyProps(this.form.value));
this.downloadHref = this.sanitizer
.bypassSecurityTrustUrl("data:text/json;charset=UTF-8," + encodeURIComponent(theJSON));
}

onFileChange(event: Event) {
const target: any = event.target;
if (target.files && target.files.length) {
const fileReader = new FileReader();
fileReader.onload = () => {
const json = JSON.parse(fileReader.result as string);
if (json) {
this.form.patchValue(json);
setTimeout(() => this.form.updateValueAndValidity({emitEvent: true, onlySelf: true}));
}
}
fileReader.readAsText(target.files[0]);
}
}

onSubmit({value, valid}: { value: Settings, valid: boolean }) {
if (valid) {
this.$api.updateSettings(value).subscribe({
Expand Down
1 change: 1 addition & 0 deletions ui/src/app/definitions/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,5 @@ export * from "./modemInfo";
export * from "./obdStates";
export * from "./ota";
export * from "./settings";
export * from "./tools";
export * from "./wifiInfo";
41 changes: 41 additions & 0 deletions ui/src/app/definitions/tools.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* This program is free software; you can use it, redistribute it
* and / or modify it under the terms of the GNU General Public License
* (GPL) as published by the Free Software Foundation; either version 3
* of the License or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program, in a file called gpl.txt or license.txt.
* If not, write to the Free Software Foundation Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307 USA
*/

export const stripEmptyProps = (arr: any): any => {
for (const i in arr) {
if (typeof arr[i] === "object") {
if (arr[i]) {
for (const k in arr[i]) {
if (typeof arr[i][k] === "string" && (arr[i][k] === "" || arr[i][k] === null)) {
delete arr[i][k];
} else if (typeof arr[i][k] === "object") {
arr[i][k] = stripEmptyProps(arr[i][k]);
if (!arr[i][k]) {
delete arr[i][k];
}
}
}
} else {
delete arr[i];
}
} else if (typeof arr[i] === "string" && (arr[i] === "" || arr[i] === null)) {
delete arr[i];
}
}

return arr;
}

0 comments on commit cb9c784

Please sign in to comment.