Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(ZMS-3253 ZMS-3466 ZMS-3415 ZMS-1891): Replicate frontend validation in the backend for the availability opening hours to improve data integrity and frontend validation messaging #825

Open
wants to merge 199 commits into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 198 commits
Commits
Show all changes
199 commits
Select commit Hold shift + click to select a range
310f536
fix(ZMS-3253): validate and block adding conflicting openingtimes
Nov 12, 2024
bbd32b1
fix(ZMS-3253): add backend validation for opening hours and improve f…
Nov 14, 2024
5543f36
fix(ZMS-3253): fix zmsentities unit test
Nov 14, 2024
03bc86e
fix(ZMS-3253): fix zmsdb unit test
Nov 14, 2024
ffcdb0a
fix(ZMS-3253): add logging to zmsapi tests
Nov 14, 2024
47565c8
fix(ZMS-3253): fix one zmsapi unit test
Nov 14, 2024
3f8030e
fix(ZMS-3253): try fix one zmsapi unit test
Nov 14, 2024
f5e08ed
fix(ZMS-3253): try fix one zmsapi unit test
Nov 14, 2024
e4b36ea
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
e5f123c
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
9528271
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
770e847
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
4a79605
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
cdd0d8c
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
8a1aa79
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
09c10fb
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
afd6d5d
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
ce5d795
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
07f74c8
Revert "fix(ZMS-3253): try fix some unit tests"
Nov 14, 2024
da65ff3
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
93b2820
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
e0d41c4
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
bde21f3
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
0cd0ad1
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
29b7cff
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
9e11157
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
c2df444
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
5faea71
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
4cd3618
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
4840338
fix(ZMS-3253): try fix some unit tests
Nov 14, 2024
c8262a0
fix(ZMS-3253): backend validation work in AvailabilityAdd
Nov 15, 2024
8281b0a
fix(ZMS-3253): correct backend validation for timeoverlaps
Nov 15, 2024
390aba7
fix(ZMS-3253): fix a validation
Nov 15, 2024
78013ea
fix(ZMS-3253): try fixing a test
Nov 15, 2024
8a07621
fix(ZMS-3253): try fixing a test
Nov 15, 2024
7892fe0
fix(ZMS-3253): try fixing a test
Nov 15, 2024
9522585
fix(ZMS-3253): try fixing a test
Nov 15, 2024
d65ccb8
fix(ZMS-3253): try fixing availability not found test
Nov 15, 2024
3fa84a1
fix(ZMS-3253): try fixing availability mockdata for testRendering
Nov 15, 2024
317d127
fix(ZMS-3253): try fixing availability mockdata for testRendering
Nov 15, 2024
c02e4e3
fix(ZMS-3253): try fixing availability mockdata for testRendering
Nov 15, 2024
c75e3c4
fix(ZMS-3253): try fixing availability mockdata for testRendering
Nov 15, 2024
2b39546
fix(ZMS-3253): try fixing availability mockdata for testRendering
Nov 15, 2024
acb62ac
fix(ZMS-3253): try fix missing scope testRendering
Nov 15, 2024
a16b2e4
fix(ZMS-3253): fix zmsadmin availabilities conflict test
Nov 15, 2024
1bd40cb
fix(ZMS-3253): show availability opening hour conflicts in the future…
Nov 15, 2024
4025319
fix(ZMS-3253): remove error_logs
Nov 15, 2024
95dcef0
fix(ZMS-3253): refactor function logic getDateTimeRangeFromList to on…
Nov 15, 2024
39ef3a6
Merge remote-tracking branch 'origin/next' into bugfix-zms-3253-valid…
Nov 15, 2024
3eb8912
fix(ZMS-3253): renable twig cache
Nov 15, 2024
46c0af9
fix(ZMS-3253): renable twig cache
Nov 15, 2024
fdd0c72
fix(ZMS-3253): fix unit test
ThomasAFink Nov 18, 2024
f319de3
fix(ZMS-3253): fix unit test
ThomasAFink Nov 18, 2024
b8fd6b6
fix(ZMS-3253): fix unit test
ThomasAFink Nov 18, 2024
a2691c1
fix(ZMS-3253): fix unit test
ThomasAFink Nov 18, 2024
fc26e13
fix(ZMS-3253): fix unit test
ThomasAFink Nov 18, 2024
bffc9fa
fix(ZMS-3253): fix unit test
ThomasAFink Nov 18, 2024
5784eb4
fix(ZMS-3253): try fix unit test
ThomasAFink Nov 18, 2024
51e25ca
fix(ZMS-3253): add unit tests for testing overlapping availability op…
ThomasAFink Nov 18, 2024
4f2a125
fix(ZMS-3253): add unit tests for testing overlapping availability op…
ThomasAFink Nov 18, 2024
e8cae55
fix(ZMS-3253): remove space
ThomasAFink Nov 18, 2024
e0f4fa6
fix(ZMS-3253): remove space
ThomasAFink Nov 18, 2024
d17ffa2
fix(ZMS-3253): add unit tests for testing overlapping availability op…
ThomasAFink Nov 18, 2024
8a41469
fix(ZMS-3253): add unit tests for testing validation availability ope…
ThomasAFink Nov 18, 2024
e230b26
fix(ZMS-3253): add unit tests for testing overlapping availability op…
ThomasAFink Nov 18, 2024
5aadb7b
fix(ZMS-3253): add unit tests for testing validation availability ope…
ThomasAFink Nov 18, 2024
246b4d1
fix(ZMS-3253): add unit tests for testing overlapping availability op…
ThomasAFink Nov 18, 2024
17dcb07
fix(ZMS-3253): add unit tests for testing overlapping availability op…
ThomasAFink Nov 18, 2024
e984774
fix(ZMS-3253): add unit tests for testing overlapping availability op…
ThomasAFink Nov 18, 2024
d5135e2
fix(ZMS-3253): add unit tests for testing overlapping availability op…
ThomasAFink Nov 18, 2024
ca99ef2
fix(ZMS-3253): add unit tests for testing validation availability ope…
ThomasAFink Nov 18, 2024
d5c6051
fix(ZMS-3253): add unit tests for testing validation availability ope…
ThomasAFink Nov 18, 2024
5527c58
fix(ZMS-3253): refactor object creation
ThomasAFink Nov 18, 2024
ad89835
fix(ZMS-3253): refactor exception messages
ThomasAFink Nov 18, 2024
2a7d978
fix(ZMS-3253): clean up commented code
ThomasAFink Nov 18, 2024
ea55b27
fix(ZMS-3253): fix grammar
ThomasAFink Nov 20, 2024
932fe5f
fix(ZMS-3253): comment error_log
ThomasAFink Nov 20, 2024
5aa9d6b
fix(ZMS-3253): Improve frontend validation for opening hours availabi…
ThomasAFink Nov 20, 2024
fb7efb7
cleanup(ZMS-3415): remove invalid text instruction for graph view ope…
ThomasAFink Nov 21, 2024
1fd8f65
fix(ZMS-1891): Add missing frontend validation for timepicker
Nov 22, 2024
f8f536f
Merge branch 'next' into bugfix-zms-3253-validation-opening-hours-of-…
Nov 22, 2024
e4981ff
fix(ZMS-1891): Improve frontend validation for time formats
Nov 22, 2024
7916a70
fix(ZMS-3253): fix frontend exclusion availability validation
ThomasAFink Dec 3, 2024
462be60
fix(ZMS-3253): fix backend exclusion availability validation
ThomasAFink Dec 4, 2024
46db273
fix(ZMS-3253): allow exclusion availability on current date
ThomasAFink Dec 4, 2024
490ddce
fix(ZMS-3253): improve validation and cleanup code
ThomasAFink Dec 4, 2024
2ce2363
fix(ZMS-3253): move js spinner
ThomasAFink Dec 4, 2024
735c579
Merge remote-tracking branch 'origin/next' into bugfix-zms-3253-valid…
ThomasAFink Dec 4, 2024
97cee9c
clean(ZMS-3253): remove console logs
ThomasAFink Dec 4, 2024
a11f7b8
Merge branch 'next' into bugfix-zms-3253-validation-opening-hours-of-…
Dec 9, 2024
b620a54
fix(ZMS-3466): fix bookable day range validation
Dec 9, 2024
e3375c1
fix(ZMS-3466): fix error accumulation
Dec 9, 2024
e646a4c
fix(ZMS-3466): improve exception handling
Dec 9, 2024
8b7a1f6
fix(ZMS-3466): improve validation prevent divide by zero
Dec 9, 2024
2a3cbb7
fix(ZMS-3466): improve validation prevent divide by zero
Dec 9, 2024
4cbe423
fix(ZMS-3466): improve validation prevent divide by zero
Dec 9, 2024
0053e60
Merge branch 'next' into bugfix-zms-3253-3466-3415-1891-validation-op…
ThomasAFink Jan 20, 2025
cab1b1d
fix(ZMS-3466): Fix to from default values in opening hours availability
ThomasAFink Jan 20, 2025
ab51699
fix(ZMS): error message
Jan 23, 2025
227e741
Merge branch 'next' into bugfix-zms-3253-3466-3415-1891-validation-op…
Jan 23, 2025
694194b
fix(ZMS-3466): fix open from and open to placeholders in form
Jan 27, 2025
d53b28e
Merge branch 'next' into bugfix-zms-3253-3466-3415-1891-validation-op…
Jan 27, 2025
088356f
fix(ZMS-3466): improve default hours
Jan 28, 2025
484cbb4
fix(ZMS-3466): improve hours selection
Jan 28, 2025
e92684e
fix(ZMS-3466): closing new opening hours
Jan 28, 2025
faa90c0
fix(ZMS-3253): add backend validation check for new availabilities ov…
Jan 29, 2025
8d863ce
fix(ZMS-3253): unit test
Jan 29, 2025
ff16fc0
fix(ZMS-3253): unit tests
Jan 29, 2025
4043a66
fix(ZMS-3253): unit tests
Jan 29, 2025
860abc6
fix(ZMS-3253): add frontend validation check for new availabilities o…
Jan 29, 2025
3a3491f
fix(ZMS-3253): new availability conflict error display
Jan 29, 2025
64c884b
fix(ZMS-3253): when footer buttons are disabled
Jan 29, 2025
36724e4
fix(ZMS-3466): disable editing availabilities in the past
Jan 30, 2025
ea9b087
fix(ZMS-3466): improve infobox message format for non errors
Jan 30, 2025
687af94
fix(ZMS-3466): fix white space scroll error
Jan 30, 2025
d86c998
fix(ZMS-3466): disable maintanence daily cronjob hours from opening h…
Jan 30, 2025
39759a4
fix(ZMS-3466): add validation tests
Jan 31, 2025
65d6e79
fix(ZMS-3466): refactor overlapping new availabilities into one function
Jan 31, 2025
551438b
fix(ZMS-3466): add overlap tests in zmsadmin
Jan 31, 2025
2f92832
fix(ZMS-3466): add overlap test in zmsentities
Jan 31, 2025
36e81f3
fix(ZMS-3466): add more tests
Jan 31, 2025
c595cad
fix(ZMS-3466): fix detect conflict in the future with one time openin…
Jan 31, 2025
b7d7ac8
fix(ZMS-3466): Add tests
Jan 31, 2025
ce1dc34
Merge branch 'next' into bugfix-zms-3253-3466-3415-1891-validation-op…
Feb 3, 2025
1612ee4
Merge branch 'next' into bugfix-zms-3253-3466-3415-1891-validation-op…
Feb 4, 2025
b504141
fix(ZMS-3466): Overlapping new availabilities
Feb 4, 2025
0a49139
fix(ZMS-3466): fix cancel update availability clear errors
Feb 4, 2025
7402576
fix(ZMS-3466): fix allow 0 in form for appointment days in future
Feb 4, 2025
8e0cdc8
fix(ZMS-3466): fix allow 0 in form for appointment days in future end…
Feb 4, 2025
b89844d
Merge branch 'next' into bugfix-zms-3253-3466-3415-1891-validation-op…
Feb 4, 2025
75dd8ed
Merge branch 'next' into bugfix-zms-3253-3466-3415-1891-validation-op…
Feb 4, 2025
26b63cf
fix(ZMS-3253): cleaned up some code from review and added success mes…
Feb 4, 2025
b9c938d
fix(ZMS-3253): fix unit test
Feb 4, 2025
29049a6
fix(ZMS-3253): improve time selection
Feb 4, 2025
97e70f1
clean(ZMS-3253): remove console log
Feb 4, 2025
4deb527
fix(ZMS-3253): check boxes disabled for past opening hours
Feb 5, 2025
93bde12
fix(ZMS-3253): allow overlapping weekdays
Feb 5, 2025
4f31871
Merge branch 'next' into bugfix-zms-3253-3466-3415-1891-validation-op…
Feb 5, 2025
a52d441
fix(ZMS-3235): fix revert form error messages and fix disabled timesl…
Feb 5, 2025
5cf8728
Merge branch 'next' into bugfix-zms-3253-3466-3415-1891-validation-op…
Feb 6, 2025
5acfab2
fix(ZMS-3253): filter availability conflicts by weekday to prevent bl…
Feb 6, 2025
a53f7c7
fix(ZMS-3253): Add two unit tests
Feb 6, 2025
1e5cd4d
fix(ZMS-3253): Add two unit tests
Feb 6, 2025
8824b41
fix(ZMS-3253): fix two unit tests
Feb 6, 2025
308de88
fix(ZMS-3253): fix two unit tests
Feb 6, 2025
20d6cbf
fix(ZMS-3253): fix two unit tests
Feb 6, 2025
9dbb73a
fix(ZMS-3253): fix two unit tests
Feb 6, 2025
d5e4f5b
fix(ZMS-3253): fix two unit tests
Feb 6, 2025
e88a979
fix(ZMS-3253): fix two unit tests
Feb 6, 2025
cc2a6c0
fix(ZMS-3253): fix two unit tests
Feb 6, 2025
a45cbc2
fix(ZMS-3253): fix two unit tests
Feb 6, 2025
33b5a73
fix(ZMS-3253): fix two unit tests
Feb 6, 2025
ca2526a
fix(ZMS-3253): fix two unit tests
Feb 6, 2025
0731d6f
fix(ZMS-3253): fix two unit tests
Feb 6, 2025
11f7496
fix(ZMS-3253): fix two unit tests
Feb 6, 2025
8fb3354
fix(ZMS-3253): fix two unit tests
Feb 6, 2025
72646c3
fix(ZMS-3253): fix two unit tests
Feb 6, 2025
896b327
fix(ZMS-3253): fix weekday to date validation
Feb 6, 2025
3eaaa1b
fix(ZMS-3253): conflicts for exclusions
Feb 7, 2025
52fc4cd
clean(ZMS-3253): remove error logs
Feb 7, 2025
3b65923
fix(ZMS-3253): unit tests
Feb 7, 2025
35dfce4
fix(ZMS-3253): unit test
Feb 7, 2025
fb01fac
fix(ZMS-3253): display weekdays in conflicts
Feb 7, 2025
ee65b9b
fix(ZMS-3253): unit test
Feb 7, 2025
5745df3
fix(ZMS-3253): unit tests
Feb 7, 2025
c89eb94
feat(ZMS-3253): add color schema to opening hours accordion with legend
Feb 7, 2025
b1a3d3c
fix(ZMS-3253): when creating exclusion is disabled
Feb 7, 2025
5c82cb3
fix(ZMS-3253): when creating exclusion is disabled
Feb 7, 2025
c6410ad
fix(ZMS-3253): syntax error
ThomasAFink Feb 7, 2025
a943be8
feat(ZMS-3253): include color coding outside of just editing
Feb 7, 2025
2b0f8eb
fix(ZMS-3253): disable buttons for dates in the past
Feb 7, 2025
c14d277
fix(ZMS-3253): update button when disabled
Feb 7, 2025
6419403
fix(ZMS-3253): default description new opening hours and improve time…
Feb 7, 2025
0dba8c3
fix(ZMS-3253): syntax error
Feb 7, 2025
d316efb
feat(ZMS-3253): Add tab to view and edit all opening hours for a scope
Feb 7, 2025
c6e2dc0
clean(ZMS-3253): Add missing grammar
Feb 7, 2025
7f6f94f
Merge branch 'next' into bugfix-zms-3253-3466-3415-1891-validation-op…
Feb 7, 2025
cde1a14
feat(ZMS-3253): add sort function for the table
Feb 7, 2025
68d68fb
Update zmsadmin/src/Zmsadmin/AvailabilityListByScope.php
ThomasAFink Feb 7, 2025
61f3823
Merge branch 'next' into bugfix-zms-3253-3466-3415-1891-validation-op…
Feb 17, 2025
0151302
clean(ZMS-3253): format code
Feb 17, 2025
244cef3
clean(ZMS-3253): reduce zmsadmin AvailabilityConflicts complexity
Feb 17, 2025
9a315fe
clean(ZMS-3253): zmsentities remove unused vars
Feb 17, 2025
f6a641a
clean(ZMS-3253): code formatting
Feb 17, 2025
6f98308
clean(ZMS-3253): code formatting
Feb 17, 2025
8e1c425
clean(ZMS-3253): reduce complexity in AvailabilityUpdate and Availabi…
Feb 17, 2025
4cb3ded
clean(ZMS-3253): remove unused parameter
Feb 17, 2025
1f28b01
clean(ZMS-3253): formatting
Feb 17, 2025
fcf3a7d
clean(ZMS-3253): package.lock
Feb 17, 2025
85be2b5
fix(ZMS-3253): weekday validation logic
Feb 17, 2025
4ebc9cc
clean(ZMS-3253): formatting
Feb 17, 2025
393edf5
clean(ZMS-3253): formatting
Feb 17, 2025
a6e2d58
clean(ZMS-3253): remove color and all availability view
Feb 17, 2025
27065a1
clean(ZMS-3253): pass corrected resolveReferences
Feb 17, 2025
c4164cb
clean(ZMS-3253): remove unused style in js
Feb 17, 2025
48e1fba
Merge branch 'next' into bugfix-zms-3253-3466-3415-1891-validation-op…
Feb 17, 2025
c4115e5
Merge branch 'next' into bugfix-zms-3253-3466-3415-1891-validation-op…
Feb 20, 2025
341674e
fix(ZMS-3253): save amendment field overwrite in availability
Feb 20, 2025
35d0ffb
fix(ZMS-3253): .keep cache folder in zmsadmin
ThomasAFink Feb 21, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion zmsadmin/cache/.keep

