From b95236c1708b0cf65b0fb115173386ace52272be Mon Sep 17 00:00:00 2001
From: Thomas Basler <thomas@familie-basler.net>
Date: Fri, 1 Sep 2023 00:20:56 +0200
Subject: [PATCH] Feature: webapp: Move inverter settings into different tabs

---
 webapp/src/locales/de.json             |   2 +
 webapp/src/locales/en.json             |   2 +
 webapp/src/locales/fr.json             |   2 +
 webapp/src/views/InverterAdminView.vue | 154 ++++++++++++++-----------
 4 files changed, 91 insertions(+), 69 deletions(-)

diff --git a/webapp/src/locales/de.json b/webapp/src/locales/de.json
index 8ea7bd32d..849415f13 100644
--- a/webapp/src/locales/de.json
+++ b/webapp/src/locales/de.json
@@ -450,6 +450,8 @@
         "SaveOrder": "Reihenfolge speichern",
         "DeleteInverter": "Wechselrichter löschen",
         "EditInverter": "Wechselrichter bearbeiten",
+        "General": "Allgemein",
+        "String": "String",
         "InverterSerial": "Wechselrichter Seriennummer:",
         "InverterName": "Wechselrichter Name:",
         "InverterNameHint": "Hier kann ein eigener Namen für den Wechselrichter angeben werden.",
diff --git a/webapp/src/locales/en.json b/webapp/src/locales/en.json
index 1edb88d86..6a5c856ed 100644
--- a/webapp/src/locales/en.json
+++ b/webapp/src/locales/en.json
@@ -450,6 +450,8 @@
         "SaveOrder": "Save order",
         "DeleteInverter": "Delete inverter",
         "EditInverter": "Edit inverter",
+        "General": "General",
+        "String": "String",
         "InverterSerial": "Inverter Serial:",
         "InverterName": "Inverter Name:",
         "InverterNameHint": "Here you can specify a custom name for your inverter.",
diff --git a/webapp/src/locales/fr.json b/webapp/src/locales/fr.json
index 8c763b959..348de6185 100644
--- a/webapp/src/locales/fr.json
+++ b/webapp/src/locales/fr.json
@@ -450,6 +450,8 @@
         "SaveOrder": "Save order",
         "DeleteInverter": "Supprimer l'onduleur",
         "EditInverter": "Modifier l'onduleur",
+        "General": "Général",
+        "String": "Ligne",
         "InverterSerial": "Numéro de série de l'onduleur",
         "InverterName": "Nom de l'onduleur :",
         "InverterNameHint": "Ici, vous pouvez spécifier un nom personnalisé pour votre onduleur.",
diff --git a/webapp/src/views/InverterAdminView.vue b/webapp/src/views/InverterAdminView.vue
index 3660a4985..1c94b70af 100644
--- a/webapp/src/views/InverterAdminView.vue
+++ b/webapp/src/views/InverterAdminView.vue
@@ -80,85 +80,101 @@
                 </div>
                 <div class="modal-body">
                     <form>
