Feature: Accessibility page at /accessibility. Settings at Admin Panel. When enabled, link at right sidebar.

Thanks to xet7 !
This commit is contained in:
Lauri Ojansivu 2025-08-04 21:22:14 +03:00
parent 5287319fde
commit d83ce5e633
10 changed files with 168 additions and 21 deletions

View file

@ -72,3 +72,28 @@
border-radius: 5px;
margin-right: 5px;
}
/* Accessibility page styles */
.accessibility-page {
padding: 20px;
max-width: 800px;
margin: 0 auto;
}
.accessibility-page h2 {
font-size: 24px;
margin-bottom: 20px;
color: #4d4d4d;
}
.accessibility-page-content {
background-color: #fff;
padding: 20px;
border-radius: 3px;
box-shadow: 0 1px 2px rgba(0,0,0,0.15);
}
.accessibility-page-content p {
margin-bottom: 16px;
line-height: 1.6;
}

View file

@ -1,8 +1,18 @@
template(name="accessibilityHeaderBar")
if currentUser
h1
| {{_ 'accessibility-title'}}
if isAccessibilityEnabled
= accessibilityTitle
else
| {{_ 'accessibility'}}
template(name="accessibility")
if currentUser
| {{_ 'accessibility-content'}}
.accessibility-page
if isAccessibilityEnabled
.accessibility-page-content
+viewer
| {{accessibilityContent}}
else
.accessibility-page-content
| {{_ 'accessibility-info-not-added-yet'}}

View file

@ -1,11 +1,38 @@
import { ReactiveCache } from '/imports/reactiveCache';
import { TAPi18n } from '/imports/i18n';
// Shared helpers for both accessibility templates
const accessibilityHelpers = {
accessibilityTitle() {
const setting = AccessibilitySettings.findOne({});
return setting && setting.title ? setting.title : TAPi18n.__('accessibility-title');
},
accessibilityContent() {
const setting = AccessibilitySettings.findOne({});
return setting && setting.body ? setting.body : TAPi18n.__('accessibility-content');
},
isAccessibilityEnabled() {
const setting = AccessibilitySettings.findOne({});
return setting && setting.enabled;
}
};
// Main accessibility page component
BlazeComponent.extendComponent({
onCreated() {
this.error = new ReactiveVar('');
this.loading = new ReactiveVar(false);
Meteor.subscribe('setting');
Meteor.subscribe('accessibilitySettings');
},
...accessibilityHelpers
}).register('accessibility');
// Header bar component
BlazeComponent.extendComponent({
onCreated() {
Meteor.subscribe('accessibilitySettings');
},
...accessibilityHelpers
}).register('accessibilityHeaderBar');

View file

@ -189,24 +189,22 @@ template(name='announcementSettings')
template(name='accessibilitySettings')
ul#accessibility-setting.setting-detail
li
a(href="/accessibility" style="text-decoration: underline; color: blue;") {{_ 'accessibility'}}
li
a.flex.js-toggle-accessibility
.materialCheckBox(class="{{#if currentAccessibility.enabled}}is-checked{{/if}}")
span {{_ 'admin-accessibility-active'}}
li
.title {{_ 'accessibility-title'}}
.form-group
input.wekan-form-control#accessibility-title(type="text", placeholder="" value="{{currentSetting.accessibilityTitle}}")
span {{_ 'accessibility-page-enabled'}}
li
.accessibility-content(class="{{#if currentAccessibility.enabled}}{{else}}hide{{/if}}")
ul
li
.title {{_ 'admin-accessibility-title'}}
textarea#admin-accessibility.wekan-form-control= currentAccessibility.accessibilityTitle
.title {{_ 'accessibility-title'}}
textarea#admin-accessibility-title.wekan-form-control= currentAccessibility.title
li
.title {{_ 'admin-accessibility-content'}}
textarea#admin-accessibility.wekan-form-control= currentAccessibility.accessibilityContent
.title {{_ 'accessibility-content'}}
textarea#admin-accessibility-content.wekan-form-control= currentAccessibility.body
li
button.js-accessibility-save.primary {{_ 'save'}}

View file