This file was deleted.

39 changes: 22 additions & 17 deletions zmsadmin/js/page/availabilityDay/form/conflicts.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,26 +11,31 @@ const renderConflictList = (conflictList) => {
let conflictDatesByMessage = [];
conflictList.map(collection => {
collection.conflicts.map((conflict) => {
if (! conflictDatesByMessage[conflict.message]) {
Object.assign({}, conflictDatesByMessage[conflict.message] = []);
const existingConflict = conflictDatesByMessage.find(
item => item.message === conflict.message
);

if (existingConflict) {
existingConflict.dates.push(formatDate(collection.date));
} else {
conflictDatesByMessage.push({
message: conflict.message,
dates: [formatDate(collection.date)]
});
}
conflictDatesByMessage[conflict.message].push(formatDate(collection.date))
})
})
});
});

return (
Object.keys(conflictDatesByMessage).map((key, index) => {
return (
<div key={index}>
<div><strong>{ conflictDatesByMessage[key].join(", ") }</strong></div>
<div key={index}>- {key}</div>
</div>
)
})
)


}
conflictDatesByMessage.map((item, index) => (
<div key={index} style={{ marginBottom: '1rem' }}>
{/* Convert newlines in the message to <br /> tags */}
<div dangerouslySetInnerHTML={{ __html: item.message.replace(/\n/g, '<br />') }} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Security Risk: Unsafe HTML rendering.

Using dangerouslySetInnerHTML with unsanitized content from item.message exposes the application to XSS attacks.

Consider these safer alternatives:

  1. Use a sanitization library:
-                <div dangerouslySetInnerHTML={{ __html: item.message.replace(/\n/g, '<br />') }} />
+                <div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(item.message.replace(/\n/g, '<br />')) }} />
  1. Or better, use CSS white-space handling:
