2020 <div
2121 :id =" modalId"
2222 ref =" modal"
23- class =" modal fade text-dark"
23+ class =" modal fade text-dark modal-xl "
2424 data-bs-backdrop =" true"
2525 tabindex =" -1"
2626 role =" dialog"
4444 </div >
4545 <form @submit.prevent =" setTargetTime" >
4646 <div class =" modal-body" >
47- <div class =" form-group mb-2" >
47+ <div
48+ class =" form-group d-lg-flex align-items-baseline mb-2 justify-content-between"
49+ >
4850 <!-- eslint-disable vue/no-v-html -->
49- <label for =" targetTimeLabel" class =" mb-3" >
51+ <label for =" targetTimeLabel" class =" mb-3 me-3 " >
5052 <span v-if =" socBasedCharging" >
5153 {{
5254 $t("main.targetCharge.descriptionSoc", {
6365 </span >
6466 </label >
6567 <!-- eslint-enable vue/no-v-html -->
66- <div
67- class =" d-flex justify-content-between"
68- :style =" { 'max-width': '350px' }"
69- >
70- <select
71- v-model =" selectedDay"
72- class =" form-select me-2"
73- :style =" { 'flex-basis': '60%' }"
74- >
68+ <div class =" d-flex justify-content-between date-selection" >
69+ <select v-model =" selectedDay" class =" form-select me-2" >
7570 <option
7671 v-for =" opt in dayOptions()"
7772 :key =" opt.value"
8378 <input
8479 v-model =" selectedTime"
8580 type =" time"
86- class =" form-control ms-2"
87- :style =" { 'flex-basis': '40%' }"
81+ class =" form-control ms-2 time-selection"
8882 :step =" 60 * 5"
8983 required
9084 />
9185 </div >
9286 </div >
93- <p v-if =" !selectedTargetTimeValid" class =" text-danger mb-0" >
94- {{ $t("main.targetCharge.targetIsInThePast") }}
87+ <p class =" mb-0" >
88+ <span v-if =" timeInThePast" class =" text-danger" >
89+ {{ $t("main.targetCharge.targetIsInThePast") }}
90+ </span >
91+ <span v-else-if =" timeTooFarInTheFuture" class =" text-secondary" >
92+ {{ $t("main.targetCharge.targetIsTooFarInTheFuture") }}
93+ </span >
94+   ;
9595 </p >
96- <TargetChargePlanMinimal v-else-if =" plan.duration" v-bind =" plan" />
96+ <TargetChargePlan
97+ v-if =" targetChargePlanProps"
98+ v-bind =" targetChargePlanProps"
99+ />
97100 </div >
98101 <div class =" modal-footer d-flex justify-content-between" >
99102 <button
109112 type =" submit"
110113 class =" btn btn-primary"
111114 data-bs-dismiss =" modal"
112- :disabled =" !selectedTargetTimeValid "
115+ :disabled =" timeInThePast "
113116 >
114- {{ $t("main.targetCharge.activate") }}
117+ <span v-if =" targetTime" >
118+ {{ $t("main.targetCharge.update") }}
119+ </span >
120+ <span v-else >
121+ {{ $t("main.targetCharge.activate") }}
122+ </span >
115123 </button >
116124 </div >
117125 </form >
@@ -127,7 +135,7 @@ import Modal from "bootstrap/js/dist/modal";
127135import " @h2d2/shopicons/es/filled/plus" ;
128136import " @h2d2/shopicons/es/filled/edit" ;
129137import LabelAndValue from " ./LabelAndValue.vue" ;
130- import TargetChargePlanMinimal from " ./TargetChargePlanMinimal .vue" ;
138+ import TargetChargePlan from " ./TargetChargePlan .vue" ;
131139import api from " ../api" ;
132140
133141import formatter from " ../mixins/formatter" ;
@@ -137,7 +145,7 @@ const LAST_TARGET_TIME_KEY = "last_target_time";
137145
138146export default {
139147 name: " TargetCharge" ,
140- components: { LabelAndValue, TargetChargePlanMinimal },
148+ components: { LabelAndValue, TargetChargePlan },
141149 mixins: [formatter],
142150 props: {
143151 id: [String , Number ],
@@ -154,6 +162,7 @@ export default {
154162 selectedDay: null ,
155163 selectedTime: null ,
156164 plan: {},
165+ tariff: {},
157166 modal: null ,
158167 isModalVisible: false ,
159168 };
@@ -162,9 +171,19 @@ export default {
162171 targetChargeEnabled : function () {
163172 return this .targetTime ;
164173 },
165- selectedTargetTimeValid : function () {
174+ timeInThePast : function () {
166175 const now = new Date ();
167- return now < this .selectedTargetTime ;
176+ return now >= this .selectedTargetTime ;
177+ },
178+ timeTooFarInTheFuture : function () {
179+ if (this .tariff ? .rates ) {
180+ const lastRate = this .tariff .rates [this .tariff .rates .length - 1 ];
181+ if (lastRate .end ) {
182+ const end = new Date (lastRate .end );
183+ return this .selectedTargetTime >= end;
184+ }
185+ }
186+ return false ;
168187 },
169188 selectedTargetTime: function () {
170189 return new Date (` ${ this .selectedDay } T${ this .selectedTime || " 00:00" } ` );
@@ -175,6 +194,12 @@ export default {
175194 targetEnergyFormatted : function () {
176195 return this .fmtKWh (this .targetEnergy * 1e3 , true , true , 1 );
177196 },
197+ targetChargePlanProps : function () {
198+ const targetTime = this .selectedTargetTime ;
199+ const { rates } = this .tariff ;
200+ const { duration , unit , plan } = this .plan ;
201+ return rates ? { duration, rates, plan, unit, targetTime } : null ;
202+ },
178203 },
179204 watch: {
180205 targetTimeLabel : function () {
@@ -219,14 +244,17 @@ export default {
219244 updatePlan : async function () {
220245 if (
221246 this .isModalVisible &&
222- this .selectedTargetTimeValid &&
247+ ! this .timeInThePast &&
223248 (this .targetEnergy || this .targetSoc )
224249 ) {
225250 try {
226- const response = await api . get ( ` /loadpoints/ ${ this . id } /target/plan ` , {
251+ const opts = {
227252 params: { targetTime: this .selectedTargetTime },
228- });
229- this .plan = response .data .result ;
253+ };
254+ this .plan = (
255+ await api .get (` /loadpoints/${ this .id } /target/plan` , opts)
256+ ).data .result ;
257+ this .tariff = (await api .get (` /tariff/planner` )).data .result ;
230258 } catch (e) {
231259 console .error (e);
232260 }
@@ -323,4 +351,12 @@ export default {
323351.value : hover {
324352 color: var (-- bs- color- white);
325353}
354+ @media (min - width : 992px ) {
355+ .date - selection {
356+ width: 370px ;
357+ }
358+ }
359+ .time - selection {
360+ flex- basis: 200px ;
361+ }
326362< / style>
0 commit comments