Most Unicode Icons back to Font Awesome 4.7 for better accessibility. Less always visible buttons, More at ☰ Men.

Thanks to xet7 !
This commit is contained in:
Lauri Ojansivu 2026-01-28 12:59:07 +02:00
parent 440f553de0
commit 7ad04f4535
84 changed files with 1828 additions and 1381 deletions

View file

@ -1,6 +1,7 @@
template(name="archivedBoards")
h2
span(title="{{_ 'archived-boards'}}") 📦
span(title="{{_ 'archived-boards'}}")
i.fa.fa-archive
| {{_ 'archived-boards'}}
ul.archived-lists
@ -8,10 +9,10 @@ template(name="archivedBoards")
li.archived-lists-item
div.board-header-btns
button.board-header-btn.js-delete-board
| 🗑️
i.fa.fa-trash
| {{_ 'delete-board'}}
button.board-header-btn.js-restore-board
| ↩️
i.fa.fa-undo
| {{_ 'restore-board'}}
= title
span {{ moment archivedAt 'LLL' }}

View file

@ -339,9 +339,9 @@ BlazeComponent.extendComponent({
.js-add-card[tabindex] {
outline: none;
}
/* Hamburger menu */
.fa-bars, .icon-hamburger {
color: #222 !important;
/* Sidebar hamburger menu button in header */
.js-toggle-sidebar .fa-bars {
color: #fff !important;
}
/* Grey icons in card detail header */
.card-detail-header .fa, .card-detail-header .icon {

View file

@ -49,6 +49,12 @@ THEME - NEPHRITIS
border-bottom: 2px solid #27ae60;
border-right: 2px solid #27ae60;
}
.board-color-nephritis .checklist-progress-bar {
background-color: #d4f1dd !important;
}
.board-color-nephritis .checklist-progress-bar .checklist-progress {
background-color: #27ae60 !important;
}
.board-color-nephritis .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #e7faef;
}
@ -150,6 +156,12 @@ THEME - Pomegranate
border-bottom: 2px solid #c0392b;
border-right: 2px solid #c0392b;
}
.board-color-pomegranate .checklist-progress-bar {
background-color: #f5d5d2 !important;
}
.board-color-pomegranate .checklist-progress-bar .checklist-progress {
background-color: #c0392b !important;
}
.board-color-pomegranate .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #faeae9;
}
@ -251,6 +263,12 @@ THEME - Belize
border-bottom: 2px solid #2980b9;
border-right: 2px solid #2980b9;
}
.board-color-belize .checklist-progress-bar {
background-color: #d1e7f5 !important;
}
.board-color-belize .checklist-progress-bar .checklist-progress {
background-color: #2980b9 !important;
}
.board-color-belize .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #e8f3fa;
}
@ -352,6 +370,12 @@ THEME - Wisteria
border-bottom: 2px solid #8e44ad;
border-right: 2px solid #8e44ad;
}
.board-color-wisteria .checklist-progress-bar {
background-color: #e8d9f0 !important;
}
.board-color-wisteria .checklist-progress-bar .checklist-progress {
background-color: #8e44ad !important;
}
.board-color-wisteria .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #f4ecf7;
}
@ -453,6 +477,12 @@ THEME - Midnight
border-bottom: 2px solid #2c3e50;
border-right: 2px solid #2c3e50;
}
.board-color-midnight .checklist-progress-bar {
background-color: #d2dae2 !important;
}
.board-color-midnight .checklist-progress-bar .checklist-progress {
background-color: #2c3e50 !important;
}
.board-color-midnight .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #e6ecf1;
}
@ -554,6 +584,12 @@ THEME - Pumpkin
border-bottom: 2px solid #e67e22;
border-right: 2px solid #e67e22;
}
.board-color-pumpkin .checklist-progress-bar {
background-color: #f9e5d1 !important;
}
.board-color-pumpkin .checklist-progress-bar .checklist-progress {
background-color: #e67e22 !important;
}
.board-color-pumpkin .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #fdf2e9;
}
@ -655,6 +691,12 @@ THEME - Moderate Pink
border-bottom: 2px solid #cd5a91;
border-right: 2px solid #cd5a91;
}
.board-color-moderatepink .checklist-progress-bar {
background-color: #f4dde8 !important;
}
.board-color-moderatepink .checklist-progress-bar .checklist-progress {
background-color: #cd5a91 !important;
}
.board-color-moderatepink .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #faeef4;
}
@ -756,6 +798,12 @@ THEME - Strong Cyan
border-bottom: 2px solid #00aecc;
border-right: 2px solid #00aecc;
}
.board-color-strongcyan .checklist-progress-bar {
background-color: #ccf2f9 !important;
}
.board-color-strongcyan .checklist-progress-bar .checklist-progress {
background-color: #00aecc !important;
}
.board-color-strongcyan .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #e0fbff;
}
@ -857,6 +905,12 @@ THEME - Lime Green
border-bottom: 2px solid #4bbf6b;
border-right: 2px solid #4bbf6b;
}
.board-color-limegreen .checklist-progress-bar {
background-color: #daf4de !important;
}
.board-color-limegreen .checklist-progress-bar .checklist-progress {
background-color: #4bbf6b !important;
}
.board-color-limegreen .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #edf9f0;
}
@ -959,6 +1013,12 @@ THEME - Dark
border-bottom: 2px solid #2c3e51;
border-right: 2px solid #2c3e51;
}
.board-color-dark .checklist-progress-bar {
background-color: #d2dae2 !important;
}
.board-color-dark .checklist-progress-bar .checklist-progress {
background-color: #2c3e51 !important;
}
.board-color-dark .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #e6ecf1;
}
@ -1162,6 +1222,12 @@ THEME - Relax
border-bottom: 2px solid #27ae61;
border-right: 2px solid #27ae61;
}
.board-color-relax .checklist-progress-bar {
background-color: #d4f1dd !important;
}
.board-color-relax .checklist-progress-bar .checklist-progress {
background-color: #27ae61 !important;
}
.board-color-relax .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #e7faef;
}
@ -1292,6 +1358,12 @@ THEME - Corteza
border-bottom: 2px solid #568ba2;
border-right: 2px solid #568ba2;
}
.board-color-corteza .checklist-progress-bar {
background-color: #dce6ec !important;
}
.board-color-corteza .checklist-progress-bar .checklist-progress {
background-color: #568ba2 !important;
}
.board-color-corteza .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #eef3f6;
}
@ -1397,6 +1469,12 @@ THEME - Clear Blue
border-bottom: 2px solid #499bea;
border-right: 2px solid #499bea;
}
.board-color-clearblue .checklist-progress-bar {
background-color: #daeefb !important;
}
.board-color-clearblue .checklist-progress-bar .checklist-progress {
background-color: #499bea !important;
}
.board-color-clearblue .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #e0fbff;
}
@ -1660,6 +1738,12 @@ THEME - Natural
border-bottom: 2px solid #596557;
border-right: 2px solid #596557;
}
.board-color-natural .checklist-progress-bar {
background-color: #dee0dd !important;
}
.board-color-natural .checklist-progress-bar .checklist-progress {
background-color: #596557 !important;
}
.board-color-natural .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #eef0ee;
}
@ -1770,6 +1854,12 @@ THEME - Modern
border-bottom: 2px solid #2a80b8;
border-right: 2px solid #2a80b8;
}
.board-color-modern .checklist-progress-bar {
background-color: #d1e7f5 !important;
}
.board-color-modern .checklist-progress-bar .checklist-progress {
background-color: #2a80b8 !important;
}
.board-color-modern .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #e8f3fa;
}
@ -2062,6 +2152,12 @@ THEME - Modern Dark
border-bottom: 2px solid #2a2a2a;
border-right: 2px solid #2a2a2a;
}
.board-color-moderndark .checklist-progress-bar {
background-color: #d1d1d1 !important;
}
.board-color-moderndark .checklist-progress-bar .checklist-progress {
background-color: #2a2a2a !important;
}
.board-color-moderndark .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #eaeaea;
}
@ -2547,6 +2643,12 @@ THEME - Exodark
border-bottom: 2px solid #dbdbdb!important;/*Fix contrast of checkbox*/
border-right: 2px solid #dbdbdb!important;
}
.board-color-exodark .checklist-progress-bar {
background-color: #cccccc !important;
}
.board-color-exodark .checklist-progress-bar .checklist-progress {
background-color: #222 !important;
}
.board-color-exodark .is-multiselection-active .multi-selection-checkbox.is-checked + .minicard {
background: #e9e9e9;
}
@ -3140,6 +3242,12 @@ THEME - Clean Dark
margin-left: 3px;
margin-top: 3px;
}
.board-color-cleandark .checklist-progress-bar {
background-color: #6b6b78 !important;
}
.board-color-cleandark .checklist-progress-bar .checklist-progress {
background-color: #23232B !important;
}
.board-color-cleandark .allBoards {
white-space: nowrap;
@ -3892,6 +4000,13 @@ THEME - Clean Light
margin-left: 3px;
margin-top: 3px;
}
.board-color-cleanlight .checklist-progress-bar {
background-color: #f5f5f5 !important;
}
.board-color-cleanlight .checklist-progress-bar .checklist-progress {
background-color: #c0c0c0 !important;
color: #010101 !important;
}
.board-color-cleanlight .allBoards {
white-space: nowrap;

View file

@ -14,41 +14,39 @@ template(name="boardHeaderBar")
with currentBoard
if currentUser.isBoardAdmin
a.board-header-btn(class="{{#if currentUser.isBoardAdmin}}js-edit-board-title{{else}}is-disabled{{/if}}" title="{{_ 'edit'}}" value=title)
| ✏️
i.fa.fa-pencil-square-o
a.board-header-btn(
class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}"
title="{{_ currentBoard.permission}}")
| {{#if currentBoard.isPublic}}🌐{{else}}🔒{{/if}}
i.fa(class="{{#if currentBoard.isPublic}}fa-globe{{else}}fa-lock{{/if}}")
span {{_ currentBoard.permission}}
a.board-header-btn.js-watch-board(
title="{{_ watchLevel }}")
if $eq watchLevel "watching"
| 👁️
i.fa.fa-eye
if $eq watchLevel "tracking"
| 🔔
i.fa.fa-bell
if $eq watchLevel "muted"
| 🔕
i.fa.fa-bell-slash
span {{_ watchLevel}}
a.board-header-btn.js-star-board(title="{{_ 'star-board'}}")
if isStarred
| ⭐
else
| ☆
a.board-header-btn.js-star-board(class="{{#if isStarred}}is-active{{/if}}"
title="{{#if isStarred}}{{_ 'click-to-unstar'}}{{else}}{{_ 'click-to-star'}}{{/if}} {{_ 'starred-boards-description'}}")
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
if showStarCounter
span.board-star-counter {{currentBoard.stars}}
a.board-header-btn(title="{{_ 'sort-cards'}}" class="{{#if isSortActive }}emphasis{{else}} js-sort-cards {{/if}}")
| {{sortCardsIcon}}
i.fa.fa-sort
span {{#if isSortActive }}{{_ 'sort-is-on'}}{{else}}{{_ 'sort-cards'}}{{/if}}
if isSortActive
a.board-header-btn-close.js-sort-reset(title="{{_ 'remove-sort'}}")
| ❌
i.fa.fa-times-thin
else
a.board-header-btn.js-log-in(
title="{{_ 'log-in'}}")
| 🚪
i.fa.fa-sign-in
span {{_ 'log-in'}}
.board-header-btns.center
@ -59,41 +57,40 @@ template(name="boardHeaderBar")
if currentUser
with currentBoard
a.board-header-btn(class="{{#if currentUser.isBoardAdmin}}js-edit-board-title{{else}}is-disabled{{/if}}" title="{{_ 'edit'}}" value=title)
| ✏️
i.fa.fa-pencil-square-o
a.board-header-btn(
class="{{#if currentUser.isBoardAdmin}}js-change-visibility{{else}}is-disabled{{/if}}"
title="{{_ currentBoard.permission}}")
| {{#if currentBoard.isPublic}}🌐{{else}}🔒{{/if}}
i.fa(class="{{#if currentBoard.isPublic}}fa-globe{{else}}fa-lock{{/if}}")
a.board-header-btn.js-watch-board(
title="{{_ watchLevel }}")
if $eq watchLevel "watching"
| 👁️
i.fa.fa-eye
if $eq watchLevel "tracking"
| 🔔
i.fa.fa-bell
if $eq watchLevel "muted"
| 🔕
a.board-header-btn.js-star-board(title="{{_ 'star-board'}}")
if isStarred
| ⭐
else
| ☆
i.fa.fa-bell-slash
a.board-header-btn.js-star-board(class="{{#if isStarred}}is-active{{/if}}"
title="{{#if isStarred}}{{_ 'click-to-unstar'}}{{else}}{{_ 'click-to-star'}}{{/if}} {{_ 'starred-boards-description'}}")
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
a.board-header-btn(title="{{_ 'sort-cards'}}" class="{{#if isSortActive }}emphasis{{else}} js-sort-cards {{/if}}")
| {{sortCardsIcon}}
i.fa.fa-sort
span {{#if isSortActive }}{{_ 'sort-is-on'}}{{else}}{{_ 'sort-cards'}}{{/if}}
if isSortActive
a.board-header-btn-close.js-sort-reset(title="{{_ 'remove-sort'}}")
| ❌
i.fa.fa-times-thin
else
a.board-header-btn.js-log-in(
title="{{_ 'log-in'}}")
| 🚪
i.fa.fa-sign-in
if isSandstorm
if currentUser
a.board-header-btn.js-open-archived-board
| 📦
i.fa.fa-archive
//if showSort
// a.board-header-btn.js-open-sort-view(title="{{_ 'sort-desc'}}")
@ -103,72 +100,68 @@ template(name="boardHeaderBar")
a.board-header-btn.js-open-filter-view(
title="{{#if Filter.isActive}}{{_ 'filter-on-desc'}}{{else}}{{_ 'filter'}}{{/if}}"
class="{{#if Filter.isActive}}js-filter-active{{/if}}")
| 🎛️
i.fa.fa-filter
span {{#if Filter.isActive}}{{_ 'filter-on-desc'}}{{else}}{{_ 'filter'}}{{/if}}
if Filter.isActive
a.board-header-btn-close.js-filter-reset(title="{{_ 'filter-clear'}}")
| ❌
i.fa.fa-times-thin
a.board-header-btn.js-open-search-view(title="{{_ 'search'}}")
| 🔍
i.fa.fa-search
span {{_ 'search'}}
unless currentBoard.isTemplatesBoard
a.board-header-btn.js-toggle-board-view(
title="{{_ 'board-view'}}")
| ▼
a.board-header-btn.js-toggle-board-view
i.fa.fa-caret-down
if $eq boardView 'board-view-swimlanes'
| 🏊
i.fa.fa-th-large
if $eq boardView 'board-view-lists'
| 📋
i.fa.fa-trello
if $eq boardView 'board-view-cal'
| 📅
i.fa.fa-calendar
if $eq boardView 'board-view-gantt'
| 📊
i.fa.fa-bar-chart
span
if $eq boardView 'board-view-swimlanes'
| {{_ 'board-view-swimlanes'}}
| {{_ 'swimlanes'}}
if $eq boardView 'board-view-lists'
| {{_ 'board-view-lists'}}
| {{_ 'lists'}}
if $eq boardView 'board-view-cal'
| {{_ 'board-view-cal'}}
| {{_ 'calendar'}}
if $eq boardView 'board-view-gantt'
| {{_ 'board-view-gantt'}}
| {{_ 'gantt'}}
if canModifyBoard
a.board-header-btn.js-multiselection-activate(
title="{{#if MultiSelection.isActive}}{{_ 'multi-selection-on'}}{{else}}{{_ 'multi-selection'}}{{/if}}"
class="{{#if MultiSelection.isActive}}js-multiselection-active{{/if}}")
if MultiSelection.isActive
| 🗂️
else
| 🗂️
class="{{#if MultiSelection.isActive}}emphasis{{/if}}")
i.fa.fa-check-square-o
span {{#if MultiSelection.isActive}}{{_ 'multi-selection-on'}}{{else}}{{_ 'multi-selection'}}{{/if}}
if MultiSelection.isActive
a.board-header-btn-close.js-multiselection-reset(title="{{_ 'multi-selection-off'}}")
| ❌
a.board-header-btn-close.js-multiselection-reset(title="{{_ 'filter-clear'}}")
i.fa.fa-times-thin
.separator
a.board-header-btn.js-toggle-sidebar(title="{{_ 'sidebar-open'}} {{_ 'or'}} {{_ 'sidebar-close'}}")
| ☰
i.fa.fa-bars
template(name="boardVisibilityList")
ul.pop-over-list
li
with "private"
a.js-select-visibility
| 🔒
i.fa.fa-lock
| {{_ 'private'}}
if visibilityCheck
| ✅
i.fa.fa-check
span.sub-name {{_ 'private-desc'}}
if notAllowPrivateVisibilityOnly
li
with "public"
a.js-select-visibility
| 🌐
i.fa.fa-globe
| {{_ 'public'}}
if visibilityCheck
| ✅
i.fa.fa-check
span.sub-name {{_ 'public-desc'}}
template(name="boardChangeVisibilityPopup")
@ -179,26 +172,26 @@ template(name="boardChangeWatchPopup")
li
with "watching"
a.js-select-watch
| 👁️
i.fa.fa-eye
| {{_ 'watching'}}
if watchCheck
| ✅
i.fa.fa-check
span.sub-name {{_ 'watching-info'}}
li
with "tracking"
a.js-select-watch
| 🔔
i.fa.fa-bell
| {{_ 'tracking'}}
if watchCheck
| ✅
i.fa.fa-check
span.sub-name {{_ 'tracking-info'}}
li
with "muted"
a.js-select-watch
| 🔕
i.fa.fa-bell-slash
| {{_ 'muted'}}
if watchCheck
| ✅
i.fa.fa-check
span.sub-name {{_ 'muted-info'}}
template(name="boardChangeViewPopup")
@ -206,31 +199,31 @@ template(name="boardChangeViewPopup")
li
with "board-view-swimlanes"
a.js-open-swimlanes-view
| 🏊
| {{_ 'board-view-swimlanes'}}
i.fa.fa-th-large
| {{_ 'swimlanes'}}
if $eq Utils.boardView "board-view-swimlanes"
| ✅
i.fa.fa-check
li
with "board-view-lists"
a.js-open-lists-view
| 📋
i.fa.fa-trello
| {{_ 'board-view-lists'}}
if $eq Utils.boardView "board-view-lists"
| ✅
i.fa.fa-check
li
with "board-view-cal"
a.js-open-cal-view
| 📅
i.fa.fa-calendar
| {{_ 'board-view-cal'}}
if $eq Utils.boardView "board-view-cal"
| ✅
i.fa.fa-check
li
with "board-view-gantt"
a.js-open-gantt-view
| 📊
i.fa.fa-bar-chart
| {{_ 'board-view-gantt'}}
if $eq Utils.boardView "board-view-gantt"
| ✅
i.fa.fa-check
template(name="createBoard")
form
@ -242,11 +235,11 @@ template(name="createBoard")
else
p.quiet
if $eq visibility.get 'public'
span 🌐
span.fa.fa-globe.colorful
= " "
| {{{_ 'board-public-info'}}}
else
span 🔒
span.fa.fa-lock.colorful
= " "
| {{{_ 'board-private-info'}}}
a.js-change-visibility {{_ 'change'}}.
@ -271,11 +264,11 @@ template(name="createBoardPopup")
else
p.quiet
if $eq visibility.get 'public'
span 🌐
span.fa.fa-globe.colorful
= " "
| {{{_ 'board-public-info'}}}
else
span 🔒
span.fa.fa-lock.colorful
= " "
| {{{_ 'board-private-info'}}}
a.js-change-visibility {{_ 'change'}}.
@ -301,11 +294,11 @@ template(name="createTemplateContainerPopup")
else
p.quiet
if $eq visibility.get 'public'
span 🌐
span.fa.fa-globe.colorful
= " "
| {{{_ 'board-public-info'}}}
else
span 🔒
span.fa.fa-lock.colorful
= " "
| {{{_ 'board-private-info'}}}
a.js-change-visibility {{_ 'change'}}.
@ -332,8 +325,7 @@ template(name="createTemplateContainerPopup")
// | {{#if $eq Direction "fa-arrow-up"}}⬆️{{else}}⬇️{{/if}}
// | {{_ value.label }}{{_ value.shortLabel}}
// if $eq sortby value.name
// | ✅
// i.fa.fa-check
template(name="boardChangeTitlePopup")
form
label
@ -353,21 +345,21 @@ template(name="cardsSortPopup")
ul.pop-over-list
li
a.js-sort-due
| 📅
i.fa.fa-calendar
| {{_ 'due-date'}}
hr
li
a.js-sort-title
| 🔤
i.fa.fa-sort-alpha-asc
| {{_ 'title-alphabetically'}}
hr
li
a.js-sort-created-desc
| ⬇️
i.fa.fa-arrow-down
| {{_ 'created-at-newest-first'}}
hr
li
a.js-sort-created-asc
| ⬆️
i.fa.fa-arrow-up
| {{_ 'created-at-oldest-first'}}

View file

@ -436,10 +436,17 @@
background-color: #999; /* Darker background for better text contrast */
border-radius: 3px;
padding: 36px 8px 32px 8px;
color: #fff; /* White text */
}
.board-list .js-add-board .label i {
color: #fff; /* White icon */
}
.board-list .js-add-board .label:hover {
background-color: #808080; /* Even darker on hover */
}
.board-list .js-add-board .label:hover i {
color: #fff; /* Keep icon white on hover */
}
.board-list .is-star-active,
.board-list .is-not-star-active {
top: 0;

View file

@ -9,24 +9,28 @@ template(name="boardList")
li(class="menu-item {{#if isSelectedMenu 'starred'}}active{{/if}}")
a.js-select-menu(data-type="starred")
span.menu-label
span.emoji-icon ⭐
span.emoji-icon
i.fa.fa-star
| {{_ 'allboards.starred'}}
span.menu-count {{menuItemCount 'starred'}}
li(class="menu-item {{#if isSelectedMenu 'templates'}}active{{/if}}")
a.js-select-menu(data-type="templates")
span.menu-label
span.emoji-icon 📋
span.emoji-icon
i.fa.fa-clipboard
| {{_ 'allboards.templates'}}
span.menu-count {{menuItemCount 'templates'}}
li(class="menu-item {{#if isSelectedMenu 'remaining'}}active{{/if}}")
a.js-select-menu(data-type="remaining")
span.menu-label
span.emoji-icon 📂
span.emoji-icon
i.fa.fa-folder
| {{_ 'allboards.remaining'}}
span.menu-count {{menuItemCount 'remaining'}}
.workspaces-header
span
span.emoji-icon 🗂️
span.emoji-icon
i.fa.fa-folder-open
| {{_ 'allboards.workspaces'}}
a.js-add-workspace(title="{{_ 'allboards.add-workspace'}}") +
// Workspaces tree
@ -51,11 +55,13 @@ template(name="boardList")
li.AllBoardBtns
div.AllBoardButtonsContainer
if userHasOrgsOrTeams
span.emoji-icon 🔍
span.emoji-icon
i.fa.fa-search
input#filterBtn(type="button" value="{{_ 'filter'}}")
button#resetBtn.filter-reset-btn
span.reset-icon
span.emoji-icon ❌
span.emoji-icon
i.fa.fa-times-thin
span {{_ 'filter-clear'}}
// Right boards grid
@ -66,34 +72,41 @@ template(name="boardList")
span.path-text {{currentMenuPath.text}}
if BoardMultiSelection.isActive
span.multiselection-hint
span.emoji-icon 📌
span.emoji-icon
i.fa.fa-thumb-tack
| {{_ 'multi-selection-active'}}
.path-right
if canModifyBoards
if hasBoardsSelected
button.js-archive-selected-boards.board-header-btn
span.emoji-icon 📦
span.emoji-icon
i.fa.fa-archive
span {{_ 'archive-board'}}
button.js-duplicate-selected-boards.board-header-btn
span.emoji-icon 📋
span.emoji-icon
i.fa.fa-clipboard
span {{_ 'duplicate-board'}}
a.board-header-btn.js-multiselection-activate(
title="{{#if BoardMultiSelection.isActive}}{{_ 'multi-selection-on'}}{{else}}{{_ 'multi-selection'}}{{/if}}"
class="{{#if BoardMultiSelection.isActive}}emphasis{{/if}}")
span.emoji-icon ☑️
span.emoji-icon
i.fa.fa-check-square-o
if BoardMultiSelection.isActive
a.board-header-btn-close.js-multiselection-reset(title="{{_ 'filter-clear'}}")
span.emoji-icon ✖
span.emoji-icon
i.fa.fa-times
ul.board-list.clearfix.js-boards(class="{{#if isMiniScreen}}mobile-view{{/if}} {{#if BoardMultiSelection.isActive}}is-multiselection-active{{/if}}")
li.js-add-board
if isSelectedMenu 'templates'
a.board-list-item.label(title="{{_ 'add-template-container'}}")
span.emoji-icon
| {{_ 'add-template-container'}}
span.emoji-icon
i.fa.fa-plus
|  {{_ 'add-template-container'}}
else
a.board-list-item.label(title="{{_ 'add-board'}}")
span.emoji-icon
| {{_ 'add-board'}}
span.emoji-icon
i.fa.fa-plus
|  {{_ 'add-board'}}
each boards
li.js-board(class="{{_id}} {{#if isStarred}}starred{{/if}} {{colorClass}} {{#if BoardMultiSelection.isSelected _id}}is-checked{{/if}}", draggable="true")
if isInvited
@ -118,7 +131,8 @@ template(name="boardList")
.materialCheckBox.multi-selection-checkbox.js-toggle-board-multi-selection(
class="{{#if BoardMultiSelection.isSelected _id}}is-checked{{/if}}")
span.board-handle(title="{{_ 'drag-board'}}")
span.emoji-icon ↕️
span.emoji-icon
i.fa.fa-arrows
a.js-open-board(href="{{pathFor 'board' id=_id slug=slug}}")
span.details
@ -132,19 +146,21 @@ template(name="boardList")
span.js-has-spenttime-cards(
class="{{#if hasOvertimeCards}}has-overtime-card-active{{else}}no-overtime-card-active{{/if}}"
title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}")
span.emoji-icon ⏱️
span.emoji-icon
i.fa.fa-clock-o
span.js-star-board(
class="{{#if isStarred}}is-star-active{{else}}is-not-star-active{{/if}}"
title="{{_ 'star-board-title'}}")
span.emoji-icon
| {{#if isStarred}}⭐{{else}}☆{{/if}}
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
else
.board-list-item
if BoardMultiSelection.isActive
.materialCheckBox.multi-selection-checkbox.js-toggle-board-multi-selection(
class="{{#if BoardMultiSelection.isSelected _id}}is-checked{{/if}}")
span.board-handle(title="{{_ 'drag-board'}}")
span.emoji-icon ↕️
span.emoji-icon
i.fa.fa-arrows
a.js-open-board(href="{{pathFor 'board' id=_id slug=slug}}")
span.details
@ -170,12 +186,13 @@ template(name="boardList")
span.js-has-spenttime-cards(
class="{{#if hasOvertimeCards}}has-overtime-card-active{{else}}no-overtime-card-active{{/if}}"
title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}")
span.emoji-icon ⏱️
span.emoji-icon
i.fa.fa-clock-o
a.js-star-board(
class="{{#if isStarred}}is-star-active{{else}}is-not-star-active{{/if}}"
title="{{_ 'star-board-title'}}")
span.emoji-icon
| {{#if isStarred}}⭐{{else}}☆{{/if}}
i.fa(class="fa-star{{#unless isStarred}}-o{{/unless}}")
template(name="boardListHeaderBar")
h1 {{_ title }}
@ -195,7 +212,8 @@ template(name="workspaceTree")
li.workspace-node(class="{{#if $eq id selectedWorkspaceId}}active{{/if}}" data-workspace-id="{{id}}" draggable="true")
.workspace-node-content
span.workspace-drag-handle
span.emoji-icon ↕️
span.emoji-icon
i.fa.fa-arrows
a.js-select-workspace(data-id="{{id}}")
span.workspace-icon
@ -203,10 +221,12 @@ template(name="workspaceTree")
+viewer
= icon
else
span.emoji-icon 📁
span.emoji-icon
i.fa.fa-folder
span.workspace-name= name
a.js-edit-workspace(data-id="{{id}}" title="{{_ 'allboards.edit-workspace'}}")
span.emoji-icon ✏️
span.emoji-icon
i.fa.fa-pencil-square-o
span.workspace-count {{workspaceCount id}}
a.js-add-subworkspace(data-id="{{id}}" title="{{_ 'allboards.add-subworkspace'}}") +
if children

View file

@ -197,48 +197,66 @@ BlazeComponent.extendComponent({
return ret;
},
currentMenuPath() {
const selectedMenuVar = this.selectedMenu;
if (!selectedMenuVar) {
return { icon: '🗂️', text: TAPi18n.__('allboards.workspaces') };
}
const sel = selectedMenuVar.get();
const currentUser = ReactiveCache.getCurrentUser();
// Helper to find space by id in tree
const findSpaceById = (nodes, targetId, path = []) => {
for (const node of nodes) {
if (node.id === targetId) {
return [...path, node];
}
if (node.children && node.children.length > 0) {
const result = findSpaceById(node.children, targetId, [
...path,
node,
]);
if (result) return result;
}
try {
const selectedMenuVar = this.selectedMenu;
if (!selectedMenuVar || typeof selectedMenuVar.get !== 'function') {
return { icon: '🗂️', text: 'Workspaces' };
}
return null;
};
const sel = selectedMenuVar.get();
const currentUser = ReactiveCache.getCurrentUser();
if (sel === 'starred') {
return { icon: '⭐', text: TAPi18n.__('allboards.starred') };
} else if (sel === 'templates') {
return { icon: '📋', text: TAPi18n.__('allboards.templates') };
} else if (sel === 'remaining') {
return { icon: '📂', text: TAPi18n.__('allboards.remaining') };
} else {
// sel is a workspaceId, build path
const tree = this.workspacesTreeVar.get();
const spacePath = findSpaceById(tree, sel);
if (spacePath && spacePath.length > 0) {
const pathText = spacePath.map((s) => s.name).join(' / ');
return {
icon: '🗂️',
text: `${TAPi18n.__('allboards.workspaces') || 'Workspaces'} / ${pathText}`,
};
// Helper function to safely get translation or fallback
const safeTranslate = (key, fallback) => {
try {
return TAPi18n.__(key) || fallback;
} catch (e) {
return fallback;
}
};
// Helper to find space by id in tree
const findSpaceById = (nodes, targetId, path = []) => {
if (!nodes || !Array.isArray(nodes)) return null;
for (const node of nodes) {
if (node.id === targetId) {
return [...path, node];
}
if (node.children && node.children.length > 0) {
const result = findSpaceById(node.children, targetId, [
...path,
node,
]);
if (result) return result;
}
}
return null;
};
if (sel === 'starred') {
return { icon: '⭐', text: safeTranslate('allboards.starred', 'Starred') };
} else if (sel === 'templates') {
return { icon: '📋', text: safeTranslate('allboards.templates', 'Templates') };
} else if (sel === 'remaining') {
return { icon: '📂', text: safeTranslate('allboards.remaining', 'Remaining') };
} else {
// sel is a workspaceId, build path
if (!this.workspacesTreeVar || typeof this.workspacesTreeVar.get !== 'function') {
return { icon: '🗂️', text: safeTranslate('allboards.workspaces', 'Workspaces') };
}
const tree = this.workspacesTreeVar.get();
const spacePath = findSpaceById(tree, sel);
if (spacePath && spacePath.length > 0) {
const pathText = spacePath.map((s) => s.name).join(' / ');
return {
icon: '🗂️',
text: `${safeTranslate('allboards.workspaces', 'Workspaces')} / ${pathText}`,
};
}
return { icon: '🗂️', text: safeTranslate('allboards.workspaces', 'Workspaces') };
}
return { icon: '🗂️', text: TAPi18n.__('allboards.workspaces') };
} catch (error) {
console.error('Error in currentMenuPath:', error);
return { icon: '🗂️', text: 'Workspaces' };
}
},
boards() {

View file

@ -3,6 +3,7 @@ template(name="miniboard")
class="minicard-{{colorClass}}")
.minicard-title
.handle
span.drag-handle(title="{{_ 'dragBoard'}}") ↕️
span.drag-handle(title="{{_ 'dragBoard'}}")
i.fa.fa-arrows
+viewer
= title