-                <div dangerouslySetInnerHTML={{ __html: item.message.replace(/\n/g, '<br />') }} />
+                <div style={{ whiteSpace: 'pre-line' }}>{item.message}</div>
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
<div dangerouslySetInnerHTML={{ __html: item.message.replace(/\n/g, '<br />') }} />
import DOMPurify from 'dompurify';
// ... other imports
// Line 33 update:
<div dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(item.message.replace(/\n/g, '<br />')) }} />
Suggested change
<div dangerouslySetInnerHTML={{ __html: item.message.replace(/\n/g, '<br />') }} />
// Line 33 update:
<div style={{ whiteSpace: 'pre-line' }}>{item.message}</div>
🧰 Tools
🪛 Biome (1.9.4)

[error] 33-33: Avoid passing content using the dangerouslySetInnerHTML prop.

Setting content using code can expose users to cross-site scripting (XSS) attacks

(lint/security/noDangerouslySetInnerHtml)

</div>
))
);
};


const Conflicts = (props) => {
const conflicts = Object.keys(props.conflictList).map(key => {
Expand Down
277 changes: 175 additions & 102 deletions zmsadmin/js/page/availabilityDay/form/content.js

Large diffs are not rendered by default.

204 changes: 131 additions & 73 deletions zmsadmin/js/page/availabilityDay/form/datepicker.js

Large diffs are not rendered by default.

31 changes: 18 additions & 13 deletions zmsadmin/js/page/availabilityDay/form/errors.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import React from 'react'
import PropTypes from 'prop-types'
import React from 'react';
import PropTypes from 'prop-types';

const renderErrors = errors => Object.keys(errors).map(key => {
return (
const renderErrors = (errors) =>
Object.keys(errors).map(key => (
<div key={errors[key].id}>
{errors[key].itemList.map((item, index) => {
return <div key={index}>{item[0].message}</div>
})}
if (Array.isArray(item)) {
return item.map((nestedItem, nestedIndex) => (
<div key={`${index}-${nestedIndex}`}>{nestedItem.message}</div>
));
} else {
return <div key={index}>{item.message}</div>;
}
})}
</div>
)
})
));

