From 186ba62db74d4fb9a0143146429f43877d6b174d Mon Sep 17 00:00:00 2001 From: andig Date: Sat, 27 Jan 2024 13:38:16 +0100 Subject: [PATCH] Site: add config UI (BC) (#9812) --- .eslintrc.js | 10 +- .gitignore | 1 + assets/css/app.css | 22 +- .../components/ChargingPlanSettingsEntry.vue | 4 +- .../js/components/Config/AddDeviceButton.vue | 45 + assets/js/components/Config/DeviceCard.vue | 105 + assets/js/components/Config/DeviceTags.vue | 64 + assets/js/components/Config/FormRow.vue | 11 +- assets/js/components/Config/MeterModal.vue | 406 ++++ assets/js/components/Config/Modbus.vue | 252 ++ assets/js/components/Config/PropertyField.vue | 55 +- assets/js/components/Config/SiteSettings.vue | 120 + assets/js/components/Config/TestResult.vue | 56 + .../Config/UserInterfaceSettings.vue | 126 + assets/js/components/Config/VehicleModal.vue | 159 +- assets/js/components/Config/mixins/test.js | 61 + assets/js/components/GlobalSettingsModal.vue | 121 +- assets/js/components/TopHeader.vue | 45 + assets/js/mixins/formatter.js | 30 +- assets/js/views/ChargingSessions.vue | 28 +- assets/js/views/Config.vue | 631 +++-- assets/js/views/Main.vue | 1 - core/keys/site.go | 5 + core/site.go | 20 + core/site/api.go | 12 + core/site_api.go | 69 + env.d.ts | 1 + i18n/en.toml | 46 +- package-lock.json | 2157 ++++++++++------- package.json | 7 +- playwright.config.js | 2 + provider/javascript.go | 16 +- provider/javascript/registry.go | 10 + server/http.go | 14 +- ...ndler.go => http_config_device_handler.go} | 312 ++- server/http_config_helper.go | 125 +- server/http_config_metadata_handler.go | 82 + server/http_config_site_handler.go | 89 + server/http_session_handler.go | 5 +- server/http_site_handler.go | 4 +- tests/config.spec.js | 143 +- tests/simulator.js | 3 +- tests/simulator/api.js | 49 +- tests/simulator/src/Simulator.vue | 8 +- tsconfig.json | 19 + util/templates/paramtype.go | 4 + util/templates/types.go | 8 +- 47 files changed, 3910 insertions(+), 1653 deletions(-) create mode 100644 assets/js/components/Config/AddDeviceButton.vue create mode 100644 assets/js/components/Config/DeviceCard.vue create mode 100644 assets/js/components/Config/DeviceTags.vue create mode 100644 assets/js/components/Config/MeterModal.vue create mode 100644 assets/js/components/Config/Modbus.vue create mode 100644 assets/js/components/Config/SiteSettings.vue create mode 100644 assets/js/components/Config/TestResult.vue create mode 100644 assets/js/components/Config/UserInterfaceSettings.vue create mode 100644 assets/js/components/Config/mixins/test.js create mode 100644 assets/js/components/TopHeader.vue create mode 100644 env.d.ts rename server/{http_config_handler.go => http_config_device_handler.go} (75%) create mode 100644 server/http_config_metadata_handler.go create mode 100644 server/http_config_site_handler.go create mode 100644 tsconfig.json diff --git a/.eslintrc.js b/.eslintrc.js index a24c9fce4..51ca7c160 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -5,12 +5,14 @@ module.exports = { es6: true, }, extends: [ + "plugin:vue/vue3-essential", "eslint:recommended", - "plugin:vue/vue3-recommended", - "plugin:prettier/recommended", - "prettier", + "@vue/eslint-config-typescript", + "@vue/eslint-config-prettier/skip-formatting", ], - parser: "vue-eslint-parser", + parserOptions: { + ecmaVersion: "latest", + }, rules: { "vue/require-default-prop": "off", "vue/attribute-hyphenation": "off", diff --git a/.gitignore b/.gitignore index c8dbce45e..4b8c120c4 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ __debug_bin !package*.json !evcc.dist.yaml !tests/**/*.evcc.yaml +!tsconfig.json /templates/docs evcc evcc.exe diff --git a/assets/css/app.css b/assets/css/app.css index 3511d755b..2e4642201 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -44,6 +44,7 @@ --evcc-box: var(--bs-white); --evcc-default-text: var(--bs-gray-dark); --evcc-gray: var(--bs-gray-medium); + --evcc-gray-50: #93949e80; --evcc-accent1: var(--evcc-dark-yellow); --evcc-accent2: var(--evcc-darker-green); @@ -193,19 +194,27 @@ a:hover { opacity: 0.2; } +.btn-outline-primary { + --bs-btn-active-bg: var(--bs-primary); + --bs-btn-active-border-color: var(--bs-primary); +} + .btn-outline-primary, .btn-outline-primary:focus { color: var(--bs-primary); background-color: transparent; border-color: var(--bs-primary); } + .btn-outline-primary:hover { color: var(--evcc-accent3) !important; background-color: transparent !important; border-color: var(--evcc-accent3) !important; } + +.btn-group > .btn-check + .btn-outline-primary:hover, .btn-outline-primary:active { - color: var(--evcc-default-text) !important; + color: var(--bs-white) !important; background-color: var(--evcc-accent3) !important; border-color: var(--evcc-accent3) !important; } @@ -319,7 +328,6 @@ a:hover { .modal-body { padding: 1rem 0 0; - overflow-x: hidden; } .modal-footer { @@ -427,6 +435,9 @@ input::-webkit-datetime-edit { background-color: var(--evcc-box); color: var(--evcc-default-text); } +.form-control:disabled { + color: var(--bs-gray-dark); +} input[type="time"]::-webkit-calendar-picker-indicator { display: none; @@ -436,6 +447,13 @@ input[type="time"]::-webkit-calendar-picker-indicator { --bs-table-bg: transparent; } +.badge { + --bs-badge-font-size: 0.8rem; + --bs-badge-padding-x: 0.75em; + --bs-badge-padding-y: 0.75em; + font-weight: normal; +} + /* larger check switch */ .form-switch .form-check-input { height: 1.1rem; diff --git a/assets/js/components/ChargingPlanSettingsEntry.vue b/assets/js/components/ChargingPlanSettingsEntry.vue index 5d83c410d..305799c77 100644 --- a/assets/js/components/ChargingPlanSettingsEntry.vue +++ b/assets/js/components/ChargingPlanSettingsEntry.vue @@ -269,12 +269,12 @@ export default { this.$t("main.targetCharge.tomorrow"), ]; for (let i = 0; i < 7; i++) { - const dayNumber = date.toLocaleDateString(this.$i18n.locale, { + const dayNumber = date.toLocaleDateString(this.$i18n?.locale, { month: "short", day: "numeric", }); const dayName = - labels[i] || date.toLocaleDateString(this.$i18n.locale, { weekday: "long" }); + labels[i] || date.toLocaleDateString(this.$i18n?.locale, { weekday: "long" }); options.push({ value: this.fmtDayString(date), name: `${dayNumber} (${dayName})`, diff --git a/assets/js/components/Config/AddDeviceButton.vue b/assets/js/components/Config/AddDeviceButton.vue new file mode 100644 index 000000000..cf657c8a4 --- /dev/null +++ b/assets/js/components/Config/AddDeviceButton.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/assets/js/components/Config/DeviceCard.vue b/assets/js/components/Config/DeviceCard.vue new file mode 100644 index 000000000..57c7049b6 --- /dev/null +++ b/assets/js/components/Config/DeviceCard.vue @@ -0,0 +1,105 @@ + + + + + diff --git a/assets/js/components/Config/DeviceTags.vue b/assets/js/components/Config/DeviceTags.vue new file mode 100644 index 000000000..bc1ea7584 --- /dev/null +++ b/assets/js/components/Config/DeviceTags.vue @@ -0,0 +1,64 @@ + + + diff --git a/assets/js/components/Config/FormRow.vue b/assets/js/components/Config/FormRow.vue index 61192e07f..ed0d22e64 100644 --- a/assets/js/components/Config/FormRow.vue +++ b/assets/js/components/Config/FormRow.vue @@ -1,18 +1,18 @@ @@ -27,7 +27,6 @@ export default { label: String, help: String, optional: Boolean, - smallValue: Boolean, example: String, }, computed: { diff --git a/assets/js/components/Config/MeterModal.vue b/assets/js/components/Config/MeterModal.vue new file mode 100644 index 000000000..d72ee2494 --- /dev/null +++ b/assets/js/components/Config/MeterModal.vue @@ -0,0 +1,406 @@ + + + + diff --git a/assets/js/components/Config/Modbus.vue b/assets/js/components/Config/Modbus.vue new file mode 100644 index 000000000..d9d3256e6 --- /dev/null +++ b/assets/js/components/Config/Modbus.vue @@ -0,0 +1,252 @@ + + + diff --git a/assets/js/components/Config/PropertyField.vue b/assets/js/components/Config/PropertyField.vue index fb21155a4..e52e25971 100644 --- a/assets/js/components/Config/PropertyField.vue +++ b/assets/js/components/Config/PropertyField.vue @@ -1,19 +1,18 @@