@ -12,6 +12,7 @@ BlazeComponent.extendComponent({
this.accountSetting = new ReactiveVar(false);
this.tableVisibilityModeSetting = new ReactiveVar(false);
this.announcementSetting = new ReactiveVar(false);
this.accessibilitySetting = new ReactiveVar(false);
this.layoutSetting = new ReactiveVar(false);
this.webhookSetting = new ReactiveVar(false);
@ -20,6 +21,7 @@ BlazeComponent.extendComponent({
Meteor.subscribe('accountSettings');
Meteor.subscribe('tableVisibilityModeSettings');
Meteor.subscribe('announcements');
Meteor.subscribe('accessibilitySettings');
Meteor.subscribe('globalwebhooks');
},
@ -106,6 +108,7 @@ BlazeComponent.extendComponent({
this.emailSetting.set('email-setting' === targetID);
this.accountSetting.set('account-setting' === targetID);
this.announcementSetting.set('announcement-setting' === targetID);
this.accessibilitySetting.set('accessibility-setting' === targetID);
this.layoutSetting.set('layout-setting' === targetID);
this.webhookSetting.set('webhook-setting' === targetID);
this.tableVisibilityModeSetting.set('tableVisibilityMode-setting' === targetID);
@ -242,7 +245,6 @@ BlazeComponent.extendComponent({
const displayAuthenticationMethod =
$('input[name=displayAuthenticationMethod]:checked').val() === 'true';
const defaultAuthenticationMethod = $('#defaultAuthenticationMethod').val();
/*
const accessibilityPageEnabled = $('input[name=accessibilityPageEnabled]:checked').val() === 'true';
const accessibilityTitle = $('#accessibility-title')
.val()
@ -250,7 +252,6 @@ BlazeComponent.extendComponent({
const accessibilityContent = $('#accessibility-content')
.val()
.trim();
*/
const spinnerName = $('#spinnerName').val();
try {
@ -274,13 +275,11 @@ BlazeComponent.extendComponent({
oidcBtnText,
mailDomainName,
legalNotice,
},
});
/*
accessibilityPageEnabled,
accessibilityTitle,
accessibilityContent,
*/
},
});
} catch (e) {
return;
} finally {
@ -317,7 +316,6 @@ BlazeComponent.extendComponent({
'click a.js-toggle-hide-logo': this.toggleHideLogo,
'click a.js-toggle-hide-card-counter-list': this.toggleHideCardCounterList,
'click a.js-toggle-hide-board-member-list': this.toggleHideBoardMemberList,
'click a.js-toggle-accessibility-page-enabled': this.toggleAccessibilityPageEnabled,
'click button.js-save-layout': this.saveLayout,
'click a.js-toggle-display-authentication-method': this
.toggleDisplayAuthenticationMethod,
@ -469,6 +467,59 @@ BlazeComponent.extendComponent({
},
}).register('announcementSettings');
BlazeComponent.extendComponent({
onCreated() {
this.loading = new ReactiveVar(false);
},
setLoading(w) {
this.loading.set(w);
},
currentAccessibility() {
return AccessibilitySettings.findOne();
},
saveAccessibility() {
const title = $('#admin-accessibility-title')
.val()
.trim();
const content = $('#admin-accessibility-content')
.val()
.trim();
AccessibilitySettings.update(AccessibilitySettings.findOne()._id, {
$set: {
title: title,
body: content
},
});
},
toggleAccessibility() {
this.setLoading(true);
const accessibilitySetting = this.currentAccessibility();
const isActive = accessibilitySetting.enabled;
AccessibilitySettings.update(accessibilitySetting._id, {
$set: { enabled: !isActive },
});
this.setLoading(false);
if (isActive) {
$('.accessibility-content').slideUp();
} else {
$('.accessibility-content').slideDown();
}
},
events() {
return [
{
'click a.js-toggle-accessibility': this.toggleAccessibility,
'click button.js-accessibility-save': this.saveAccessibility,
},
];
},
}).register('accessibilitySettings');
Template.selectAuthenticationMethod.onCreated(function() {
this.authenticationMethods = new ReactiveVar([]);

View file

@ -106,7 +106,7 @@
top: 7px;
font-size: 1em;
line-height: 1.6em;
color: #999;
color: #000;
}
.sidebar .sidebar-shortcuts .sidebar-btn {
margin-left: 3px;
@ -146,6 +146,23 @@
font-size: 24px;
transition: transform 0.5s;
}
.sidebar-accessibility {
color: #4d4d4d;
padding: 5px 10px;
display: flex;
align-items: center;
text-decoration: none;
border-radius: 3px;
cursor: pointer;
margin-left: auto;
margin-right: 30px;
}
.sidebar-accessibility:hover {
background-color: #d9d9d9;
}
.sidebar-accessibility span {
margin-left: 5px;
}
.board-sidebar.is-open .sidebar-tongue {
left: -28px;
}

View file

@ -12,6 +12,10 @@ template(name="sidebar")
a.sidebar-btn.js-keyboard-shortcuts-toggle(
title="{{#if isKeyboardShortcuts}}{{_ 'keyboard-shortcuts-enabled'}}{{else}}{{_ 'keyboard-shortcuts-disabled'}}{{/if}}")
i.fa(class="fa-solid fa-{{#if isKeyboardShortcuts}}check-square-o{{else}}ban{{/if}}")
if isAccessibilityEnabled
a.sidebar-accessibility
i.fa.fa-universal-access
span {{_ 'accessibility'}}
a.sidebar-xmark.js-close-sidebar ✕
.sidebar-content.js-board-sidebar-content
//a.hide-btn.js-hide-sidebar
@ -26,7 +30,6 @@ template(name="sidebar")
template(name='homeSidebar')
hr
+membersWidget
| {{_ 'accessibility'}}
hr
+labelsWidget
hr

View file

@ -26,6 +26,9 @@ BlazeComponent.extendComponent({
this._hideCardCounterList = new ReactiveVar(false);
this._hideBoardMemberList = new ReactiveVar(false);
Sidebar = this;
// Subscribe to accessibility settings
Meteor.subscribe('accessibilitySettings');
},
onDestroyed() {
@ -115,6 +118,11 @@ BlazeComponent.extendComponent({
return user && user.isVerticalScrollbars();
},
isAccessibilityEnabled() {
const setting = AccessibilitySettings.findOne({});
return setting && setting.enabled;
},
events() {
return [
{
@ -145,6 +153,10 @@ BlazeComponent.extendComponent({
'click .js-show-week-of-year-toggle'() {
ReactiveCache.getCurrentUser().toggleShowWeekOfYear();
},
'click .sidebar-accessibility'() {
FlowRouter.go('accessibility');
Sidebar.toggle();
},
'click .js-close-sidebar'() {
Sidebar.toggle()
},

View file

@ -1270,6 +1270,7 @@
"supportPopup-title": "Support",
"accessibility": "Accessibility",
"accessibility-page-enabled": "Accessibility page enabled",
"accessibility-title": "Accessibility topic",
"accessibility-info-not-added-yet": "Accessibility info has not been added yet",
"accessibility-title": "Accessibility title",
"accessibility-content": "Accessibility content"
}

View file

@ -0,0 +1,3 @@
Meteor.publish('accessibilitySettings', function() {
return AccessibilitySettings.find({});
});