-                        <div class="mb-3">
-                            <label for="inverter-serial" class="col-form-label">
-                                {{ $t('inverteradmin.InverterSerial') }}
-                            </label>
-                            <input v-model="selectedInverterData.serial" type="number" id="inverter-serial"
-                                class="form-control" />
-                            <label for="inverter-name" class="col-form-label">{{ $t('inverteradmin.InverterName') }}
-                                <BIconInfoCircle v-tooltip :title="$t('inverteradmin.InverterNameHint')" />
-                            </label>
-                            <input v-model="selectedInverterData.name" type="text" id="inverter-name"
-                                class="form-control" maxlength="31" />
-
-                            <CardElement :text="$t('inverteradmin.InverterStatus')" addSpace>
-                                <InputElement :label="$t('inverteradmin.PollEnable')"
-                                    v-model="selectedInverterData.poll_enable"
-                                    type="checkbox" wide />
-                                <InputElement :label="$t('inverteradmin.PollEnableNight')"
-                                    v-model="selectedInverterData.poll_enable_night"
-                                    type="checkbox" wide/>
-                                <InputElement :label="$t('inverteradmin.CommandEnable')"
-                                    v-model="selectedInverterData.command_enable"
-                                    type="checkbox" wide/>
-                                <InputElement :label="$t('inverteradmin.CommandEnableNight')"
-                                    v-model="selectedInverterData.command_enable_night"
-                                    type="checkbox" wide/>
-                                <div class="alert alert-secondary mt-3" role="alert" v-html="$t('inverteradmin.StatusHint')"></div>
-                            </CardElement>
-                        </div>
-
-                        <div v-for="(ch, index) in selectedInverterData.channel" :key="`${index}`">
-                            <div class="row g-2">
-                                <div class="col-md">
-                                    <label :for="`inverter-name_${index}`" class="col-form-label">
-                                        {{ $t('inverteradmin.StringName', { num: index + 1 }) }}
-                                        <BIconInfoCircle v-tooltip :title="$t('inverteradmin.StringNameHint')" />
+                        <nav>
+                            <div class="nav nav-tabs" id="nav-tab" role="tablist">
+                                <button class="nav-link active" id="nav-general-tab" data-bs-toggle="tab" data-bs-target="#nav-general"
+                                    type="button" role="tab" aria-controls="nav-general" aria-selected="true">{{
+                                        $t('inverteradmin.General')
+                                    }}</button>
+                                <button class="nav-link" id="nav-string-tab" data-bs-toggle="tab" data-bs-target="#nav-string"
+                                    type="button" role="tab" aria-controls="nav-string">{{ $t('inverteradmin.String') }}</button>
+                            </div>
+                        </nav>
+                        <div class="tab-content" id="nav-tabContent">
+                            <div class="tab-pane fade show active" id="nav-general" role="tabpanel" aria-labelledby="nav-general-tab" tabindex="0">
+                                <div class="mb-3">
+                                    <label for="inverter-serial" class="col-form-label">
+                                        {{ $t('inverteradmin.InverterSerial') }}
                                     </label>
-                                    <div class="d-flex mb-2">
-                                        <div class="input-group">
-                                            <input type="text" class="form-control" :id="`inverter-name_${index}`"
-                                                maxlength="31" v-model="ch.name" />
-                                        </div>
-                                    </div>
+                                    <input v-model="selectedInverterData.serial" type="number" id="inverter-serial"
+                                        class="form-control" />
+                                    <label for="inverter-name" class="col-form-label">{{ $t('inverteradmin.InverterName') }}
+                                        <BIconInfoCircle v-tooltip :title="$t('inverteradmin.InverterNameHint')" />
+                                    </label>
+                                    <input v-model="selectedInverterData.name" type="text" id="inverter-name"
+                                        class="form-control" maxlength="31" />
+
+                                    <CardElement :text="$t('inverteradmin.InverterStatus')" addSpace>
+                                        <InputElement :label="$t('inverteradmin.PollEnable')"
+                                            v-model="selectedInverterData.poll_enable"
+                                            type="checkbox" wide />
+                                        <InputElement :label="$t('inverteradmin.PollEnableNight')"
+                                            v-model="selectedInverterData.poll_enable_night"
+                                            type="checkbox" wide/>
+                                        <InputElement :label="$t('inverteradmin.CommandEnable')"
+                                            v-model="selectedInverterData.command_enable"
+                                            type="checkbox" wide/>
+                                        <InputElement :label="$t('inverteradmin.CommandEnableNight')"
+                                            v-model="selectedInverterData.command_enable_night"
+                                            type="checkbox" wide/>
+                                        <div class="alert alert-secondary mt-3" role="alert" v-html="$t('inverteradmin.StatusHint')"></div>
+                                    </CardElement>
                                 </div>
                             </div>
