Browse Source

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

Thanks to xet7 !
Lauri Ojansivu 1 day ago
parent
commit
d83ce5e633

+ 25 - 0
client/components/main/accessibility.css

@@ -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;
+}

+ 12 - 2
client/components/main/accessibility.jade

@@ -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'}}

+ 27 - 0
client/components/main/accessibility.js

@@ -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');

+ 7 - 9
client/components/settings/settingBody.jade

@@ -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'}}
 

+ 58 - 7
client/components/settings/settingBody.js

@@ -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([]);
 

+ 18 - 1
client/components/sidebar/sidebar.css

@@ -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;
 }

+ 4 - 1
client/components/sidebar/sidebar.jade

@@ -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

+ 12 - 0
client/components/sidebar/sidebar.js

@@ -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()
         },

+ 2 - 1
imports/i18n/data/en.i18n.json

@@ -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"
 }

+ 3 - 0
server/publications/accessibilitySettings.js

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