Skip to content

Commit 26b63cf

Browse files
Thomas FinkThomas Fink
authored andcommitted
fix(ZMS-3253): cleaned up some code from review and added success message for delete availability
1 parent 75dd8ed commit 26b63cf

File tree

16 files changed

+228
-180
lines changed

16 files changed

+228
-180
lines changed

zmsadmin/js/page/availabilityDay/form/validate.js

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,12 +185,22 @@ function validateStartTime(today, tomorrow, selectedDate, data) {
185185
*/
186186
const startHourInt = parseInt(startHour);
187187
const endHourInt = parseInt(endHour);
188-
if (startHourInt >= 23 || startHourInt === 0 || endHourInt >= 23 || endHourInt === 0) {
188+
if (
189+
(startHourInt === 22 && startMinute > 0) ||
190+
startHourInt === 23 ||
191+
startHourInt === 0 ||
192+
(endHourInt === 22 && endMinute > 0) ||
193+
endHourInt === 23 ||
194+
endHourInt === 0 ||
195+
(startHourInt === 1 && startMinute > 0) ||
196+
(endHourInt === 1 && endMinute > 0)
197+
) {
189198
errorList.push({
190199
type: 'startOfDay',
191-
message: 'Die Uhrzeit darf nicht zwischen 23:00 und 01:00 liegen, da in diesem Zeitraum der tägliche Cronjob ausgeführt wird.'
192-
})
200+
message: 'Die Uhrzeit darf nicht zwischen 22:00 und 01:00 liegen, da in diesem Zeitraum der tägliche Cronjob ausgeführt wird.'
201+
});
193202
}
203+
194204
return errorList;
195205
}
196206

zmsadmin/js/page/availabilityDay/helpers.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import moment from 'moment'
22

