Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,18 @@ This project (not yet) adheres to [Semantic Versioning](https://semver.org/spec/
### Fixed

- Images remain in the upload section through validation
- Accessibility improvements regarding alternative texts
- Accessibility improvements regarding semantic structure and adaptability
- Accessibility improvements regarding structured navigation and consistent focus indication

### Changed

- Using uv as python package manager now





## mB-v2509.1

### Changed
Expand Down Expand Up @@ -383,3 +390,4 @@ count as labels)
- actions: only create actions for phases and projects if the project is not
a draft (!1437)
- reformat CHANGELOG.md

Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ const CommentManageDropdown = (props) => {
const editTag = django.gettext('Edit')
const deleteTag = django.gettext('Delete')
const reportTag = django.gettext('Report')
const menuLabel = django.gettext('Comment Actions')
return (
<ul className="nav navbar-nav">
<li className="dropdown">
<button
type="button" className="dropdown-toggle" aria-haspopup="true"
aria-expanded="false" data-bs-toggle="dropdown"
aria-expanded="false" aria-label={menuLabel} data-bs-toggle="dropdown"
>
<i className="fa fa-ellipsis-h" aria-hidden="true" />
</button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ exports[`Comment Component renders comment with creator and comment text 1`] = `
<button
aria-expanded="false"
aria-haspopup="true"
aria-label="Comment Actions"
class="dropdown-toggle btn btn--link"
data-bs-toggle="dropdown"
type="button"
Expand Down Expand Up @@ -279,6 +280,7 @@ exports[`Comment Component renders comment with creator and comment text 1`] = `
<button
aria-expanded="false"
aria-haspopup="true"
aria-label="Comment Actions"
class="dropdown-toggle btn btn--link"
data-bs-toggle="dropdown"
type="button"
Expand Down Expand Up @@ -520,6 +522,7 @@ exports[`Comment Component renders comment with moderator badge 1`] = `
<button
aria-expanded="false"
aria-haspopup="true"
aria-label="Comment Actions"
class="dropdown-toggle btn btn--link"
data-bs-toggle="dropdown"
type="button"
Expand Down Expand Up @@ -754,6 +757,7 @@ exports[`Comment Component renders comment with moderator badge 1`] = `
<button
aria-expanded="false"
aria-haspopup="true"
aria-label="Comment Actions"
class="dropdown-toggle btn btn--link"
data-bs-toggle="dropdown"
type="button"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ exports[`CommentBox Component comments are fetched and loading spinners is hidde
class="a4-control-bar__search__logo-start"
/>
<input
autocomplete="on"
class="form-control a4-control-bar__search__input"
id="searchterm"
placeholder=""
Expand Down Expand Up @@ -202,6 +203,7 @@ exports[`CommentBox Component comments are fetched and loading spinners is hidde
class="a4-control-bar__search__logo-start"
/>
<input
autocomplete="on"
class="form-control a4-control-bar__search__input"
id="searchterm"
placeholder=""
Expand Down
13 changes: 13 additions & 0 deletions adhocracy4/comments_async/static/comments_async/comment.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,19 @@ export default class Comment extends React.Component {
}
}

componentDidUpdate (prevProps, prevState) {
// Focus on textarea when entering edit mode
if (!prevState.edit && this.state.edit) {
window.requestAnimationFrame(() => {
const textareaId = 'id_textarea-top' + this.props.id
const textarea = document.getElementById(textareaId)
if (textarea) {
textarea.focus()
}
})
}
}

toggleEdit (e) {
if (e) {
e.preventDefault()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import django from 'django'

const translated = {
edit: django.gettext('Edit'),
delete: django.gettext('Delete')
delete: django.gettext('Delete'),
menuLabel: django.gettext('Comment Actions')
}

const CommentManageDropdown = (props) => {
Expand All @@ -14,6 +15,7 @@ const CommentManageDropdown = (props) => {
className="dropdown-toggle btn btn--link"
aria-haspopup="true"
aria-expanded="false"
aria-label={translated.menuLabel}
data-bs-toggle="dropdown"
>
<i className="fas fa-ellipsis-h" aria-hidden="true" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
<input type="hidden" name="{{ par_name }}" value="{{ value }}">
{% endif %}
{% endfor %}
<input class="search-filter-input" id="{{ id }}" type="search" name="{{ name }}" value="{{ value }}">
<input class="search-filter-input" id="{{ id }}" type="search" name="{{ name }}" value="{{ value }}" autocomplete="on">
<button class="search-filter-btn btn" type="submit" title="{% translate 'Search' %}"><i class="fa fa-search" aria-label="{% translate 'Search' %}"></i></button>
</form>
</div>
9 changes: 7 additions & 2 deletions adhocracy4/polls/static/PollDetail/ChoiceRow.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ const ChoiceInput = ({
choice,
checked,
onInputChange,
disabled
disabled,
name
}) => (
<input
className="poll-row__radio"
type={type}
id={'id_choice-' + choice.id + '-' + (type === 'radio' ? 'single' : 'multiple')}
name={name}
value={choice.id}
checked={checked}
onChange={(event) => onInputChange(event, choice.is_other_choice)}
Expand All @@ -35,7 +37,8 @@ export const ChoiceRow = React.memo(({
otherChoiceAnswer,
onOtherChange,
isReadOnly,
errors
errors,
name
}) => {
const [textareaValue, setTextareaValue] = useState(otherChoiceAnswer)
const [showTextarea, setShowTextarea] = useState(false)
Expand Down Expand Up @@ -78,6 +81,7 @@ export const ChoiceRow = React.memo(({
checked={checked}
onInputChange={handleChange}
disabled={disabled}
name={name}
/>
<span className={'radio__text' + (type === 'checkbox' ? ' radio__text--checkbox' : '')}>
{choice.is_other_choice ? translated.other : choice.label}
Expand All @@ -89,6 +93,7 @@ export const ChoiceRow = React.memo(({
onChange={handleTextareaChange}
disabled={disabled}
error={errors}
label={translated.other}
/>
)}
</label>
Expand Down
49 changes: 27 additions & 22 deletions adhocracy4/polls/static/PollDetail/PollChoice.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -68,28 +68,33 @@ export const PollChoice = (props) => {

return (
<div className="poll poll--question">
<h3>{props.question.label}</h3>
{questionHelpText}
{multiHelpText}
<div className="poll__rows">
{props.question.choices.map((choice) => {
const checked = userChoices.indexOf(choice.id) !== -1
return (
<ChoiceRow
key={choice.id}
choice={choice}
checked={checked}
onInputChange={props.question.multiple_choice ? handleMultiChange : handleSingleChange}
type={props.question.multiple_choice ? 'checkbox' : 'radio'}
disabled={!userAllowedVote || props.question.isReadOnly}
otherChoiceAnswer={otherChoiceAnswer}
onOtherChange={handleOtherChange}
isReadOnly={props.question.isReadOnly}
errors={errors}
/>
)
})}
</div>
<fieldset>
<legend className="poll__question-legend">
<h3>{props.question.label}</h3>
</legend>
{questionHelpText}
{multiHelpText}
<div className="poll__rows">
{props.question.choices.map((choice) => {
const checked = userChoices.indexOf(choice.id) !== -1
return (
<ChoiceRow
key={choice.id}
choice={choice}
checked={checked}
onInputChange={props.question.multiple_choice ? handleMultiChange : handleSingleChange}
type={props.question.multiple_choice ? 'checkbox' : 'radio'}
disabled={!userAllowedVote || props.question.isReadOnly}
otherChoiceAnswer={otherChoiceAnswer}
onOtherChange={handleOtherChange}
isReadOnly={props.question.isReadOnly}
errors={errors}
name={props.question.multiple_choice ? undefined : 'question-' + props.question.id}
/>
)
})}
</div>
</fieldset>
</div>
)
}
2 changes: 1 addition & 1 deletion adhocracy4/static/Captcha.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ const CaptCheck = ({ apiUrl, name, onChange, refresh }) => {
}
type="text"
name="captcheck_selected_answer"
aria-label="Type your answer here."
aria-labelledby={'captcheck_' + captcha.id_prefix + '_question_access'}
autoComplete="off"
onInput={(e) => chooseAnswer(e, e.target.value, false)}
/>
Expand Down
28 changes: 26 additions & 2 deletions adhocracy4/static/Modal.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,31 +17,54 @@ const Modal = ({
onClose
}) => {
const dialogRef = useRef(null)
const toggleButtonRef = useRef(null)
const uniqueId = useId()

const focusButton = (button) => {
if (button?.isConnected) {
button.focus()
}
}

useEffect(() => {
const handleClickOutside = (event) => {
if (event.target === dialogRef.current) {
handleClose()
}
}

const handleDialogClose = () => {
if (toggleButtonRef.current) {
focusButton(toggleButtonRef.current)
toggleButtonRef.current = null
}
onClose?.()
}

const dialog = dialogRef.current
if (dialog) {
dialog.addEventListener('click', handleClickOutside)
return () => dialog.removeEventListener('click', handleClickOutside)
dialog.addEventListener('close', handleDialogClose)
return () => {
dialog.removeEventListener('click', handleClickOutside)
dialog.removeEventListener('close', handleDialogClose)
}
}
})

const findDropdownToggle = (modalButton) => {
return modalButton.closest('.dropdown')?.querySelector('.dropdown-toggle[data-bs-toggle="dropdown"]') || modalButton
}

const handleOpen = (e) => {
e.preventDefault()
toggleButtonRef.current = findDropdownToggle(e.currentTarget)
dialogRef.current?.showModal()
onOpen?.()
}

const handleClose = () => {
dialogRef.current?.close()
onClose?.()
}

const onConfirm = (e) => {
Expand Down Expand Up @@ -104,6 +127,7 @@ const Modal = ({
return (
<>
<button
ref={toggleButtonRef}
className="a4-modal__toggle btn-link link"
onClick={handleOpen}
>
Expand Down
1 change: 1 addition & 0 deletions adhocracy4/static/control_bar/ControlBarSearch.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export const ControlBarSearch = ({ onSearch, term, placeholder }) => {
placeholder={placeholder || ''}
value={value}
id="searchterm"
autoComplete="on"
onChange={handleChange}
/>
</div>
Expand Down
2 changes: 1 addition & 1 deletion tests/filter/test_filter_widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,5 @@ def test_free_text_filter_widget():
assert '<input type="hidden" name="other" value="other_value">' in html
assert (
'<input class="search-filter-input" id="test_id" type="search" '
'name="test_filter" value="value">' in html
'name="test_filter" value="value" autocomplete="on">' in html
)
Loading