const Errors = (props) => {
return (
Expand All @@ -18,15 +23,15 @@ const Errors = (props) => {
<h3>Folgende Fehler sind bei der Prüfung Ihrer Eingaben aufgetreten:</h3>
{renderErrors(props.errorList)}
</div> : null
)
}
);
};

Errors.defaultProps = {
errorList: []
}
};

Errors.propTypes = {
errorList: PropTypes.object
}
};

export default Errors
export default Errors;
84 changes: 74 additions & 10 deletions zmsadmin/js/page/availabilityDay/form/footerButtons.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,91 @@
import React from 'react'
import PropTypes from 'prop-types'
import moment from 'moment'

const FooterButtons = (props) => {
const { hasConflicts, stateChanged, data, onNew, onPublish, onAbort, hasSlotCountError } = props
const {
hasConflicts,
hasErrors,
stateChanged,
data,
onNew,
onPublish,
onAbort,
hasSlotCountError,
availabilitylist,
selectedDate
} = props;

const hasNewAvailabilities = availabilitylist?.some(
availability => availability?.tempId?.includes('__temp__')
);

const hasSplitInProgress = (() => {
let hasOriginWithId = false;
let hasExclusion = false;
let hasFuture = false;

availabilitylist?.forEach(availability => {
if (availability?.kind) {
if (availability.kind === 'origin' && availability.id) {
hasOriginWithId = true;
} else if (availability.kind === 'exclusion') {
hasExclusion = true;
} else if (availability.kind === 'future') {
hasFuture = true;
}
}
});

return hasOriginWithId && (hasExclusion || hasFuture);
})();
Comment on lines +19 to +41
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Consider refactoring for better maintainability and testability.

The current implementation has two areas for improvement:

  1. The IIFE makes the code harder to test.
  2. The hasNewAvailabilities check could be simplified.

Consider these improvements:

-    const hasNewAvailabilities = availabilitylist?.some(
-        availability => availability?.tempId?.includes('__temp__')
-    );
+    const hasNewAvailabilities = availabilitylist?.some(
+        availability => availability?.tempId?.includes('__temp__')
+    ) ?? false;

-    const hasSplitInProgress = (() => {
-        let hasOriginWithId = false;
-        let hasExclusion = false;
-        let hasFuture = false;
-
-        availabilitylist?.forEach(availability => {
-            if (availability?.kind) {
-                if (availability.kind === 'origin' && availability.id) {
-                    hasOriginWithId = true;
-                } else if (availability.kind === 'exclusion') {
-                    hasExclusion = true;
-                } else if (availability.kind === 'future') {
-                    hasFuture = true;
-                }
-            }
-        });
-
-        return hasOriginWithId && (hasExclusion || hasFuture);
-    })();
+    const checkSplitInProgress = (availabilitylist) => {
+        const kinds = availabilitylist?.reduce((acc, availability) => {
+            if (availability?.kind) {
+                acc[availability.kind] = true;
+                if (availability.kind === 'origin' && availability.id) {
+                    acc.hasOriginWithId = true;
+                }
+            }
+            return acc;
+        }, {});
+        return kinds?.hasOriginWithId && (kinds?.exclusion || kinds?.future) ?? false;
+    };
+    const hasSplitInProgress = checkSplitInProgress(availabilitylist);

This refactoring:

  1. Extracts the IIFE into a named function for better testability
  2. Uses reduce for a more functional approach
  3. Adds null coalescing operators for safety
  4. Makes the code more maintainable
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const hasNewAvailabilities = availabilitylist?.some(
availability => availability?.tempId?.includes('__temp__')
);
const hasSplitInProgress = (() => {
let hasOriginWithId = false;
let hasExclusion = false;
let hasFuture = false;
availabilitylist?.forEach(availability => {
if (availability?.kind) {
if (availability.kind === 'origin' && availability.id) {
hasOriginWithId = true;
} else if (availability.kind === 'exclusion') {
hasExclusion = true;
} else if (availability.kind === 'future') {
hasFuture = true;
}
}
});
return hasOriginWithId && (hasExclusion || hasFuture);
})();
const hasNewAvailabilities = availabilitylist?.some(
availability => availability?.tempId?.includes('__temp__')
) ?? false;
const checkSplitInProgress = (availabilitylist) => {
const kinds = availabilitylist?.reduce((acc, availability) => {
if (availability?.kind) {
acc[availability.kind] = true;
if (availability.kind === 'origin' && availability.id) {
acc.hasOriginWithId = true;
}
}
return acc;
}, {});
return kinds?.hasOriginWithId && (kinds?.exclusion || kinds?.future) ?? false;
};
const hasSplitInProgress = checkSplitInProgress(availabilitylist);


const isPastDate = moment.unix(selectedDate).isBefore(moment(), 'day');

return (
<div className="form-actions" style={{"marginTop":"0", "padding":"0.75em"}}>
<button title="Neue Öffnungszeit anlegen und bearbeiten" className="button button--diamond button-new" onClick={onNew} disabled={(stateChanged || hasConflicts || data)}>neue Öffnungszeit</button>
<button title="Alle Änderungen werden zurückgesetzt" className="button btn" type="abort" onClick={onAbort} disabled={(!stateChanged && !hasConflicts && !data)}>Abbrechen</button>
<button title="Alle Änderungen werden gespeichert" className="button button--positive button-save" type="save" value="publish" onClick={onPublish} disabled={(!stateChanged || hasSlotCountError)}>Alle Änderungen aktivieren
</button>

<div className="form-actions" style={{ "marginTop": "0", "padding": "0.75em" }}>
<button
title="Neue Öffnungszeit anlegen und bearbeiten"
className="button button--diamond button-new"
onClick={onNew}
disabled={data || hasConflicts || hasSplitInProgress || isPastDate}
>
neue Öffnungszeit
</button>
<button
title="Alle Änderungen werden zurückgesetzt"
className="button btn"
type="abort"
onClick={onAbort}
disabled={(!stateChanged && !hasNewAvailabilities && !hasConflicts && !hasErrors) || isPastDate}
>
Abbrechen
</button>
<button
title="Alle Änderungen werden gespeichert"
className="button button--positive button-save"
type="save"
value="publish"
onClick={onPublish}
disabled={(!stateChanged && !hasNewAvailabilities) || hasSlotCountError || hasConflicts || hasErrors || isPastDate}
>
Alle Änderungen aktivieren
</button>
</div>

)
}