-                            <div class="row g-2">
-                                <div class="col">
-                                    <label :for="`inverter-max_${index}`" class="col-form-label">
-                                        {{ $t('inverteradmin.StringMaxPower', { num: index + 1 }) }}
-                                        <BIconInfoCircle v-tooltip :title="$t('inverteradmin.StringMaxPowerHint')" />
-                                    </label>
-                                    <div class="d-flex mb-2">
-                                        <div class="input-group">
-                                            <input type="number" class="form-control" :id="`inverter-max_${index}`"
-                                                min="0" v-model="ch.max_power"
-                                                :aria-describedby="`inverter-maxDescription_${index} inverter-customizer`" />
-                                            <span class="input-group-text"
-                                                :id="`inverter-maxDescription_${index}`">W<sub>p</sub><sup>*</sup></span>
+
+                            <div class="tab-pane fade show" id="nav-string" role="tabpanel" aria-labelledby="nav-string-tab" tabindex="0">
+                                <div v-for="(ch, index) in selectedInverterData.channel" :key="`${index}`">
+                                    <div class="row g-2">
+                                        <div class="col-md">
+                                            <label :for="`inverter-name_${index}`" class="col-form-label">
+                                                {{ $t('inverteradmin.StringName', { num: index + 1 }) }}
+                                                <BIconInfoCircle v-tooltip :title="$t('inverteradmin.StringNameHint')" />
+                                            </label>
+                                            <div class="d-flex mb-2">
+                                                <div class="input-group">
+                                                    <input type="text" class="form-control" :id="`inverter-name_${index}`"
+                                                        maxlength="31" v-model="ch.name" />
+                                                </div>
+                                            </div>
                                         </div>
                                     </div>
-                                </div>
-                                <div class="col">
-                                    <label :for="`inverter-ytoffset_${index}`" class="col-form-label">
-                                        {{ $t('inverteradmin.StringYtOffset', { num: index + 1 }) }}
-                                        <BIconInfoCircle v-tooltip :title="$t('inverteradmin.StringYtOffsetHint')" />
-                                    </label>
-                                    <div class="d-flex mb-2">
-                                        <div class="input-group">
-                                            <input type="number" class="form-control" :id="`inverter-ytoffset_${index}`"
-                                                min="0" v-model="ch.yield_total_offset"
-                                                :aria-describedby="`inverter-ytoffsetDescription_${index} inverter-customizer`" />
-                                            <span class="input-group-text"
-                                                :id="`inverter-ytoffsetDescription_${index}`">kWh</span>
+                                    <div class="row g-2">
+                                        <div class="col">
+                                            <label :for="`inverter-max_${index}`" class="col-form-label">
+                                                {{ $t('inverteradmin.StringMaxPower', { num: index + 1 }) }}
+                                                <BIconInfoCircle v-tooltip :title="$t('inverteradmin.StringMaxPowerHint')" />
+                                            </label>
+                                            <div class="d-flex mb-2">
+                                                <div class="input-group">
+                                                    <input type="number" class="form-control" :id="`inverter-max_${index}`"
+                                                        min="0" v-model="ch.max_power"
+                                                        :aria-describedby="`inverter-maxDescription_${index} inverter-customizer`" />
+                                                    <span class="input-group-text"
+                                                        :id="`inverter-maxDescription_${index}`">W<sub>p</sub><sup>*</sup></span>
+                                                </div>
+                                            </div>
+                                        </div>
+                                        <div class="col">
+                                            <label :for="`inverter-ytoffset_${index}`" class="col-form-label">
+                                                {{ $t('inverteradmin.StringYtOffset', { num: index + 1 }) }}
+                                                <BIconInfoCircle v-tooltip :title="$t('inverteradmin.StringYtOffsetHint')" />
+                                            </label>
+                                            <div class="d-flex mb-2">
+                                                <div class="input-group">
+                                                    <input type="number" class="form-control" :id="`inverter-ytoffset_${index}`"
+                                                        min="0" v-model="ch.yield_total_offset"
+                                                        :aria-describedby="`inverter-ytoffsetDescription_${index} inverter-customizer`" />
+                                                    <span class="input-group-text"
+                                                        :id="`inverter-ytoffsetDescription_${index}`">kWh</span>
+                                                </div>
+                                            </div>
                                         </div>
                                     </div>
                                 </div>
+                                <div :id="`inverter-customizer`" class="form-text" v-html="$t('inverteradmin.InverterHint')">
+                                </div>
                             </div>
                         </div>
-                        <div :id="`inverter-customizer`" class="form-text" v-html="$t('inverteradmin.InverterHint')">
-                        </div>
                     </form>
 
                 </div>