3-
export const getStateFromProps = props => {
3+
export const getStateFromProps = (props, existingState = {}) => {
44
return {
55
availabilitylistslices: writeSlotCalculationIntoAvailability(
66
props.availabilitylist,
@@ -11,7 +11,10 @@ export const getStateFromProps = props => {
1111
conflicts: props.conflicts,
1212
today: props.today,
1313
busyslots: props.busyslots,
14-
slotbuckets: props.slotbuckets,
14+
// Preserve SaveBar state
15+
saveType: existingState.saveType || 'save',
16+
lastSave: existingState.lastSave,
17+
saveSuccess: existingState.saveSuccess
1518
}
1619
}
1720

@@ -77,6 +80,7 @@ export const getInitialState = (props) => Object.assign({}, {
7780
lastSave: null,
7881
stateChanged: false,
7982
selectedTab: 'table',
83+
saveType: 'save',
8084
}, getStateFromProps(props))
8185

8286
export const getNewAvailability = (timestamp, tempId, scope, existingAvailabilities = []) => {

zmsadmin/js/page/availabilityDay/index.js

Lines changed: 77 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -82,23 +82,31 @@ class AvailabilityPage extends Component {
8282
});
8383
}
8484

85+
// Add this new method
86+
updateDataState(newProps) {
87+
this.setState({
88+
conflicts: newProps.conflicts,
89+
availabilitylist: newProps.availabilityList,
90+
busyslots: newProps.busySlotsForAvailabilities,
91+
maxslots: newProps.maxSlotsForAvailabilities,
92+
slotbuckets: newProps.slotBuckets,
93+
availabilitylistslices: writeSlotCalculationIntoAvailability(
94+
newProps.availabilityList,
95+
newProps.maxSlotsForAvailabilities,
96+
newProps.busySlotsForAvailabilities
97+
),
98+
stateChanged: false
99+
});
100+
}
101+
102+
// Modify refreshData to use the new method
85103
refreshData() {
86104
const currentDate = formatTimestampDate(this.props.timestamp)
87105
const url = `${this.props.links.includeurl}/scope/${this.props.scope.id}/availability/day/${currentDate}/conflicts/`
88106
$.ajax(url, {
89107
method: 'GET'
90108
}).done(data => {
91-
const newProps = {
92-
conflicts: data.conflicts,
93-
availabilitylist: data.availabilityList,
94-
busyslots: data.busySlotsForAvailabilities,
95-
maxslots: data.maxSlotsForAvailabilities,
96-
slotbuckets: data.slotBuckets,
97-
}
98-
this.setState(Object.assign({}, getStateFromProps(Object.assign({}, this.props, newProps)), {
99-
stateChanged: false
100-
}))
101-
109+
this.updateDataState(data);
102110
}).fail(err => {
103111
console.log('refreshData error', err)
104112
})
@@ -108,9 +116,7 @@ class AvailabilityPage extends Component {
108116
const ok = confirm('Möchten Sie wirklich die Änderungen aller Öffnungszeiten speichern?');
109117
if (ok) {
110118
showSpinner();
111-
112119
const selectedDate = formatTimestampDate(this.props.timestamp);
113-
114120
const sendData = this.state.availabilitylist
115121
.filter((availability) => {
116122
return (
@@ -124,7 +130,6 @@ class AvailabilityPage extends Component {
124130
if (availability.tempId) {
125131
delete sendAvailability.tempId;
126132
}
127-
console.log(availability.kind);
128133
return {
129134
...sendAvailability,
130135
kind: availability.kind || 'default',
@@ -137,58 +142,42 @@ class AvailabilityPage extends Component {
137142
selectedDate: selectedDate
138143
};
139144

140-
console.log('Saving updates', payload);
141-
142145
$.ajax(`${this.props.links.includeurl}/availability/`, {
143146
method: 'POST',
144147
data: JSON.stringify(payload),
145148
contentType: 'application/json'
146149
}).done((success) => {
147-
console.log('save success:', success);
150+
// Update data immediately
148151
this.refreshData();
149-
this.setState({
150-
lastSave: new Date().getTime(),
151-
saveSuccess: true,
152-
}, () => {
153-
// Attempt to scroll immediately after state update, before the 6-second timer expires
154-
if (this.successElement) {
155-
this.successElement.scrollIntoView();
156-
} else {
157-
// Fallback to bottom scroll if the element isn't available
158-
this.handleScrollToBottom();
159-
}
160-
});
152+
this.getValidationList();
153+
154+
// Set SaveBar state with new method
155+
this.updateSaveBarState('save', true);
156+
157+
if (this.successElement) {
158+
this.successElement.scrollIntoView();
159+
}
161160
hideSpinner();
162-
this.handleScrollToBottom();
163161
}).fail((err) => {
164162
let isException = err.responseText.toLowerCase().includes('exception');
165163
if (err.status >= 500 && isException) {
166164
new ExceptionHandler($('.opened'), {
167165
code: err.status,
168166
message: err.responseText
169167
});
170-
} else if (err.status === 404) {
171-
console.log('404 error, ignored');
172168
} else {
173169
console.log('save all error', err);
174170
}
175-
this.setState({
176-
lastSave: new Date().getTime(),
177-
saveSuccess: true,
178-
}, () => {
179-
if (this.successElement) {
180-
this.successElement.scrollIntoView();
181-
}
182-
});
171+
this.updateSaveBarState('save', false);
183172
this.getValidationList();
184173
hideSpinner();
185-
this.handleScrollToBottom();
186174
});
187175
} else {
188176
hideSpinner();
189177
}
190178
}
191179

180+
192181
onRevertUpdates() {
193182
this.isCreatingExclusion = false
194183
this.setState(Object.assign({}, getInitialState(this.props), {
@@ -207,7 +196,6 @@ class AvailabilityPage extends Component {
207196

208197
if (ok) {
209198
const selectedDate = formatTimestampDate(this.props.timestamp);
210-
211199
const sendAvailability = Object.assign({}, availability);
212200

213201
if (sendAvailability.tempId) {
@@ -224,23 +212,22 @@ class AvailabilityPage extends Component {
224212
selectedDate: selectedDate
225213
};
226214

227-
console.log('Updating single availability', payload);
228-
229215
$.ajax(`${this.props.links.includeurl}/availability/save/${id}/`, {
230216
method: 'POST',
231217
data: JSON.stringify(payload),
232218
contentType: 'application/json'
233219
}).done((data) => {
234-
console.log('Single update success:', data);
220+
// Update data immediately
235221
this.refreshData();
236-
this.setState({
237-
lastSave: new Date().getTime(),
238-
saveSuccess: true,
239-
}, () => {
222+
this.getValidationList();
223+
224+
// Set SaveBar state with new method
225+
this.updateSaveBarState('save', true);
226+
227+
if (this.successElement) {
240228
this.successElement.scrollIntoView();
241-
});
229+
}
242230
hideSpinner();
243-
this.handleScrollToBottom();
244231
}).fail(err => {
245232
const isException = err.responseText.toLowerCase().includes('exception');
246233
if (isException) {
@@ -251,20 +238,23 @@ class AvailabilityPage extends Component {
251238
} else {
252239
console.log('Update error:', err);
253240
}
254-
this.setState({
255-
lastSave: new Date().getTime(),
256-
saveSuccess: false,
257-
});
258-
241+
this.updateSaveBarState('save', false);
259242
this.getValidationList();
260243
hideSpinner();
261-
this.handleScrollToBottom();
262244
});
263245
} else {
264246
hideSpinner();
265247
}
266248
}
267249

250+
updateSaveBarState(type, success) {
251+
this.setState({
252+
lastSave: new Date().getTime(),
253+
saveSuccess: success,
254+
saveType: type
255+
});
256+
}
257+
268258
onDeleteAvailability(availability) {
269259
showSpinner();
270260
const ok = confirm('Soll diese Öffnungszeit wirklich gelöscht werden?')
@@ -273,13 +263,21 @@ class AvailabilityPage extends Component {
273263
$.ajax(`${this.props.links.includeurl}/availability/delete/${id}/`, {
274264
method: 'GET'
275265
}).done(() => {
276-
this.setState(Object.assign({}, deleteAvailabilityInState(this.state, availability), {
277-
selectedAvailability: null
278-
}), () => {
279-
this.refreshData()
280-
this.getConflictList(),
281-
this.getValidationList()
282-
});
266+
const newState = deleteAvailabilityInState(this.state, availability);
267+
268+
// Update data immediately
269+
this.refreshData();
270+
if (newState.availabilitylist.length > 0) {
271+
this.getConflictList();
272+
}
273+
this.getValidationList();
274+
275+
// Set SaveBar state with new method
276+
this.updateSaveBarState('delete', true);
277+
278+
if (this.successElement) {
279+
this.successElement.scrollIntoView();
280+
}
283281
hideSpinner();
284282
}).fail(err => {
285283
console.log('delete error', err);
@@ -292,6 +290,7 @@ class AvailabilityPage extends Component {
292290
} else {
293291
console.log('delete error', err);
294292
}
293+
this.updateSaveBarState('delete', false);
295294
hideSpinner();
296295
})
297296
} else {
@@ -459,23 +458,23 @@ class AvailabilityPage extends Component {
459458
let state = {};
460459
const newAvailability = getNewAvailability(this.props.timestamp, tempId(), this.props.scope, this.state.availabilitylist);
461460
newAvailability.type = "appointment";
462-
461+
463462
state = Object.assign(
464463
state,
465464
updateAvailabilityInState(this.state, newAvailability)
466465
);
467-
466+
468467
state.selectedAvailability = newAvailability;
469468
state.stateChanged = false;
470-
469+
471470
this.setState(state, () => {
472471
Promise.all([
473472
this.getValidationList(),
474473
this.getConflictList()
475474
])
476-
.then(() => {
477-
$('body').scrollTop(0);
478-
})
475+
.then(() => {
476+
$('body').scrollTop(0);
477+
})
479478
});
480479
}
481480

@@ -541,24 +540,24 @@ class AvailabilityPage extends Component {
541540
}
542541
return [];
543542
};
544-
543+
545544
try {
546545
const list = this.state.availabilitylist
547546
.map(validateData)
548547
.flat();
549-
548+
550549
console.log("Validations fetched successfully:", list);
551-
550+
552551
this.setState(
553552
{
554553
errorList: list.length ? list : [],
555554
},
556555
() => {
557556
if (list.length > 0) {
558-
const nonPastTimeErrors = list.filter(error =>
557+
const nonPastTimeErrors = list.filter(error =>
559558
!error.itemList?.flat(2).some(item => item?.type === 'endTimePast')
560559
);
561-
560+
562561
if (nonPastTimeErrors.length > 0) {
563562
console.warn("Validation failed with errors:", nonPastTimeErrors);
564563
this.errorElement?.scrollIntoView();
@@ -590,9 +589,9 @@ class AvailabilityPage extends Component {
590589
selectedDate: formatTimestampDate(timestamp)
591590
}),
592591
};
593-
592+
594593
const url = `${this.props.links.includeurl}/availability/conflicts/`;
595-
594+
596595
fetch(url, requestOptions)
597596
.then((res) => res.json())
598597
.then(
@@ -876,6 +875,7 @@ class AvailabilityPage extends Component {
876875
lastSave={this.state.lastSave}
877876
success={this.state.saveSuccess}
878877
setSuccessRef={this.setSuccessRef}
878+
type={this.state.saveType}
879879
/>
880880
)
881881
}

0 commit comments

Comments
 (0)