FooterButtons.propTypes = {
data: PropTypes.object,
hasConflicts: PropTypes.bool,
hasErrors: PropTypes.bool,
stateChanged: PropTypes.bool,
onNew: PropTypes.func,
onPublish: PropTypes.func,
onAbort: PropTypes.func
onAbort: PropTypes.func,
hasSlotCountError: PropTypes.bool,
availabilitylist: PropTypes.array,
selectedDate: PropTypes.number.isRequired
}

export default FooterButtons
export default FooterButtons
56 changes: 47 additions & 9 deletions zmsadmin/js/page/availabilityDay/form/formButtons.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,63 @@
import React from 'react'
import PropTypes from 'prop-types'
import moment from 'moment'

const FormButtons = (props) => {
const { data, onCopy, onExclusion, onEditInFuture, onUpdateSingle, onDelete, selectedDate, hasConflicts } = props
const disabled = ((data && (! data.id || data.__modified === true)) || hasConflicts);
const {
data,
onCopy,
onExclusion,
onEditInFuture,
onUpdateSingle,
onDelete,
selectedDate,
hasConflicts,
hasErrors,
hasSlotCountError,
isCreatingExclusion
} = props;

const disabled = ((data && (!data.id || data.__modified === true)) || hasConflicts || hasErrors || hasSlotCountError);
const isPastDate = moment.unix(selectedDate).isBefore(moment(), 'day');

return (
<div className="body">
<div className="form-actions">
<button onClick={onDelete}
title="Ausgewählte Öffnungszeit löschen"
className="button button--destructive button-delete" disabled={disabled}>Löschen</button>
className="button button--destructive button-delete"
>Löschen</button>
<button onClick={onCopy}
title="Öffnungszeit kopieren und bearbeiten"
className="button button--diamond" disabled={disabled}>Kopieren</button>
<button onClick={onExclusion}
className="button button--diamond"
disabled={disabled || isPastDate}>Kopieren</button>
<button
onClick={onExclusion}
title="Ausnahme von dieser Öffnungszeit eintragen"
className="button button--diamond" disabled={disabled || data.endDate == selectedDate}>Ausnahme</button>
className="button button--diamond"
disabled={disabled || data.endDate == selectedDate || isCreatingExclusion || isPastDate}
>
Ausnahme
</button>
<button onClick={onEditInFuture}
title="Öffnungszeit ab diesem Tag ändern"
className="button button--diamond" disabled={disabled || data.startDate == selectedDate}>Ab diesem Tag ändern</button>
className="button button--diamond"
disabled={disabled || data.startDate == selectedDate || isPastDate}>Ab diesem Tag ändern</button>
<button onClick={onUpdateSingle}
title="Öffnungszeit aktualisieren"
className="button button--diamond" disabled={(data && !data.id) || hasConflicts || props.isCreatingExclusion}>Aktualisieren</button>
className="button button--diamond"
disabled={
(data && !data.id) ||
!data.__modified ||
hasConflicts ||
hasErrors ||
hasSlotCountError ||
isCreatingExclusion ||
isPastDate
}
>
Aktualisieren
</button>
</div>
</div>
)
Expand All @@ -30,6 +66,8 @@ const FormButtons = (props) => {
FormButtons.propTypes = {
data: PropTypes.object,
hasConflicts: PropTypes.bool,
hasErrors: PropTypes.bool,
hasSlotCountError: PropTypes.bool,
onCopy: PropTypes.func,
onExclusion: PropTypes.func,
onEditInFuture: PropTypes.func,
Expand All @@ -39,4 +77,4 @@ FormButtons.propTypes = {
isCreatingExclusion: PropTypes.bool
}

export default FormButtons
export default FormButtons
27 changes: 16 additions & 11 deletions zmsadmin/js/page/availabilityDay/form/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import PropTypes from 'prop-types'
import FormButtons from './formButtons'
import FormContent from './content'
import { getDataValuesFromForm, cleanupFormData, getFormValuesFromData } from '../helpers'
import { hasSlotCountError } from '../form/validate';

class AvailabilityForm extends Component {
constructor(props) {
Expand Down Expand Up @@ -38,36 +39,40 @@ class AvailabilityForm extends Component {
}

const hasConflicts = ((
this.props.conflictList.itemList &&
Object.keys(this.props.conflictList.itemList).length
) ||
this.props.conflictList.itemList &&
Object.keys(this.props.conflictList.itemList).length
)) ? true : false

const hasErrors = (
(
this.props.errorList &&
Object.keys(this.props.errorList).length
)) ? true : false
)) ? true : false

return (
<div>
{<FormContent
today = {this.props.today}
{<FormContent
today={this.props.today}
availabilityList={this.props.availabilityList}
setErrorRef={this.props.setErrorRef}
errorList={this.props.errorList}
conflictList={this.props.conflictList}
{... { data, onChange }} />}
{<FormButtons
data = {data}
onCopy={this.props.onCopy}
{<FormButtons
data={data}
onCopy={this.props.onCopy}
onExclusion={this.props.onExclusion}
onEditInFuture={this.props.onEditInFuture}
onEditInFuture={this.props.onEditInFuture}
onDelete={this.props.onDelete}
onUpdateSingle={this.props.onUpdateSingle}
selectedDate={this.props.selectedDate}
hasConflicts={hasConflicts}
hasErrors={hasErrors}
hasSlotCountError={hasSlotCountError(this.props)}
isCreatingExclusion={this.props.isCreatingExclusion}
/>}
</div>
)
)
}
}

Expand Down
Loading
Loading