From 7ad04f45353e1628881fec310caedf7625a34d4d Mon Sep 17 00:00:00 2001 From: Lauri Ojansivu Date: Wed, 28 Jan 2026 12:59:07 +0200 Subject: [PATCH] =?UTF-8?q?Most=20Unicode=20Icons=20back=20to=20Font=20Awe?= =?UTF-8?q?some=204.7=20for=20better=20accessibility.=20Less=20always=20vi?= =?UTF-8?q?sible=20buttons,=20More=20at=20=E2=98=B0=20Men.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Thanks to xet7 ! --- .meteor/packages | 2 +- .meteor/versions | 1 + client/components/activities/comments.jade | 3 +- .../components/boardConversionProgress.jade | 8 +- client/components/boards/boardArchive.jade | 7 +- client/components/boards/boardBody.js | 6 +- client/components/boards/boardColors.css | 115 ++++++ client/components/boards/boardHeader.jade | 152 ++++---- client/components/boards/boardsList.css | 7 + client/components/boards/boardsList.jade | 68 ++-- client/components/boards/boardsList.js | 96 ++--- client/components/boards/miniboard.jade | 3 +- client/components/cards/attachments.css | 44 ++- client/components/cards/attachments.jade | 36 +- client/components/cards/cardCustomFields.jade | 10 +- client/components/cards/cardDate.jade | 101 +++--- client/components/cards/cardDate.js | 26 -- client/components/cards/cardDetails.css | 13 + client/components/cards/cardDetails.jade | 220 ++++++------ client/components/cards/checklists.css | 66 +--- client/components/cards/checklists.jade | 113 +++--- client/components/cards/checklists.js | 89 ++--- client/components/cards/labels.jade | 9 +- client/components/cards/labels.js | 30 +- client/components/cards/minicard.css | 13 +- client/components/cards/minicard.jade | 50 ++- client/components/cards/resultCard.jade | 6 +- client/components/cards/subtasks.jade | 16 +- client/components/forms/forms.css | 35 +- client/components/import/import.jade | 4 +- client/components/lists/list.css | 328 ++++++++++++------ client/components/lists/list.js | 36 +- client/components/lists/listBody.jade | 17 +- client/components/lists/listHeader.jade | 125 ++++--- client/components/lists/listHeader.js | 130 ++++++- client/components/lists/minilist.jade | 3 +- client/components/main/dueCards.jade | 19 +- client/components/main/editor.jade | 6 +- client/components/main/globalSearch.jade | 4 +- client/components/main/header.jade | 27 +- client/components/main/keyboardShortcuts.jade | 2 +- client/components/main/layouts.jade | 17 +- client/components/main/layouts.js | 121 ++++--- client/components/main/myCards.jade | 18 +- client/components/main/popup.css | 1 + client/components/main/popup.tpl.jade | 4 +- .../components/notifications/notification.css | 2 +- .../notifications/notifications.jade | 2 +- .../notifications/notificationsDrawer.jade | 32 +- .../rules/actions/boardActions.jade | 12 +- .../components/rules/actions/cardActions.jade | 15 +- .../rules/actions/checklistActions.jade | 15 +- .../components/rules/actions/mailActions.jade | 2 +- client/components/rules/ruleDetails.jade | 4 +- client/components/rules/rulesActions.jade | 11 +- client/components/rules/rulesList.jade | 12 +- client/components/rules/rulesTriggers.jade | 11 +- .../rules/triggers/boardTriggers.jade | 24 +- .../rules/triggers/cardTriggers.jade | 20 +- .../rules/triggers/checklistTriggers.jade | 24 +- client/components/settings/attachments.jade | 8 +- client/components/settings/cronSettings.jade | 56 +-- .../components/settings/informationBody.jade | 4 +- .../settings/migrationProgress.jade | 5 +- client/components/settings/peopleBody.jade | 81 +++-- client/components/settings/settingBody.jade | 60 ++-- client/components/settings/settingHeader.jade | 21 +- .../components/settings/translationBody.jade | 10 +- client/components/sidebar/sidebar.jade | 244 +++++++------ .../sidebar/sidebarCustomFields.jade | 2 +- client/components/sidebar/sidebarFilters.jade | 70 ++-- client/components/swimlanes/miniswimlane.jade | 2 +- .../components/swimlanes/swimlaneHeader.jade | 40 ++- client/components/swimlanes/swimlaneHeader.js | 3 +- client/components/swimlanes/swimlanes.css | 57 ++- client/components/swimlanes/swimlanes.jade | 16 +- client/components/users/passwordInput.jade | 8 +- client/components/users/passwordInput.js | 33 +- client/components/users/userAvatar.jade | 10 +- client/components/users/userForm.css | 8 +- client/components/users/userHeader.jade | 54 +-- client/components/users/userHeader.js | 2 +- client/config/blazeHelpers.js | 2 + client/lib/inlinedform.js | 20 ++ 84 files changed, 1828 insertions(+), 1381 deletions(-) diff --git a/.meteor/packages b/.meteor/packages index 2add42b78..e9a6af949 100644 --- a/.meteor/packages +++ b/.meteor/packages @@ -79,7 +79,7 @@ ejson@1.1.3 logging@1.3.3 wekan-fullcalendar momentjs:moment@2.29.3 -# wekan-fontawesome +wekan-fontawesome useraccounts:flow-routing-extra ostrio:flow-router-extra diff --git a/.meteor/versions b/.meteor/versions index 398894ce4..da76e4646 100644 --- a/.meteor/versions +++ b/.meteor/versions @@ -141,6 +141,7 @@ wekan-accounts-cas@0.1.0 wekan-accounts-lockout@1.0.0 wekan-accounts-oidc@1.0.10 wekan-accounts-sandstorm@0.8.0 +wekan-fontawesome@6.4.2 wekan-fullcalendar@3.10.5 wekan-ldap@0.0.2 wekan-markdown@1.0.9 diff --git a/client/components/activities/comments.jade b/client/components/activities/comments.jade index 68e477d44..1860eb4f4 100644 --- a/client/components/activities/comments.jade +++ b/client/components/activities/comments.jade @@ -25,7 +25,8 @@ template(name="comment") = text .edit-controls button.primary(type="submit") {{_ 'edit'}} - a.js-close-inlined-form(title="{{_ 'close' }}") ❌ + a.js-close-inlined-form(title="{{_ 'close' }}") + i.fa.fa-times-thin else .comment-text +viewer diff --git a/client/components/boardConversionProgress.jade b/client/components/boardConversionProgress.jade index 37a404d90..2ace5e05b 100644 --- a/client/components/boardConversionProgress.jade +++ b/client/components/boardConversionProgress.jade @@ -3,7 +3,7 @@ template(name="boardConversionProgress") .board-conversion-modal .board-conversion-header h3 - | ⚙️ + i.fa.fa-cog | {{_ 'converting-board'}} p {{_ 'converting-board-description'}} @@ -14,14 +14,14 @@ template(name="boardConversionProgress") .progress-text {{conversionProgress}}% .conversion-status - | ⚙️ + i.fa.fa-cog | {{conversionStatus}} .conversion-time(style="{{#unless conversionEstimatedTime}}display: none;{{/unless}}") - | ⏰ + i.fa.fa-clock-o | {{_ 'estimated-time-remaining'}}: {{conversionEstimatedTime}} .board-conversion-footer .conversion-info - | ℹ️ + i.fa.fa-info-circle | {{_ 'conversion-info-text'}} diff --git a/client/components/boards/boardArchive.jade b/client/components/boards/boardArchive.jade index ada3dc81a..839f183e1 100644 --- a/client/components/boards/boardArchive.jade +++ b/client/components/boards/boardArchive.jade @@ -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' }} diff --git a/client/components/boards/boardBody.js b/client/components/boards/boardBody.js index 2a88343a7..a5d6b9760 100644 --- a/client/components/boards/boardBody.js +++ b/client/components/boards/boardBody.js @@ -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 { diff --git a/client/components/boards/boardColors.css b/client/components/boards/boardColors.css index a0fb5f73c..641f85ad7 100644 --- a/client/components/boards/boardColors.css +++ b/client/components/boards/boardColors.css @@ -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; diff --git a/client/components/boards/boardHeader.jade b/client/components/boards/boardHeader.jade index a85b98741..76fd8a25a 100644 --- a/client/components/boards/boardHeader.jade +++ b/client/components/boards/boardHeader.jade @@ -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'}} diff --git a/client/components/boards/boardsList.css b/client/components/boards/boardsList.css index e0f716932..9ba4ee1c7 100644 --- a/client/components/boards/boardsList.css +++ b/client/components/boards/boardsList.css @@ -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; diff --git a/client/components/boards/boardsList.jade b/client/components/boards/boardsList.jade index 1003d183a..aea3c2d8a 100644 --- a/client/components/boards/boardsList.jade +++ b/client/components/boards/boardsList.jade @@ -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 diff --git a/client/components/boards/boardsList.js b/client/components/boards/boardsList.js index 381d37cde..fcb2461e6 100644 --- a/client/components/boards/boardsList.js +++ b/client/components/boards/boardsList.js @@ -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() { diff --git a/client/components/boards/miniboard.jade b/client/components/boards/miniboard.jade index ea40604a7..f0a1ea367 100644 --- a/client/components/boards/miniboard.jade +++ b/client/components/boards/miniboard.jade @@ -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 diff --git a/client/components/cards/attachments.css b/client/components/cards/attachments.css index 64a0c8735..97039dfe3 100644 --- a/client/components/cards/attachments.css +++ b/client/components/cards/attachments.css @@ -55,6 +55,12 @@ flex-direction: row; align-items: center; } +.attachment-actions a { + margin-left: 16px; +} +.attachment-actions a:first-child { + margin-left: 0; +} .add-attachment { display: flex; align-items: center; @@ -106,6 +112,9 @@ color: white; cursor: pointer; font-size: 4em; + position: absolute; + right: 50px; + top: 16px; } /* Upload progress indicators for drag-and-drop uploads */ @@ -241,10 +250,6 @@ .js-card-details.is-dragging-over { border: 2px dashed #007bff !important; background: rgba(0, 123, 255, 0.05) !important; -} - top: 0; - right: 8px; - position: absolute; } .attachment-arrow { font-size: 4em; @@ -253,6 +258,20 @@ align-self: center; margin: 0 20px; } +#prev-attachment { + font-size: 4em; + color: white; + cursor: pointer; + align-self: center; + margin-left: 70px; +} +#next-attachment { + font-size: 4em; + color: white; + cursor: pointer; + align-self: center; + margin-right: 70px; +} #viewer-content { display: flex; justify-content: center; @@ -266,6 +285,13 @@ max-width: 100%; max-height: 100%; } +#video-viewer { + max-width: 100%; + max-height: 100%; +} +#audio-viewer { + max-width: 100%; +} #pdf-viewer { width: 40vw; height: 100%; @@ -300,9 +326,19 @@ } #prev-attachment { left: 0; + position: absolute; + bottom: 2.2em; + font-size: 1.6em; + padding: 16px; + margin-left: 0; } #next-attachment { right: 0; + position: absolute; + bottom: 2.2em; + font-size: 1.6em; + padding: 16px; + margin-right: 0; } #pdf-viewer { width: 100%; diff --git a/client/components/cards/attachments.jade b/client/components/cards/attachments.jade index 34a9b2496..054c547d9 100644 --- a/client/components/cards/attachments.jade +++ b/client/components/cards/attachments.jade @@ -34,10 +34,11 @@ template(name="attachmentViewer") #viewer-overlay.hidden #viewer-top-bar span#attachment-name - a#viewer-close ❌ + a#viewer-close + i.fa.fa-times-thin #viewer-container - | ◀️ + i.fa.fa-caret-left#prev-attachment #viewer-content img#image-viewer.hidden video#video-viewer.hidden(controls="true") @@ -45,7 +46,7 @@ template(name="attachmentViewer") object#pdf-viewer.hidden(type="application/pdf") span.pdf-preview-error {{_ 'preview-pdf-not-supported' }} object#txt-viewer.hidden(type="text/plain") - | ▶️ + i.fa.fa-caret-right#next-attachment template(name="attachmentGallery") @@ -53,7 +54,7 @@ template(name="attachmentGallery") if canModifyCard a.attachment-item.add-attachment.js-add-attachment - | ➕ + i.fa.fa-plus each attachments @@ -87,22 +88,21 @@ template(name="attachmentGallery") span.file-size ({{fileSize size}}) .attachment-actions a.js-download(href="{{link}}?download=true", download="{{name}}", title="{{_ 'download'}}") - | ⬇️ + i.fa.fa-arrow-down if currentUser.isBoardMember unless currentUser.isCommentOnly unless currentUser.isWorker a.js-rename(title="{{_ 'rename'}}") - | ✏️ + i.fa.fa-pencil-square-o a.js-confirm-delete(title="{{_ 'delete'}}") - | 🗑️ + i.fa.fa-trash a.js-open-attachment-menu(data-attachment-link="{{link}}", title="{{_ 'attachmentActionsPopup-title'}}") - | ☰ - + i.fa.fa-bars // Migration spinner overlay if isAttachmentMigrating _id .attachment-migration-overlay .migration-spinner - | ⚙️ + i.fa.fa-cog.fa-spin .migration-text {{_ 'migrating-attachment'}} template(name="attachmentActionsPopup") @@ -110,16 +110,12 @@ template(name="attachmentActionsPopup") li if isImage a(class="{{#if isCover}}js-remove-cover{{else}}js-add-cover{{/if}}") - | 📖 - | 🖼️ - if isCover - | {{_ 'remove-cover'}} - else - | {{_ 'add-cover'}} + i.fa.fa-picture-o + | {{#if isCover}}{{_ 'remove-cover'}}{{else}}{{_ 'add-cover'}}{{/if}} if currentUser.isBoardAdmin if isImage a(class="{{#if isBackgroundImage}}js-remove-background-image{{else}}js-add-background-image{{/if}}") - | 🖼️ + i.fa.fa-picture-o if isBackgroundImage | {{_ 'remove-background-image'}} else @@ -127,19 +123,19 @@ template(name="attachmentActionsPopup") if $neq versions.original.storage "fs" a.js-move-storage-fs - | ▶️ + i.fa.fa-arrow-right | {{_ 'attachment-move-storage-fs'}} if $neq versions.original.storage "gridfs" if versions.original.storage a.js-move-storage-gridfs - | ▶️ + i.fa.fa-arrow-right | {{_ 'attachment-move-storage-gridfs'}} if $neq versions.original.storage "s3" if versions.original.storage a.js-move-storage-s3 - | ▶️ + i.fa.fa-arrow-right | {{_ 'attachment-move-storage-s3'}} template(name="attachmentRenamePopup") diff --git a/client/components/cards/cardCustomFields.jade b/client/components/cards/cardCustomFields.jade index 5534c9c77..685b5765a 100644 --- a/client/components/cards/cardCustomFields.jade +++ b/client/components/cards/cardCustomFields.jade @@ -6,10 +6,10 @@ template(name="cardCustomFieldsPopup") span.full-name = name if hasCustomField - | ✅ + i.fa.fa-check hr a.quiet-button.full.js-settings - | ⚙️ + i.fa.fa-cog span {{_ 'settings'}} template(name="cardCustomField") @@ -55,9 +55,11 @@ template(name="cardCustomField-number") template(name="cardCustomField-checkbox") .js-checklist-item.checklist-item(class="{{#if data.value }}is-checked{{/if}}") if canModifyCard - span.check-box-unicode {{#if data.value }}✅{{else}}⬜{{/if}} + span.check-box-unicode + i.fa(class="{{#if data.value}}fa-check-square{{else}}fa-square-o{{/if}}") else - span.check-box-unicode {{#if data.value }}✅{{else}}⬜{{/if}} + span.check-box-unicode + i.fa(class="{{#if data.value}}fa-check-square{{else}}fa-square-o{{/if}}") template(name="cardCustomField-currency") if canModifyCard diff --git a/client/components/cards/cardDate.jade b/client/components/cards/cardDate.jade index c8c6f45a3..e4939788b 100644 --- a/client/components/cards/cardDate.jade +++ b/client/components/cards/cardDate.jade @@ -95,58 +95,61 @@ template(name="minicardCustomFieldDate") | {{showWeek}} template(name="editCardReceivedDatePopup") - form.edit-card-received-date - .datepicker - // Date input field (existing) - // Insert calendar selector right after date input - .calendar-selector - label(for="calendar-received") 🗓️ - input#calendar-received.js-calendar-date(type="date") - // Time input field (if present) - .clear-date - a.js-clear-date {{_ 'clear'}} - .datepicker-actions - button.primary.wide.left(type="submit") {{_ 'save'}} - button.js-delete-date.negate.wide.right {{_ 'delete'}} + .datepicker-container + form.edit-date + .fields + .left + label(for="date") {{_ 'date'}} + input.js-date-field#date(type="date" name="date" value=showDate autofocus) + .right + label(for="time") {{_ 'time'}} + input.js-time-field#time(type="time" name="time" value=showTime) + if error.get + .warning {{_ error.get}} + button.primary.wide.left.js-submit-date(type="submit") {{_ 'save'}} + button.js-delete-date.negate.wide.right.js-delete-date {{_ 'delete'}} template(name="editCardStartDatePopup") - form.edit-card-start-date - .datepicker - // Date input field (existing) - .calendar-selector - label(for="calendar-start") 🗓️ - input#calendar-start.js-calendar-date(type="date") - // Time input field (if present) - .clear-date - a.js-clear-date {{_ 'clear'}} - .datepicker-actions - button.primary.wide.left(type="submit") {{_ 'save'}} - button.js-delete-date.negate.wide.right {{_ 'delete'}} + .datepicker-container + form.edit-date + .fields + .left + label(for="date") {{_ 'date'}} + input.js-date-field#date(type="date" name="date" value=showDate autofocus) + .right + label(for="time") {{_ 'time'}} + input.js-time-field#time(type="time" name="time" value=showTime) + if error.get + .warning {{_ error.get}} + button.primary.wide.left.js-submit-date(type="submit") {{_ 'save'}} + button.js-delete-date.negate.wide.right.js-delete-date {{_ 'delete'}} template(name="editCardDueDatePopup") - form.edit-card-due-date - .datepicker - // Date input field (existing) - .calendar-selector - label(for="calendar-due") 🗓️ - input#calendar-due.js-calendar-date(type="date") - // Time input field (if present) - .clear-date - a.js-clear-date {{_ 'clear'}} - .datepicker-actions - button.primary.wide.left(type="submit") {{_ 'save'}} - button.js-delete-date.negate.wide.right {{_ 'delete'}} + .datepicker-container + form.edit-date + .fields + .left + label(for="date") {{_ 'date'}} + input.js-date-field#date(type="date" name="date" value=showDate autofocus) + .right + label(for="time") {{_ 'time'}} + input.js-time-field#time(type="time" name="time" value=showTime) + if error.get + .warning {{_ error.get}} + button.primary.wide.left.js-submit-date(type="submit") {{_ 'save'}} + button.js-delete-date.negate.wide.right.js-delete-date {{_ 'delete'}} template(name="editCardEndDatePopup") - form.edit-card-end-date - .datepicker - // Date input field (existing) - .calendar-selector - label(for="calendar-end") 🗓️ - input#calendar-end.js-calendar-date(type="date") - // Time input field (if present) - .clear-date - a.js-clear-date {{_ 'clear'}} - .datepicker-actions - button.primary.wide.left(type="submit") {{_ 'save'}} - button.js-delete-date.negate.wide.right {{_ 'delete'}} + .datepicker-container + form.edit-date + .fields + .left + label(for="date") {{_ 'date'}} + input.js-date-field#date(type="date" name="date" value=showDate autofocus) + .right + label(for="time") {{_ 'time'}} + input.js-time-field#time(type="time" name="time" value=showTime) + if error.get + .warning {{_ error.get}} + button.primary.wide.left.js-submit-date(type="submit") {{_ 'save'}} + button.js-delete-date.negate.wide.right.js-delete-date {{_ 'delete'}} diff --git a/client/components/cards/cardDate.js b/client/components/cards/cardDate.js index a470bbba4..5863e8f48 100644 --- a/client/components/cards/cardDate.js +++ b/client/components/cards/cardDate.js @@ -47,22 +47,6 @@ import { this.data().getStart() && this.date.set(new Date(this.data().getStart())); } - onRendered() { - super.onRendered(); - // DatePicker base class handles initialization with native HTML inputs - const self = this; - this.$('.js-calendar-date').on('change', function(evt) { - const currentUser = ReactiveCache.getCurrentUser && ReactiveCache.getCurrentUser(); - const dateFormat = currentUser ? currentUser.getDateFormat() : 'YYYY-MM-DD'; - const value = evt.target.value; - if (value) { - // Format date according to user preference - const formatted = formatDateByUserPreference(new Date(value), dateFormat, true); - self._storeDate(new Date(value)); - } - }); - } - _storeDate(date) { this.card.setStart(formatDateTime(date)); } @@ -79,11 +63,6 @@ import { this.data().getDue() && this.date.set(new Date(this.data().getDue())); } - onRendered() { - super.onRendered(); - // DatePicker base class handles initialization with native HTML inputs - } - _storeDate(date) { this.card.setDue(formatDateTime(date)); } @@ -100,11 +79,6 @@ import { this.data().getEnd() && this.date.set(new Date(this.data().getEnd())); } - onRendered() { - super.onRendered(); - // DatePicker base class handles initialization with native HTML inputs - } - _storeDate(date) { this.card.setEnd(formatDateTime(date)); } diff --git a/client/components/cards/cardDetails.css b/client/components/cards/cardDetails.css index c387bf3aa..734da03fa 100644 --- a/client/components/cards/cardDetails.css +++ b/client/components/cards/cardDetails.css @@ -192,6 +192,8 @@ body.desktop-mode .card-details.card-details-collapsed { position: sticky; top: 0px; z-index: 500; + display: flow-root; + min-height: 40px; } .card-details .card-details-header .card-number { color: #b3b3b3; @@ -209,6 +211,8 @@ body.desktop-mode .card-details.card-details-collapsed { cursor: pointer; user-select: none; color: #000; + vertical-align: middle; + line-height: 1.2; } /* Drag handle */ @@ -220,6 +224,8 @@ body.desktop-mode .card-details.card-details-collapsed { user-select: none; display: inline-block; float: right; + vertical-align: middle; + line-height: 1.2; } .card-details .card-details-header .close-card-details, @@ -241,6 +247,8 @@ body.desktop-mode .card-details.card-details-collapsed { margin-right: -8px; cursor: pointer; user-select: none; + vertical-align: middle; + line-height: 1.2; } .card-details .card-details-header .close-card-details-mobile-web, .card-details .card-details-header .card-mobile-desktop-toggle { @@ -263,6 +271,8 @@ body.desktop-mode .card-details.card-details-collapsed { .card-details .card-details-header .card-details-menu { font-size: 17px; padding: 10px; + vertical-align: middle; + line-height: 1.2; } .card-details .card-details-header .card-details-menu-mobile-web { font-size: 17px; @@ -309,6 +319,9 @@ body.desktop-mode .card-details.card-details-collapsed { font-size: 1.33em; margin: 7px 0 0; padding: 0; + display: inline-block; + vertical-align: middle; + line-height: 1.3; } .card-details .card-details-header .linked-card-location { font-style: italic; diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 8f0043cb9..0fc865435 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -14,55 +14,53 @@ template(name="cardDetails") unless isPopup span.card-collapse-toggle.js-card-collapse-toggle(title="{{_ 'collapse-card'}}") if cardCollapsed - | ▶ + i.fa.fa-caret-right else - | 🔽 + i.fa.fa-caret-down a.close-card-details.js-close-card-details(title="{{_ 'close-card'}}") - | ❌ + i.fa.fa-times-thin if cardMaximized - a.minimize-card-details.js-minimize-card-details(title="{{_ 'minimize-card'}}") - | 🔽 + a.fa.fa-window-minimize.minimize-card-details.js-minimize-card-details(title="{{_ 'minimize-card'}}") else - a.maximize-card-details.js-maximize-card-details(title="{{_ 'maximize-card'}}") - | 🔼 + a.fa.fa-window-maximize.maximize-card-details.js-maximize-card-details(title="{{_ 'maximize-card'}}") a.card-details-menu.js-open-card-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}") - | ☰ + i.fa.fa-bars a.card-copy-button.js-copy-link( id="cardURL_copy" title="{{_ 'copy-card-link-to-clipboard'}}" href="{{ originRelativeUrl }}" ) - span.emoji-icon 🔗 + span.emoji-icon + i.fa.fa-link if canModifyCard span.card-drag-handle.js-card-drag-handle(title="Drag card") - | ↕️ + i.fa.fa-arrows span.copied-tooltip {{_ 'copied'}} else a.close-card-details.js-close-card-details(title="{{_ 'close-card'}}") - | ❌ + i.fa.fa-times-thin a.card-zoom-out.js-card-zoom-out(title="{{_ 'zoom-out'}}") - | 🔍➖ + i.fa.fa-search-minus a.card-zoom-in.js-card-zoom-in(title="{{_ 'zoom-in'}}") - | 🔍➕ + i.fa.fa-search-plus a.card-mobile-desktop-toggle.js-card-mobile-desktop-toggle(title="{{_ 'mobile-desktop-toggle'}}") if mobileMode - | 🖥️ + i.fa.fa-desktop else - | 📱 + i.fa.fa-mobile if cardMaximized - a.minimize-card-details.js-minimize-card-details(title="{{_ 'minimize-card'}}") - | 🔽 + a.fa.fa-window-minimize.minimize-card-details.js-minimize-card-details(title="{{_ 'minimize-card'}}") else - a.maximize-card-details.js-maximize-card-details(title="{{_ 'maximize-card'}}") - | 🔼 + a.fa.fa-window-maximize.maximize-card-details.js-maximize-card-details(title="{{_ 'maximize-card'}}") a.card-details-menu-mobile-web.js-open-card-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}") - | ☰ + i.fa.fa-bars a.card-copy-mobile-button.js-copy-link( id="cardURL_copy" title="{{_ 'copy-card-link-to-clipboard'}}" href="{{ originRelativeUrl }}" ) - span.emoji-icon 🔗 + span.emoji-icon + i.fa.fa-link span.copied-tooltip {{_ 'copied'}} h2.card-details-title.js-card-title( class="{{#if canModifyCard}}js-open-inlined-form is-editable{{else}}js-card-title-drag-handle{{/if}}") @@ -73,7 +71,7 @@ template(name="cardDetails") = getTitle if isWatching i.card-details-watch - | 👁️ + i.fa.fa-eye .card-details-path each parentList |   >   @@ -95,7 +93,7 @@ template(name="cardDetails") if hasActiveUploads .card-details-upload-progress .upload-progress-header - | 📤 + i.fa.fa-upload span {{_ 'uploading-files'}} ({{uploadCount}}) each uploads .upload-progress-item(class="{{#if $eq status 'error'}}upload-error{{/if}}") @@ -104,11 +102,11 @@ template(name="cardDetails") .upload-progress-fill(style="width: {{progress}}%") if $eq status 'error' .upload-progress-error - | ⚠️ + i.fa.fa-exclamation-triangle span {{_ 'upload-failed'}} else if $eq status 'completed' .upload-progress-success - | ✅ + i.fa.fa-check span {{_ 'upload-completed'}} .card-details-left @@ -117,7 +115,7 @@ template(name="cardDetails") if currentBoard.allowsLabels .card-details-item.card-details-item-labels h3.card-details-item-title - | 🏷️ + i.fa.fa-tags | {{_ 'labels'}} a(class="{{#if canModifyCard}}js-add-labels{{else}}is-disabled{{/if}}" title="{{_ 'card-labels-title'}}") each labels @@ -127,14 +125,14 @@ template(name="cardDetails") if canModifyCard unless currentUser.isWorker a.card-label.add-label.js-add-labels(title="{{_ 'card-labels-title'}}") - | ➕ + i.fa.fa-plus if currentBoard.hasAnyAllowsDate hr .card-details-item.card-details-item-date-format h3.card-details-item-title - | 📅 + i.fa.fa-calendar | {{_ 'date-format'}} .card-details-item-content select.js-date-format-selector @@ -145,7 +143,7 @@ template(name="cardDetails") if currentBoard.allowsReceivedDate .card-details-item.card-details-item-received h3.card-details-item-title - | 📥 + i.fa.fa-sign-out | {{_ 'card-received'}} if getReceived +cardReceivedDate @@ -153,12 +151,12 @@ template(name="cardDetails") if canModifyCard unless currentUser.isWorker a.card-label.add-label.js-received-date - | ➕ + i.fa.fa-plus if currentBoard.allowsStartDate .card-details-item.card-details-item-start h3.card-details-item-title - | 🚀 + i.fa.fa-hourglass-start | {{_ 'card-start'}} if getStart +cardStartDate @@ -166,12 +164,12 @@ template(name="cardDetails") if canModifyCard unless currentUser.isWorker a.card-label.add-label.js-start-date - | ➕ + i.fa.fa-plus if currentBoard.allowsDueDate .card-details-item.card-details-item-due h3.card-details-item-title - | ⏰ + i.fa.fa-clock-o | {{_ 'card-due'}} if getDue +cardDueDate @@ -179,12 +177,12 @@ template(name="cardDetails") if canModifyCard unless currentUser.isWorker a.card-label.add-label.js-due-date - | ➕ + i.fa.fa-plus if currentBoard.allowsEndDate .card-details-item.card-details-item-end h3.card-details-item-title - | 🏁 + i.fa.fa-hourglass-end | {{_ 'card-end'}} if getEnd +cardEndDate @@ -192,7 +190,7 @@ template(name="cardDetails") if canModifyCard unless currentUser.isWorker a.card-label.add-label.js-end-date - | ➕ + i.fa.fa-plus if currentBoard.hasAnyAllowsUser hr @@ -200,7 +198,7 @@ template(name="cardDetails") if currentBoard.allowsCreator .card-details-item.card-details-item-creator h3.card-details-item-title - | 👤 + i.fa.fa-user | {{_ 'creator'}} +userAvatar(userId=userId noRemove=true) @@ -210,7 +208,7 @@ template(name="cardDetails") if currentBoard.allowsMembers .card-details-item.card-details-item-members h3.card-details-item-title - | 👥 + i.fa.fa-users | {{_ 'members'}} each userId in getMembers +userAvatar(userId=userId cardId=_id) @@ -218,30 +216,30 @@ template(name="cardDetails") if canModifyCard unless currentUser.isWorker a.member.add-member.card-details-item-add-button.js-add-members(title="{{_ 'card-members-title'}}") - | ➕ + i.fa.fa-plus //if assigneeSelected if currentBoard.allowsAssignee .card-details-item.card-details-item-assignees h3.card-details-item-title - | 👤 + i.fa.fa-user | {{_ 'assignee'}} each userId in getAssignees +userAvatar(userId=userId cardId=_id assignee=true) | {{! XXX Hack to hide syntaxic coloration /// }} if canModifyCard a.assignee.add-assignee.card-details-item-add-button.js-add-assignees(title="{{_ 'assignee'}}") - | ➕ + i.fa.fa-plus if currentUser.isWorker unless assigneeSelected a.assignee.add-assignee.card-details-item-add-button.js-add-assignees(title="{{_ 'assignee'}}") - | ➕ + i.fa.fa-plus //.card-details-items if currentBoard.allowsRequestedBy .card-details-item.card-details-item-name h3.card-details-item-title - | 🛒 + i.fa.fa-shopping-cart | {{_ 'requested-by'}} if canModifyCard unless currentUser.isWorker @@ -261,7 +259,7 @@ template(name="cardDetails") if currentBoard.allowsAssignedBy .card-details-item.card-details-item-name h3.card-details-item-title - | ✍️ + i.fa.fa-user-plus | {{_ 'assigned-by'}} if canModifyCard unless currentUser.isWorker @@ -284,7 +282,7 @@ template(name="cardDetails") if currentBoard.allowsCardSortingByNumber .card-details-item.card-details-sort-order h3.card-details-item-title - | 🔢 + i.fa.fa-sort-numeric-asc | {{_ 'sort'}} if canModifyCard +inlinedForm(classNames="js-card-details-sort") @@ -297,7 +295,7 @@ template(name="cardDetails") if currentBoard.allowsShowLists .card-details-item.card-details-show-lists h3.card-details-item-title - | 📋 + i.fa.fa-list | {{_ 'list'}} select.js-select-card-details-lists(disabled="{{#unless canModifyCard}}disabled{{/unless}}") each currentBoard.lists @@ -323,7 +321,7 @@ template(name="cardDetails") hr .card-details-item.card-details-item-customfield h3.card-details-item-title - | 📋 + i.fa.fa-list = definition.name +cardCustomField @@ -341,7 +339,7 @@ template(name="cardDetails") .vote-title div.flex h3 - | 👍 + i.fa.fa-thumbs-up | {{_ 'vote-question'}} if getVoteEnd +voteEndDate @@ -359,7 +357,7 @@ template(name="cardDetails") if showVotingButtons button.card-details-green.js-vote.js-vote-positive(class="{{#if voteState}}voted{{/if}}") if voteState - | 👍 + i.fa.fa-thumbs-up | {{_ 'vote-for-it'}} button.card-details-red.js-vote.js-vote-negative(class="{{#if $eq voteState false}}voted{{/if}}") if $eq voteState false @@ -371,7 +369,7 @@ template(name="cardDetails") .poker-title div.flex h3 - | 👍 + i.fa.fa-thumbs-up | {{_ 'poker-question'}} if getPokerEnd +pokerEndDate @@ -386,52 +384,52 @@ template(name="cardDetails") .poker-card span.inner.js-poker.js-poker-vote-one(class="{{#if $eq pokerState 'one'}}poker-voted{{/if}}") {{_ 'poker-one'}} if $eq pokerState "one" - | ✅ + i.fa.fa-check .poker-deck .poker-card span.inner.js-poker.js-poker-vote-two(class="{{#if $eq pokerState 'two'}}poker-voted{{/if}}") {{_ 'poker-two'}} if $eq pokerState "two" - | ✅ + i.fa.fa-check .poker-deck .poker-card span.inner.js-poker.js-poker-vote-three(class="{{#if $eq pokerState 'three'}}poker-voted{{/if}}") {{_ 'poker-three'}} if $eq pokerState "three" - | ✅ + i.fa.fa-check .poker-deck .poker-card span.inner.js-poker.js-poker-vote-five(class="{{#if $eq pokerState 'five'}}poker-voted{{/if}}") {{_ 'poker-five'}} if $eq pokerState "five" - | ✅ + i.fa.fa-check .poker-deck .poker-card span.inner.js-poker.js-poker-vote-eight(class="{{#if $eq pokerState 'eight'}}poker-voted{{/if}}") {{_ 'poker-eight'}} if $eq pokerState "eight" - | ✅ + i.fa.fa-check .poker-deck .poker-card span.inner.js-poker.js-poker-vote-thirteen(class="{{#if $eq pokerState 'thirteen'}}poker-voted{{/if}}") {{_ 'poker-thirteen'}} if $eq pokerState "thirteen" - | ✅ + i.fa.fa-check .poker-deck .poker-card span.inner.js-poker.js-poker-vote-twenty(class="{{#if $eq pokerState 'twenty'}}poker-voted{{/if}}") {{_ 'poker-twenty'}} if $eq pokerState "twenty" - | ✅ + i.fa.fa-check .poker-deck .poker-card span.inner.js-poker.js-poker-vote-forty(class="{{#if $eq pokerState 'forty'}}poker-voted{{/if}}") {{_ 'poker-forty'}} if $eq pokerState "forty" - | ✅ + i.fa.fa-check .poker-deck .poker-card span.inner.js-poker.js-poker-vote-one-hundred(class="{{#if $eq pokerState 'oneHundred'}}poker-voted{{/if}}") {{_ 'poker-oneHundred'}} if $eq pokerState "oneHundred" - | ✅ + i.fa.fa-check .poker-deck .poker-card span.inner.js-poker.js-poker-vote-unsure(class="{{#if $eq pokerState 'unsure'}}poker-voted{{/if}}") {{_ 'poker-unsure'}} if $eq pokerState "unsure" - | ✅ + i.fa.fa-check if currentUser.isBoardAdmin button.card-details-blue.js-poker-finish(class="{{#if $eq voteState false}}poker-voted{{/if}}") {{_ 'poker-finish'}} @@ -561,7 +559,7 @@ template(name="cardDetails") button.card-details-red.js-poker-replay(class="{{#if $eq voteState false}}voted{{/if}}") {{_ 'poker-replay'}} div.estimation-add button.js-poker-estimation - | ➕ + i.fa.fa-plus | {{_ 'set-estimation'}} input(type=text,autofocus value=getPokerEstimation,id="pokerEstimation") @@ -571,7 +569,7 @@ template(name="cardDetails") if currentBoard.allowsDescriptionTitle hr h3.card-details-item-title - | 📝 + i.fa.fa-file-text-o | {{_ 'description'}} if currentBoard.allowsDescriptionText +inlinedCardDescription(classNames="card-description js-card-description") @@ -582,7 +580,7 @@ template(name="cardDetails") else if currentBoard.allowsDescriptionText a.js-open-inlined-form(title="{{_ 'edit'}}" value=title) - | ✏️ + i.fa.fa-pencil-square-o a.js-open-inlined-form(title="{{_ 'edit'}}" value=title) if getDescription +viewer @@ -612,7 +610,7 @@ template(name="cardDetails") if currentBoard.allowsAttachments hr h3.card-details-item-title - | 📎 + i.fa.fa-paperclip | {{_ 'attachments'}} if Meteor.settings.public.attachmentsUploadMaxSize | {{_ 'max-upload-filesize'}} {{Meteor.settings.public.attachmentsUploadMaxSize}} @@ -628,7 +626,7 @@ template(name="cardDetails") unless currentUser.isNoComments .comment-title h3.card-details-item-title - | 💬 + i.fa.fa-comment-o | {{_ 'comments'}} if currentBoard.allowsComments @@ -645,7 +643,7 @@ template(name="cardDetails") if currentUser.isBoardAdmin .activity-title h3.card-details-item-title - | 📜 + i.fa.fa-history | {{ _ 'activities'}} if currentUser.isBoardMember .material-toggle-switch(title="{{_ 'show-activities'}}") @@ -696,10 +694,10 @@ template(name="cardDetailsActionsPopup") li a.js-toggle-watch-card if isWatching - | 👁️ + i.fa.fa-eye | {{_ 'unwatch'}} else - | 👁️ + i.fa.fa-eye | {{_ 'watch'}} hr if canModifyCard @@ -710,16 +708,16 @@ template(name="cardDetailsActionsPopup") //li: a.js-attachments {{_ 'card-edit-attachments'}} li a.js-start-voting - | 👍 + i.fa.fa-thumbs-up | {{_ 'card-edit-voting'}} li a.js-start-planning-poker - | 👍 + i.fa.fa-thumbs-up | {{_ 'card-edit-planning-poker'}} if currentUser.isBoardAdmin li a.js-custom-fields - | 📋 + i.fa.fa-list | {{_ 'card-edit-custom-fields'}} //li: a.js-received-date {{_ 'editCardReceivedDatePopup-title'}} //li: a.js-start-date {{_ 'editCardStartDatePopup-title'}} @@ -727,19 +725,19 @@ template(name="cardDetailsActionsPopup") //li: a.js-end-date {{_ 'editCardEndDatePopup-title'}} li a.js-spent-time - | 🕐 + i.fa.fa-clock-o | {{_ 'editCardSpentTimePopup-title'}} li a.js-set-card-color - | 🎨 + i.fa.fa-paint-brush | {{_ 'setCardColorPopup-title'}} li a.js-toggle-show-list-on-minicard if showListOnMinicard - | 👁️ + i.fa.fa-eye | {{_ 'hide-list-on-minicard'}} else - | 👁️ + i.fa.fa-eye | {{_ 'show-list-on-minicard'}} if canModifyCard hr @@ -750,7 +748,7 @@ template(name="cardDetailsActionsPopup") ul.pop-over-list li a.js-export-card - | 📤 + i.fa.fa-upload | {{_ 'export-card'}} unless canModifyCard unless currentUser.isReadOnly @@ -759,95 +757,93 @@ template(name="cardDetailsActionsPopup") ul.pop-over-list li a.js-move-card-to-top - | ⬆️ + i.fa.fa-arrow-up | {{_ 'moveCardToTop-title'}} li a.js-move-card-to-bottom - | ⬇️ + i.fa.fa-arrow-down | {{_ 'moveCardToBottom-title'}} hr ul.pop-over-list if currentUser.isBoardAdmin li a.js-move-card - | ➡️ + i.fa.fa-arrow-right | {{_ 'moveCardPopup-title'}} unless currentUser.isWorker li a.js-copy-card - | 📋 + i.fa.fa-clipboard | {{_ 'copyCardPopup-title'}} unless currentUser.isWorker ul.pop-over-list li a.js-copy-checklist-cards - | 📋 - | 📋 + i.fa.fa-copy | {{_ 'copyManyCardsPopup-title'}} unless archived hr ul.pop-over-list li a.js-archive - | ➡️ - | 📦 + i.fa.fa-archive | {{_ 'archive-card'}} hr ul.pop-over-list li a.js-more - span.emoji-icon 🔗 + span.emoji-icon + i.fa.fa-link | {{_ 'cardMorePopup-title'}} if canModifyCard hr ul.pop-over-list li a.js-move-card-to-top - | ⬆️ + i.fa.fa-arrow-up | {{_ 'moveCardToTop-title'}} li a.js-move-card-to-bottom - | ⬇️ + i.fa.fa-arrow-down | {{_ 'moveCardToBottom-title'}} hr ul.pop-over-list if currentUser.isBoardAdmin li a.js-move-card - | ➡️ + i.fa.fa-arrow-right | {{_ 'moveCardPopup-title'}} unless currentUser.isWorker li a.js-copy-card - | 📋 + i.fa.fa-clipboard | {{_ 'copyCardPopup-title'}} unless currentUser.isWorker ul.pop-over-list li a.js-copy-checklist-cards - | 📋 - | 📋 + i.fa.fa-copy | {{_ 'copyManyCardsPopup-title'}} unless archived hr ul.pop-over-list li a.js-archive - | ➡️ - | 📦 + i.fa.fa-archive | {{_ 'archive-card'}} hr ul.pop-over-list li a.js-more - span.emoji-icon 🔗 + span.emoji-icon + i.fa.fa-link | {{_ 'cardMorePopup-title'}} template(name="exportCardPopup") ul.pop-over-list li a(href="{{exportUrlCardPDF}}",, download="{{exportFilenameCardPDF}}") - | 📤 + i.fa.fa-upload | {{_ 'export-card-pdf'}} template(name="moveCardPopup") @@ -915,8 +911,7 @@ template(name="cardMembersPopup") if userData.username | (#{userData.username}) if isCardMember - | ✅ - + i.fa.fa-check template(name="cardAssigneesPopup") input.card-assignees-filter(type="text" placeholder="{{_ 'search'}}") unless currentUser.isWorker @@ -930,8 +925,7 @@ template(name="cardAssigneesPopup") if userData.username | (#{userData.username}) if isCardAssignee - | ✅ - if currentUser.isWorker + i.fa.fa-check if currentUser.isWorker ul.pop-over-list.js-card-assignee-list li.item(class="{{#if currentUser.isCardAssignee}}active{{/if}}") a.name.js-select-assignee(href="#") @@ -941,8 +935,7 @@ template(name="cardAssigneesPopup") if currentUser.username | (#{currentUser.username}) if currentUser.isCardAssignee - | ✅ - + i.fa.fa-check template(name="cardAssigneePopup") .board-assignee-menu .mini-profile-info @@ -965,7 +958,7 @@ template(name="cardMorePopup") span.clearfix span {{_ 'link-card'}} = ' ' - | {{#if board.isPublic}}🌐{{else}}🔒{{/if}} + i.fa(class="{{#if currentBoard.isPublic}}fa-globe{{else}}fa-lock{{/if}}") input.inline-input(type="text" id="cardURL" readonly value="{{ originRelativeUrl }}" autofocus="autofocus") button.js-copy-card-link-to-clipboard(class="btn" id="clipboard") {{_ 'copy-card-link-to-clipboard'}} .copied-tooltip {{_ 'copied'}} @@ -1003,13 +996,14 @@ template(name="cardMorePopup") template(name="setCardColorPopup") form.edit-label - .palette-colors: each colors - unless $eq color 'white' - span.card-label.palette-color.js-palette-color(class="card-details-{{color}}") - if(isSelected color) - | ✅ - button.primary.confirm.js-submit {{_ 'save'}} - button.js-remove-color.negate.wide.right {{_ 'unset-color'}} + .palette-colors + each colors + unless $eq color 'white' + span.card-label.palette-color.js-palette-color(class="card-details-{{color}}") + if(isSelected color) + i.fa.fa-check + button.primary.confirm.js-submit {{_ 'save'}} + button.js-remove-color.negate.wide.right {{_ 'unset-color'}} template(name="cardDeletePopup") p {{_ "card-delete-pop"}} @@ -1041,12 +1035,12 @@ template(name="cardStartVotingPopup") .materialCheckBox#vote-public(name="vote-public" class="{{#if votePublic}}is-checked{{/if}}") span {{_ 'vote-public'}} .check-div.flex - | ⏰ + i.fa.fa-clock-o a.js-end-date span | {{_ 'card-end'}} unless getVoteEnd - | ➕ + i.fa.fa-plus if getVoteEnd +voteEndDate @@ -1087,12 +1081,12 @@ template(name="cardStartPlanningPokerPopup") .materialCheckBox#poker-allow-non-members(name="poker-allow-non-members" class="{{#if pokerAllowNonBoardMembers}}is-checked{{/if}}") span {{_ 'allowNonBoardMembers'}} .check-div.flex - | ⏰ + i.fa.fa-clock-o a.js-end-date span | {{_ 'card-end'}} unless getPokerEnd - | ➕ + i.fa.fa-plus if getPokerEnd +pokerEndDate diff --git a/client/components/cards/checklists.css b/client/components/cards/checklists.css index 78cba4610..073e7ec79 100644 --- a/client/components/cards/checklists.css +++ b/client/components/cards/checklists.css @@ -37,23 +37,16 @@ textarea.js-edit-checklist-item { .checklist-progress-bar-container .checklist-progress-bar { width: 80%; height: 10px; - background-color: #d6ebff !important; + background-color: #e0e0e0; border-radius: 16px; } .checklist-progress-bar-container .checklist-progress-bar .checklist-progress { - color: #fff !important; - background-color: #3cb500 !important; + color: #fff; + background-color: #666; padding: 0.01em 16px; border-radius: 16px; height: 100%; } -/* Grey progress bar when grey icons setting is enabled */ -body.grey-icons-enabled .checklist-progress-bar-container .checklist-progress-bar { - background-color: #d9d9d9; -} -body.grey-icons-enabled .checklist-progress-bar-container .checklist-progress-bar .checklist-progress { - background-color: #7a7a7a !important; -} .checklist-title { padding: 10px; } @@ -76,14 +69,10 @@ body.grey-icons-enabled .checklist-progress-bar-container .checklist-progress-ba .checklist-title .checklist-stat.is-finished { color: #3cb500; } -.checklist-title span.checklist-handle { +.checklist-title span.fa.checklist-handle { padding-right: 20px; padding-top: 3px; float: left; - display: inline-block; - width: 1.2em; - text-align: center; - color: #999; } #card-details-overlay { top: 0; @@ -114,25 +103,6 @@ body.grey-icons-enabled .checklist-progress-bar-container .checklist-progress-ba height: auto; overflow: hidden; } - -/* iPhone mobile: larger checklist titles and more spacing between items */ -body.mobile-mode.iphone-device .checklist-title .title { - font-size: 1.3em !important; - font-weight: bold; -} - -body.mobile-mode.iphone-device .checklist-item { - margin-top: 12px !important; - margin-bottom: 8px !important; - padding: 8px 4px !important; - min-height: 44px; /* iOS recommended touch target size */ -} - -body.mobile-mode.iphone-device .checklist-item span.checklistitem-handle { - font-size: 1.5em !important; - padding-right: 15px !important; - width: 1.5em !important; -} .checklist-item.is-checked.invisible { opacity: 0; height: 0; @@ -162,27 +132,6 @@ body.mobile-mode.iphone-device .checklist-item span.checklistitem-handle { border-bottom: 2px solid #3cb500; border-right: 2px solid #3cb500; } -/* Unicode checkbox icons styling */ -.checklist-item .check-box-unicode, -.cardCustomField-checkbox .check-box-unicode { - font-size: 1.3em; - margin-right: 8px; - cursor: pointer; - display: inline-block; - vertical-align: middle; - line-height: 1; -} -/* Grey checkmarks when grey icons setting is enabled */ -body.grey-icons-enabled .checklist-item .check-box.is-checked { - border-bottom: 2px solid #7a7a7a; - border-right: 2px solid #7a7a7a; -} -body.grey-icons-enabled .checklist-item .check-box-unicode, -body.grey-icons-enabled .cardCustomField-checkbox .check-box-unicode { - filter: grayscale(100%); - -webkit-filter: grayscale(100%); - opacity: 0.85; -} .checklist-item .item-title { flex: 1; } @@ -197,14 +146,9 @@ body.grey-icons-enabled .cardCustomField-checkbox .check-box-unicode { word-wrap: break-word; max-width: 420px; } -.checklist-item span.checklistitem-handle { +.checklist-item span.fa.checklistitem-handle { padding-top: 2px; padding-right: 10px; - display: inline-block; - width: 1.2em; - text-align: center; - color: #999; - cursor: pointer; } .js-delete-checklist-item, .js-convert-checklist-item-to-card { diff --git a/client/components/cards/checklists.jade b/client/components/cards/checklists.jade index eac285d4d..e943e338f 100644 --- a/client/components/cards/checklists.jade +++ b/client/components/cards/checklists.jade @@ -1,25 +1,34 @@ template(name="checklists") .checklists-title h3.card-details-item-title - | ✅ + i.fa.fa-check | {{_ 'checklists'}} if canModifyCard +inlinedForm(autoclose=false classNames="js-add-checklist" cardId = cardId position="top") +addChecklistItemForm else a.add-checklist-top.js-open-inlined-form(title="{{_ 'add-checklist'}}") - | ➕ + i.fa.fa-plus + if currentUser.isBoardMember + .material-toggle-switch(title="{{_ 'hide-finished-checklist'}}") + //span.toggle-switch-title + if card.hideFinishedChecklistIfItemsAreHidden + input.toggle-switch(type="checkbox" id="toggleHideFinishedChecklist" checked="checked") + else + input.toggle-switch(type="checkbox" id="toggleHideFinishedChecklist") + label.toggle-label(for="toggleHideFinishedChecklist") .card-checklist-items each checklist in checklists - +checklistDetail(checklist = checklist card = card) + if checklist.showChecklist card.hideFinishedChecklistIfItemsAreHidden + +checklistDetail(checklist = checklist card = card) if canModifyCard +inlinedForm(autoclose=false classNames="js-add-checklist" cardId = cardId) +addChecklistItemForm(checklist=checklist showNewlineBecomesNewChecklistItem=false) else a.add-checklist.js-open-inlined-form(title="{{_ 'add-checklist'}}") - | ➕ + i.fa.fa-plus template(name="checklistDetail") .js-checklist.checklist.nodragscroll @@ -29,12 +38,12 @@ template(name="checklistDetail") .checklist-title span if canModifyCard - a.checklist-details-menu.js-open-checklist-details-menu(title="{{_ 'checklistActionsPopup-title'}}") ☰ + a.fa.fa-navicon.checklist-details-menu.js-open-checklist-details-menu(title="{{_ 'checklistActionsPopup-title'}}") if canModifyCard h4.title.js-open-inlined-form.is-editable if isTouchScreenOrShowDesktopDragHandles - span.checklist-handle(title="{{_ 'dragChecklist'}}") ↕️ + span.fa.checklist-handle(class="fa-arrows" title="{{_ 'dragChecklist'}}") +viewer = checklist.title else @@ -53,18 +62,13 @@ template(name="checklistDeletePopup") p {{_ 'confirm-checklist-delete-popup'}} button.js-confirm.negate.full(type="submit") {{_ 'delete'}} -template(name="checklistItemDeletePopup") - p {{_ 'confirm-checklist-delete-popup'}} - button.js-confirm.negate.full(type="submit") {{_ 'delete'}} - template(name="addChecklistItemForm") - a(title="{{_ 'copy-text-to-clipboard'}}") + a.fa.fa-copy(title="{{_ 'copy-text-to-clipboard'}}") span.copied-tooltip {{_ 'copied'}} textarea.js-add-checklist-item(rows='1' autofocus) .edit-controls.clearfix button.primary.confirm.js-submit-add-checklist-item-form(type="submit") {{_ 'save'}} - a.js-close-inlined-form(title="{{_ 'close-add-checklist-item'}}") - | ❌ + a.fa.fa-times-thin.js-close-inlined-form(title="{{_ 'close-add-checklist-item'}}") if showNewlineBecomesNewChecklistItem .material-toggle-switch(title="{{_ 'newlineBecomesNewChecklistItem'}}") input.toggle-switch(type="checkbox" id="toggleNewlineBecomesNewChecklistItem") @@ -77,7 +81,7 @@ template(name="addChecklistItemForm") | {{_ 'originOrder'}} template(name="editChecklistItemForm") - a(title="{{_ 'copy-text-to-clipboard'}}") + a.fa.fa-copy(title="{{_ 'copy-text-to-clipboard'}}") span.copied-tooltip {{_ 'copied'}} textarea.js-edit-checklist-item(rows='1' autofocus dir="auto") if $eq type 'item' @@ -86,17 +90,13 @@ template(name="editChecklistItemForm") = checklist.title .edit-controls.clearfix button.primary.confirm.js-submit-edit-checklist-item-form(type="submit") {{_ 'save'}} - a.js-close-inlined-form(title="{{_ 'close-edit-checklist-item'}}") - | ❌ + a.fa.fa-times-thin.js-close-inlined-form(title="{{_ 'close-edit-checklist-item'}}") span(title=createdAt) {{ moment createdAt }} if canModifyCard - if $eq type 'item' - a.js-delete-checklist-item {{_ "delete"}}... - a.js-convert-checklist-item-to-card - | 📋 - | {{_ 'convertChecklistItemToCardPopup-title'}} - else - a.js-delete-checklist {{_ "delete"}}... + a.js-delete-checklist-item {{_ "delete"}}... + a.js-convert-checklist-item-to-card + i.fa.fa-copy + | {{_ 'convertChecklistItemToCardPopup-title'}} template(name="checklistItems") if checklist.items.length @@ -105,7 +105,7 @@ template(name="checklistItems") +addChecklistItemForm(checklist=checklist showNewlineBecomesNewChecklistItem=true position="top") else a.add-checklist-item.js-open-inlined-form(title="{{_ 'add-checklist-item'}}") - | ➕ + i.fa.fa-plus .checklist-items.js-checklist-items each item in checklist.items +inlinedForm(classNames="js-edit-checklist-item" item = item checklist = checklist) @@ -117,20 +117,21 @@ template(name="checklistItems") +addChecklistItemForm(checklist=checklist showNewlineBecomesNewChecklistItem=true) else a.add-checklist-item.js-open-inlined-form(title="{{_ 'add-checklist-item'}}") - | ➕ + i.fa.fa-plus template(name='checklistItemDetail') .js-checklist-item.checklist-item(class="{{#if item.isFinished }}is-checked{{#if checklist.hideCheckedChecklistItems}} invisible{{/if}}{{/if}}{{#if checklist.hideAllChecklistItems}} is-checked invisible{{/if}}" role="checkbox" aria-checked="{{#if item.isFinished }}true{{else}}false{{/if}}" tabindex="0") if canModifyCard - span.check-box-unicode {{#if item.isFinished }}✅{{else}}⬜{{/if}} + .check-box-container + .check-box.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}") if isTouchScreenOrShowDesktopDragHandles - span.checklistitem-handle(title="{{_ 'dragChecklistItem'}}") ↕️ + span.fa.checklistitem-handle(class="fa-arrows" title="{{_ 'dragChecklistItem'}}") .item-title.js-open-inlined-form.is-editable(class="{{#if item.isFinished }}is-checked{{/if}}") +viewer = item.title else - span.check-box-unicode {{#if item.isFinished }}✅{{else}}⬜{{/if}} + .materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}") .item-title(class="{{#if item.isFinished }}is-checked{{/if}}") +viewer = item.title @@ -139,16 +140,16 @@ template(name="checklistActionsPopup") ul.pop-over-list li a.js-delete-checklist.delete-checklist - | 🗑️ + i.fa.fa-trash | {{_ "delete"}} ... a.js-move-checklist.move-checklist - | ➡️ + i.fa.fa-arrow-right | {{_ "moveChecklist"}} ... a.js-copy-checklist.copy-checklist - | 📋 + i.fa.fa-copy | {{_ "copyChecklist"}} ... a.js-hide-checked-checklist-items - | 🙈 + i.fa.fa-eye-slash | {{_ "hideCheckedChecklistItems"}} ... .material-toggle-switch(title="{{_ 'hide-checked-items'}}") if checklist.hideCheckedChecklistItems @@ -157,7 +158,7 @@ template(name="checklistActionsPopup") input.toggle-switch(type="checkbox" id="toggleHideCheckedChecklistItems_{{checklist._id}}") label.toggle-label(for="toggleHideCheckedChecklistItems_{{checklist._id}}") a.js-hide-all-checklist-items - | 🚫 + i.fa.fa-ban | {{_ "hideAllChecklistItems"}} ... .material-toggle-switch(title="{{_ 'hideAllChecklistItems'}}") if checklist.hideAllChecklistItems @@ -165,62 +166,34 @@ template(name="checklistActionsPopup") else input.toggle-switch(type="checkbox" id="toggleHideAllChecklistItems_{{checklist._id}}") label.toggle-label(for="toggleHideAllChecklistItems_{{checklist._id}}") - a.js-toggle-show-checklist-at-minicard - | 📋 - | {{_ "showChecklistAtMinicard"}} ... - .material-toggle-switch(title="{{_ 'showChecklistAtMinicard'}}") - if checklist.showChecklistAtMinicard - input.toggle-switch(type="checkbox" id="toggleShowChecklistAtMinicard_{{checklist._id}}" checked="checked") - else - input.toggle-switch(type="checkbox" id="toggleShowChecklistAtMinicard_{{checklist._id}}") - label.toggle-label(for="toggleShowChecklistAtMinicard_{{checklist._id}}") template(name="copyChecklistPopup") - unless currentUser.isWorker - label {{_ 'boards'}}: - select.js-select-boards(autofocus) - each boards - option(value="{{_id}}" selected="{{#if isDialogOptionBoardId _id}}selected{{/if}}") {{add @index 1}}. {{title}} - - label {{_ 'swimlanes'}}: - select.js-select-swimlanes - each swimlanes - option(value="{{_id}}" selected="{{#if isDialogOptionSwimlaneId _id}}selected{{/if}}") {{add @index 1}}. {{isTitleDefault title}} - - label {{_ 'lists'}}: - select.js-select-lists - each lists - option(value="{{_id}}" selected="{{#if isDialogOptionListId _id}}selected{{/if}}") {{add @index 1}}. {{title}} - - label {{_ 'card'}}: - select.js-select-cards - each cards - option(value="{{_id}}" selected="{{#if isDialogOptionCardId _id}}selected{{/if}}") {{add @index 1}}. {{title}} - - .edit-controls.clearfix - button.primary.confirm.js-done {{_ 'done'}} + +copyAndMoveChecklist template(name="moveChecklistPopup") + +copyAndMoveChecklist + +template(name="copyAndMoveChecklist") unless currentUser.isWorker label {{_ 'boards'}}: select.js-select-boards(autofocus) each boards - option(value="{{_id}}" selected="{{#if isDialogOptionBoardId _id}}selected{{/if}}") {{add @index 1}}. {{title}} + option(value="{{_id}}" selected="{{#if isDialogOptionBoardId _id}}selected{{/if}}") {{title}} label {{_ 'swimlanes'}}: select.js-select-swimlanes each swimlanes - option(value="{{_id}}" selected="{{#if isDialogOptionSwimlaneId _id}}selected{{/if}}") {{add @index 1}}. {{isTitleDefault title}} + option(value="{{_id}}" selected="{{#if isDialogOptionSwimlaneId _id}}selected{{/if}}") {{title}} label {{_ 'lists'}}: select.js-select-lists each lists - option(value="{{_id}}" selected="{{#if isDialogOptionListId _id}}selected{{/if}}") {{add @index 1}}. {{title}} + option(value="{{_id}}" selected="{{#if isDialogOptionListId _id}}selected{{/if}}") {{title}} - label {{_ 'card'}}: + label {{_ 'cards'}}: select.js-select-cards each cards - option(value="{{_id}}" selected="{{#if isDialogOptionCardId _id}}selected{{/if}}") {{add @index 1}}. {{title}} + option(value="{{_id}}" selected="{{#if isDialogOptionCardId _id}}selected{{/if}}") {{title}} .edit-controls.clearfix button.primary.confirm.js-done {{_ 'done'}} diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js index 459fdeb0a..6762eab02 100644 --- a/client/components/cards/checklists.js +++ b/client/components/cards/checklists.js @@ -65,7 +65,7 @@ BlazeComponent.extendComponent({ $(self.itemsDom).sortable('option', 'disabled', !userIsMember()); if (Utils.isTouchScreenOrShowDesktopDragHandles()) { $(self.itemsDom).sortable({ - handle: 'span.checklistitem-handle', + handle: 'span.fa.checklistitem-handle', }); } } @@ -157,21 +157,29 @@ BlazeComponent.extendComponent({ textarea.focus(); }, - async editChecklist(event) { + deleteItem() { + const checklist = this.currentData().checklist; + const item = this.currentData().item; + if (checklist && item && item._id) { + ChecklistItems.remove(item._id); + } + }, + + editChecklist(event) { event.preventDefault(); const textarea = this.find('textarea.js-edit-checklist-item'); const title = textarea.value.trim(); const checklist = this.currentData().checklist; - await checklist.setTitle(title); + checklist.setTitle(title); }, - async editChecklistItem(event) { + editChecklistItem(event) { event.preventDefault(); const textarea = this.find('textarea.js-edit-checklist-item'); const title = textarea.value.trim(); const item = this.currentData().item; - await item.setTitle(title); + item.setTitle(title); }, pressKey(event) { @@ -208,28 +216,14 @@ BlazeComponent.extendComponent({ 'submit .js-add-checklist-item': this.addChecklistItem, 'submit .js-edit-checklist-item': this.editChecklistItem, 'click .js-convert-checklist-item-to-card': Popup.open('convertChecklistItemToCard'), - 'click .js-delete-checklist-item'(event) { - const item = this.currentData().item; - const confirmFunc = Popup.afterConfirm('checklistItemDelete', function () { - if (item && item._id) { - ChecklistItems.remove(item._id); - } - }); - confirmFunc.call(this, event); - }, - 'click .js-delete-checklist'(event) { - const checklist = this.currentData().checklist; - const confirmFunc = Popup.afterConfirm('checklistDelete', function () { - Popup.back(2); - if (checklist && checklist._id) { - Checklists.remove(checklist._id); - } - }); - confirmFunc.call(this, event); - }, + 'click .js-delete-checklist-item': this.deleteItem, 'focus .js-add-checklist-item': this.focusChecklistItem, // add and delete checklist / checklist-item 'click .js-open-inlined-form': this.closeAllInlinedForms, + 'click #toggleHideFinishedChecklist'(event) { + event.preventDefault(); + this.data().card.toggleHideFinishedChecklist(); + }, keydown: this.pressKey, }, ]; @@ -281,8 +275,8 @@ BlazeComponent.extendComponent({ Template.checklists.helpers({ checklists() { const card = ReactiveCache.getCard(this.cardId); - if (!card || typeof card.checklists !== 'function') return []; - return card.checklists(); + const ret = card.checklists(); + return ret; }, }); @@ -309,32 +303,23 @@ BlazeComponent.extendComponent({ events() { return [ { - 'click .js-delete-checklist'(event) { - const checklist = this.data().checklist; - const confirmFunc = Popup.afterConfirm('checklistDelete', function () { - Popup.back(2); - if (checklist && checklist._id) { - Checklists.remove(checklist._id); - } - }); - confirmFunc.call(this, event); - }, + 'click .js-delete-checklist': Popup.afterConfirm('checklistDelete', function () { + Popup.back(2); + const checklist = this.checklist; + if (checklist && checklist._id) { + Checklists.remove(checklist._id); + } + }), 'click .js-move-checklist': Popup.open('moveChecklist'), 'click .js-copy-checklist': Popup.open('copyChecklist'), - async 'click .js-hide-checked-checklist-items'(event) { + 'click .js-hide-checked-checklist-items'(event) { event.preventDefault(); - await this.data().checklist.toggleHideCheckedChecklistItems(); + this.data().checklist.toggleHideCheckedChecklistItems(); Popup.back(); }, - async 'click .js-hide-all-checklist-items'(event) { + 'click .js-hide-all-checklist-items'(event) { event.preventDefault(); - await this.data().checklist.toggleHideAllChecklistItems(); - Popup.back(); - }, - async 'click .js-toggle-show-checklist-at-minicard'(event) { - event.preventDefault(); - const checklist = this.data().checklist; - await checklist.toggleShowChecklistAtMinicard(); + this.data().checklist.toggleHideAllChecklistItems(); Popup.back(); }, } @@ -365,17 +350,16 @@ Template.checklistItemDetail.helpers({ }); BlazeComponent.extendComponent({ - async toggleItem() { + toggleItem() { const checklist = this.currentData().checklist; const item = this.currentData().item; if (checklist && item && item._id) { - await item.toggleItem(); + item.toggleItem(); } }, events() { return [ { - 'click .js-checklist-item .check-box-unicode': this.toggleItem, 'click .js-checklist-item .check-box-container': this.toggleItem, }, ]; @@ -390,12 +374,7 @@ BlazeComponent.extendComponent({ } setDone(cardId, options) { ReactiveCache.getCurrentUser().setMoveChecklistDialogOption(this.currentBoardId, options); - const checklist = this.data().checklist; - Meteor.call('moveChecklist', checklist._id, cardId, (error) => { - if (error) { - console.error('Error moving checklist:', error); - } - }); + this.data().checklist.move(cardId); } }).register('moveChecklistPopup'); diff --git a/client/components/cards/labels.jade b/client/components/cards/labels.jade index a32256748..8d12dc488 100644 --- a/client/components/cards/labels.jade +++ b/client/components/cards/labels.jade @@ -6,7 +6,7 @@ template(name="formLabel") .palette-colors: each labels span.card-label.palette-color.js-palette-color(class="card-label-{{color}}") if(isSelected color) - | ✅ + i.fa.fa-check template(name="createLabelPopup") form.create-label @@ -28,14 +28,13 @@ template(name="cardLabelsPopup") ul.edit-labels-pop-over each board.labels li.js-card-label-item - a.card-label-edit-button.js-edit-label - | ✏️ + a.card-label-edit-button.fa.fa-pencil.js-edit-label if isTouchScreenOrShowDesktopDragHandles - span.label-handle(title="{{_ 'dragLabel'}}") ↕️ + span.fa.label-handle(class="fa-arrows" title="{{_ 'dragLabel'}}") span.card-label.card-label-selectable.js-select-label.card-label-wrapper(class="card-label-{{color}}" class="{{# if isLabelSelected ../_id }}active{{/if}}") +viewer = name if(isLabelSelected ../_id) - | ✅ + i.card-label-selectable-icon.fa.fa-check a.quiet-button.full.js-add-label {{_ 'label-create'}} diff --git a/client/components/cards/labels.js b/client/components/cards/labels.js index 2962cae77..e09598189 100644 --- a/client/components/cards/labels.js +++ b/client/components/cards/labels.js @@ -125,19 +125,8 @@ Template.createLabelPopup.events({ .$('#labelName') .val() .trim(); - - // Find the selected color by looking for the palette color that contains the checkmark - let selectedColor = null; - templateInstance.$('.js-palette-color').each(function() { - if ($(this).text().includes('✅')) { - selectedColor = Blaze.getData(this).color; - return false; // break out of loop - } - }); - - if (selectedColor) { - board.addLabel(name, selectedColor); - } + const color = Blaze.getData(templateInstance.find('.fa-check')).color; + board.addLabel(name, color); Popup.back(); }, }); @@ -155,19 +144,8 @@ Template.editLabelPopup.events({ .$('#labelName') .val() .trim(); - - // Find the selected color by looking for the palette color that contains the checkmark - let selectedColor = null; - templateInstance.$('.js-palette-color').each(function() { - if ($(this).text().includes('✅')) { - selectedColor = Blaze.getData(this).color; - return false; // break out of loop - } - }); - - if (selectedColor) { - board.editLabel(this._id, name, selectedColor); - } + const color = Blaze.getData(templateInstance.find('.fa-check')).color; + board.editLabel(this._id, name, color); Popup.back(); }, }); diff --git a/client/components/cards/minicard.css b/client/components/cards/minicard.css index 171307ef5..0d57ca8d4 100644 --- a/client/components/cards/minicard.css +++ b/client/components/cards/minicard.css @@ -49,7 +49,7 @@ top: 0.7vh; font-size: clamp(14px, 3vw, 18px); padding: 0; - z-index: 10; + z-index: 1; } .minicard-details-menu { float: right; @@ -99,6 +99,7 @@ } .minicard .minicard-labels { float: none; + margin-right: 6vw; } .minicard .minicard-labels .minicard-label { width: clamp(12px, 1.5vw, 16px); @@ -113,6 +114,7 @@ } .minicard .minicard-custom-fields { display: block; + margin-right: 6vw; } .minicard .minicard-custom-field { display: flex; @@ -138,7 +140,7 @@ right: 3vw; top: 0.7vh; display: none; - z-index: 10; + z-index: 1; } @media only screen { .minicard .handle { @@ -152,6 +154,9 @@ width: 1.4em; text-align: center; } +.minicard .minicard-title { + margin-right: 6vw; +} .minicard .minicard-title .card-number { color: #b3b3b3; display: inline-block; @@ -170,6 +175,10 @@ display: flex; flex-direction: row; flex-wrap: wrap; + position: relative; + z-index: 5; + margin-right: 6vw; + clear: both; } .minicard .date { margin-right: 0.4vw; diff --git a/client/components/cards/minicard.jade b/client/components/cards/minicard.jade index e4ddb3af1..468d14af2 100644 --- a/client/components/cards/minicard.jade +++ b/client/components/cards/minicard.jade @@ -6,9 +6,10 @@ template(name="minicard") if canMoveCard if isTouchScreenOrShowDesktopDragHandles .handle - | ↕️ + i.fa.fa-arrows if canModifyCard - a.minicard-details-menu-with-handle.js-open-minicard-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}") ☰ + a.minicard-details-menu-with-handle.js-open-minicard-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}") + i.fa.fa-bars .dates if getReceived .date @@ -32,7 +33,7 @@ template(name="minicard") if hasActiveUploads .minicard-upload-progress .upload-progress-header - | 📤 + i.fa.fa-upload span {{_ 'uploading-files'}} ({{uploadCount}}) each uploads .upload-progress-item(class="{{#if $eq status 'error'}}upload-error{{/if}}") @@ -41,12 +42,11 @@ template(name="minicard") .upload-progress-fill(style="width: {{progress}}%") if $eq status 'error' .upload-progress-error - | ⚠️ + i.fa.fa-warning span {{_ 'upload-failed'}} else if $eq status 'completed' .upload-progress-success - | ✅ - span {{_ 'upload-completed'}} + i.fa.fa-check span {{_ 'upload-completed'}} .minicard-title if $eq 'prefix-with-full-path' currentBoard.presentParentTask @@ -57,12 +57,15 @@ template(name="minicard") | {{ parentCardName }} if isLinkedBoard a.js-linked-link - span.linked-icon | 📁 + span.linked-icon + i.fa.fa-folder else if isLinkedCard a.js-linked-link - span.linked-icon | 🃏 + span.linked-icon + i.fa.fa-id-card if getArchived - span.linked-icon.linked-archived | 📦 + span.linked-icon.linked-archived + i.fa.fa-archive +viewer if currentBoard.allowsCardNumber span.card-number @@ -143,7 +146,8 @@ template(name="minicard") if canModifyCard if comments.length .badge(title="{{_ 'card-comments-title' comments.length }}") - span.badge-icon.badge-comment.badge-text 💬 + span.badge-icon.badge-comment.badge-text + i.fa.fa-comment-o = ' ' = comments.length //span.badge-comment.badge-text @@ -151,32 +155,39 @@ template(name="minicard") if getDescription unless currentBoard.allowsDescriptionTextOnMinicard .badge.badge-state-image-only(title=getDescription) - span.badge-icon 📝 + span.badge-icon + i.fa.fa-file-text-o if getVoteQuestion .badge.badge-state-image-only(title=getVoteQuestion) - span.badge-icon(class="{{#if voteState}}text-green{{/if}}") 👍 + span.badge-icon(class="{{#if voteState}}text-green{{/if}}") + i.fa.fa-thumbs-up span.badge-text {{ voteCountPositive }} - span.badge-icon(class="{{#if $eq voteState false}}text-red{{/if}}") 👎 + span.badge-icon(class="{{#if $eq voteState false}}text-red{{/if}}") + i.fa.fa-thumbs-down span.badge-text {{ voteCountNegative }} if getPokerQuestion .badge.badge-state-image-only(title=getPokerQuestion) - span.badge-icon(class="{{#if pokerState}}text-green{{/if}}") ✅ + span.badge-icon(class="{{#if pokerState}}text-green{{/if}}") + i.fa.fa-check-square if expiredPoker span.badge-text {{ getPokerEstimation }} if attachments.length if currentBoard.allowsBadgeAttachmentOnMinicard .badge - span.badge-icon 📎 + span.badge-icon + i.fa.fa-paperclip span.badge-text= attachments.length if allSubtasks.count .badge - span.badge-icon 🌐 + span.badge-icon + i.fa.fa-globe span.badge-text.check-list-text {{subtasksFinishedCount}}/{{allSubtasksCount}} //{{subtasksFinishedCount}}/{{subtasksCount}} does not work because when a subtaks is archived, the count goes down if currentBoard.allowsCardSortingByNumber if currentBoard.allowsCardSortingByNumberOnMinicard .badge - span.badge-icon 🔢 + span.badge-icon + i.fa.fa-sort-numeric-asc span.badge-text.check-list-sort {{ sort }} if shouldShowChecklistAtMinicard each shouldShowChecklistAtMinicard @@ -188,7 +199,7 @@ template(name="minicard") | {{ getDescription }} if shouldShowListOnMinicard .minicard-list-name - | 📋 + i.fa.fa-list | {{ listName }} if $eq 'subtext-with-full-path' currentBoard.presentParentTask .parent-subtext @@ -207,7 +218,8 @@ template(name="minicardChecklist") .checklist-header .checklist-title= checklist.title if canModifyCard - a.checklist-menu.js-open-checklist-menu(title="{{_ 'checklistActionsPopup-title'}}") ☰ + a.checklist-menu.js-open-checklist-menu(title="{{_ 'checklistActionsPopup-title'}}") + i.fa.fa-bars each visibleItems +checklistItemDetail(item = . checklist = checklist card = card) diff --git a/client/components/cards/resultCard.jade b/client/components/cards/resultCard.jade index 5259f8ecc..90d7c07a0 100644 --- a/client/components/cards/resultCard.jade +++ b/client/components/cards/resultCard.jade @@ -13,7 +13,7 @@ template(name="resultCard") .broken-cards-null | {{_ 'no-name'}} if getBoard.archived - | 📦 + i.fa.fa-archive li.result-card-context.result-card-context-separator = ' ' | {{_ 'context-separator'}} @@ -27,7 +27,7 @@ template(name="resultCard") .broken-cards-null | {{_ 'no-name'}} if getSwimlane.archived - | 📦 + i.fa.fa-archive li.result-card-context.result-card-context-separator = ' ' | {{_ 'context-separator'}} @@ -41,4 +41,4 @@ template(name="resultCard") .broken-cards-null | {{_ 'no-name'}} if getList.archived - | 📦 + i.fa.fa-archive diff --git a/client/components/cards/subtasks.jade b/client/components/cards/subtasks.jade index 987235f2a..3ea5ec5e3 100644 --- a/client/components/cards/subtasks.jade +++ b/client/components/cards/subtasks.jade @@ -1,6 +1,6 @@ template(name="subtasks") h3.card-details-item-title - | 🌐 + i.fa.fa-globe | {{_ 'subtasks'}} if currentUser.isBoardAdmin if toggleDeleteDialog.get @@ -16,7 +16,7 @@ template(name="subtasks") +addSubtaskItemForm else a.js-open-inlined-form(title="{{_ 'add-subtask'}}") - | ➕ + i.fa.fa-plus template(name="subtaskDetail") .js-subtasks.subtask @@ -68,18 +68,20 @@ template(name="subtasksItems") +addSubtaskItemForm else a.add-subtask-item.js-open-inlined-form - | ➕ + i.fa.fa-plus | {{_ 'add-subtask-item'}}... template(name='subtaskItemDetail') .js-subtasks-item.subtasks-item if canModifyCard - span.check-box-unicode {{#if item.isFinished }}✅{{else}}⬜{{/if}} + span.check-box-unicode + i.fa(class="{{#if item.isFinished}}fa-check-square{{else}}fa-square-o{{/if}}") .item-title.js-open-inlined-form.is-editable(class="{{#if item.isFinished }}is-checked{{/if}}") +viewer = item.title else - span.check-box-unicode {{#if item.isFinished }}✅{{else}}⬜{{/if}} + span.check-box-unicode + i.fa(class="{{#if item.isFinished}}fa-check-square{{else}}fa-square-o{{/if}}") .item-title(class="{{#if item.isFinished }}is-checked{{/if}}") +viewer = item.title @@ -92,10 +94,10 @@ template(name="subtaskActionsPopup") ul.pop-over-list li a.js-view-subtask(title="{{ subtask.title }}") - | 👁️ + i.fa.fa-eye | {{_ "view-it"}} if currentUser.isBoardAdmin a.js-delete-subtask.delete-subtask - | 🗑️ + i.fa.fa-trash | {{_ "delete"}} ... diff --git a/client/components/forms/forms.css b/client/components/forms/forms.css index f2fd7fbc4..ed26361bf 100644 --- a/client/components/forms/forms.css +++ b/client/components/forms/forms.css @@ -130,8 +130,8 @@ textarea.editor { } input[type="submit"], button { - background: #cfcfcf; - background: linear-gradient(#cfcfcf, #c2c2c2); + background: #000; + background: linear-gradient(#000, #000); border: none; cursor: pointer; display: inline-block; @@ -139,6 +139,7 @@ button { line-height: 1.3; padding: 1vh 2.5vw; text-align: center; + color: #fff; } input[type="submit"] .wide, button .wide { @@ -149,14 +150,16 @@ input[type="submit"]:hover, button:hover, input[type="submit"]:focus, button:focus { - background: #c2c2c2; - background: linear-gradient(#c2c2c2, #b5b5b5); + background: #222; + background: linear-gradient(#222, #222); + color: #fff; } input[type="submit"]:active, button:active { - background: #b5b5b5; - background: linear-gradient(#b5b5b5, #a8a8a8); - box-shadow: inset 0 3px 6px rgba(0,0,0,0.1); + background: #111; + background: linear-gradient(#111, #111); + box-shadow: inset 0 3px 6px rgba(0,0,0,0.3); + color: #fff; } input[type="submit"]:active:hover, button:active:hover, @@ -183,6 +186,12 @@ input[type="submit"].primary:active, button.primary:active { background: #01628c; } +input[type="submit"].negate, +button.negate { + background: #eb5a46; + box-shadow: 0 1px 0 #4d4d4d; + color: #fff; +} input[type="submit"].negate:hover, button.negate:hover, input[type="submit"].negate:focus, @@ -217,10 +226,10 @@ input[type="submit"]:disabled:active, input[type="button"].disabled:active, button.disabled:active, .button.disabled:active { - background: #cfcfcf; + background: #555; cursor: default; box-shadow: none; - color: #a8a8a8; + color: #999; } fieldset { border: 1px solid #bfbfbf; @@ -400,12 +409,12 @@ body.grey-icons-enabled .materialCheckBox.is-checked { .button-link.setting.disabled.primary, .button-link.setting.disabled.primary:hover, .button-link.setting.disabled.primary:active { - background: #cfcfcf; - border-color: #c2c2c2; - border-bottom-color: #b5b5b5; + background: #555; + border-color: #444; + border-bottom-color: #333; cursor: default; box-shadow: none; - color: #a8a8a8; + color: #999; } .button-link.setting .label { color: #222; diff --git a/client/components/import/import.jade b/client/components/import/import.jade index 18039c7f5..3a85ce75a 100644 --- a/client/components/import/import.jade +++ b/client/components/import/import.jade @@ -1,7 +1,7 @@ template(name="importHeaderBar") h1 a.back-btn(href="{{pathFor 'home'}}") - | ⬅️ + i.fa-arrow-left | {{_ title}} template(name="import") @@ -36,7 +36,7 @@ template(name="importMapMembers") +userAvatar(userId=wekanId) else a.member.add-member - | ➕ + i.fa.fa-plus //- Due to the way the flewbox layout is working, we need to set some invisible items so that the last row items have a consistent width. diff --git a/client/components/lists/list.css b/client/components/lists/list.css index 10a94f3f0..fd548a9b6 100644 --- a/client/components/lists/list.css +++ b/client/components/lists/list.css @@ -161,29 +161,35 @@ body.list-resizing-active * { /* Use original display for consistent button positioning */ display: block !important; position: relative !important; - /* Prevent vertical expansion but allow normal height */ - overflow: hidden !important; + /* Allow overflow for text wrapping and forms */ + overflow: visible !important; +} + +/* Clearfix for floated buttons */ +.list-header::after { + content: ""; + display: table; + clear: both; } /* Ensure title text doesn't cause height changes for all lists */ .list-header .list-header-name { - /* Prevent text wrapping to maintain consistent height */ - white-space: nowrap !important; - /* Truncate text with ellipsis if too long */ - text-overflow: ellipsis !important; + /* Allow text wrapping to flow below buttons */ + white-space: normal !important; /* Ensure proper line height */ line-height: 1.2 !important; - /* Ensure it doesn't overflow */ - overflow: hidden !important; - /* Add margin to prevent overlap with buttons */ - margin-right: 120px !important; + /* Ensure it doesn't overflow horizontally */ + overflow-wrap: break-word !important; + word-wrap: break-word !important; + /* Full width since buttons are now absolutely positioned above */ + width: 100% !important; } -/* Position elements from right to left: hamburger, add card, drag handle */ +/* Position elements at top aligned with collapse button */ .list-header .js-open-list-menu { position: absolute !important; - top: 2.5vh !important; - right: 1.5vw !important; + top: 5px !important; + right: 10px !important; z-index: 15 !important; display: inline-block !important; padding: 4px !important; @@ -191,8 +197,8 @@ body.list-resizing-active * { .list-header .list-header-plus-top { position: absolute !important; - top: 2.5vh !important; - right: 3.25vw !important; + top: 5px !important; + right: 10px !important; z-index: 15 !important; display: inline-block !important; padding: 4px !important; @@ -200,8 +206,8 @@ body.list-resizing-active * { .list-header .list-header-handle-desktop { position: absolute !important; - top: 2.5vh !important; - right: 6.5vw !important; + top: 5px !important; + right: 40px !important; z-index: 15 !important; display: inline-block !important; cursor: move !important; @@ -245,42 +251,61 @@ body.list-resizing-active * { } .list.list-collapsed { flex: none; - min-width: 60px; - max-width: 80px; - width: 60px; + min-width: 30px; + max-width: 30px; + width: 30px; min-height: 60vh; height: 60vh; overflow: visible; position: relative; } .list.list-collapsed .list-header { - padding: 1vh 1.5vw 0.5vh; - min-height: 2.5vh !important; - height: auto !important; + padding: 5px 0; + min-height: 100% !important; + height: 100% !important; display: flex; flex-direction: column; align-items: center; justify-content: flex-start; position: relative; overflow: visible !important; - width: 100%; - max-width: 60px; - margin: 0 auto; + width: 30px; + max-width: 30px; + margin: 0; } .list.list-collapsed .list-header .js-collapse { - margin: 0 auto 0 auto; + position: relative !important; + left: -10px !important; + margin: 5px auto; z-index: 10; - padding: 8px 12px; - font-size: 12px; + padding: 5px; + font-size: 16px; white-space: nowrap; display: block; - width: fit-content; + width: auto; + left: auto !important; + top: auto !important; } .list.list-collapsed .list-header .list-header-handle { - position: absolute !important; - top: 30px !important; - right: 1.5vw !important; - z-index: 15 !important; + position: static !important; + margin: 5px auto; + z-index: 10; + padding: 5px; + display: block; + width: auto; + top: auto !important; + right: auto !important; +} + +.list.list-collapsed .list-header .list-header-handle-desktop { + position: static !important; + margin: 5px auto; + z-index: 10; + padding: 5px; + display: block; + width: auto; + top: auto !important; + right: auto !important; } .list.list-collapsed .list-header .list-rotated { width: auto !important; @@ -288,30 +313,43 @@ body.list-resizing-active * { margin: 20px 0 0 0 !important; position: relative !important; overflow: visible !important; + transform: rotate(90deg); + transform-origin: center center; + flex: 1; + display: flex; + align-items: center; + justify-content: center; } .list.list-collapsed .list-header .list-rotated h2.list-header-name { - text-align: left; + text-align: center; overflow: visible; white-space: nowrap; display: block !important; font-size: 12px; line-height: 1.2; color: #333; - background-color: rgba(255, 255, 255, 0.95); - border: 1px solid #ddd; - padding: 0; - border-radius: 4px; + padding: 4px 8px; margin: 0; - width: 100vh; - height: 30px; - position: absolute; - left: 40px; - top: 50%; - transform: translateY(calc(-50% + 20px)) rotate(0deg); + width: auto; + height: auto; + position: static; + left: auto; + top: auto; + transform: none; z-index: 10; visibility: visible !important; opacity: 1 !important; - pointer-events: none; + pointer-events: auto; +} + +.list.list-composer, +.list-composer { + display: none; +} + +/* Show list-composer when inside an active inlined form */ +form.inlined-form .list-composer { + display: block; } .list.list-composer .open-list-composer, @@ -348,16 +386,17 @@ body.list-resizing-active * { display: none; } .list-header .list-header-name { - display: inline; + display: block; font-size: clamp(14px, 3vw, 18px); line-height: 1.2; margin: 0; font-weight: bold; min-height: 1.2vh; min-width: 4vw; - overflow: hidden; - text-overflow: ellipsis; + overflow-wrap: break-word; word-wrap: break-word; + vertical-align: top; + width: 100%; } /* Sum badge shown before list title */ .list-header .list-sum-badge { @@ -398,6 +437,8 @@ body.list-resizing-active * { .list-header .list-header-plus-top { color: #a6a6a6; margin-right: 15px; + vertical-align: middle; + line-height: 1.2; } .list-header .list-header-collapse-right { color: #a6a6a6; @@ -406,41 +447,38 @@ body.list-resizing-active * { color: #a6a6a6; margin-right: 15px; } -/* List header collapse button styling */ -.list-header .list-header-collapse-container { - display: flex; - flex-direction: row; - align-items: flex-start; - gap: 10px; - flex: 1; - min-width: 0; -} - +/* List header collapse button styling - positioned at top left */ .list-header .js-collapse { + position: absolute !important; + top: 5px !important; + left: 10px !important; color: #a6a6a6; display: inline-block; - vertical-align: middle; + vertical-align: top; padding: 5px 8px; border: none; border-radius: 0; background-color: transparent; cursor: pointer; font-size: 18px; - line-height: 1; + line-height: 1.2; min-width: 30px; text-align: center; - flex-shrink: 0; text-decoration: none; margin: 0; + z-index: 15; } .list-header .js-collapse:hover { background-color: transparent; color: #333; } -.list-header .list-header-collapse-container > div { - flex: 1; - min-width: 0; +/* Title text container - full width below buttons */ +.list-header > div { + padding-top: 25px; + width: 100%; + display: block; + clear: both; } .list.list-collapsed .list-header .js-collapse { display: inline-block !important; @@ -448,132 +486,155 @@ body.list-resizing-active * { opacity: 1 !important; } +/* Hide menu button in collapsed state */ +.list.list-collapsed .list-header .js-open-list-menu, +.list.list-collapsed .list-header .list-header-menu { + display: none !important; +} + /* Responsive adjustments for collapsed lists */ @media (min-width: 768px) { .list.list-collapsed { - min-width: 60px; - max-width: 80px; - width: 60px; + min-width: 30px; + max-width: 30px; + width: 30px; min-height: 60vh; height: 60vh; } .list.list-collapsed .list-header { - max-width: 60px; - margin: 0 auto; - min-height: 2.5vh !important; - height: auto !important; + width: 30px; + max-width: 30px; + margin: 0; + min-height: 100% !important; + height: 100% !important; } .list.list-collapsed .list-header .list-rotated { width: auto !important; height: auto !important; margin: 20px 0 0 0 !important; position: relative !important; + transform: rotate(90deg); + flex: 1; } .list.list-collapsed .list-header .list-rotated h2.list-header-name { - width: 100vh; + width: auto; font-size: 12px; - height: 30px; + height: auto; line-height: 1.2; - padding: 0; + padding: 4px 8px; margin: 0; overflow: visible; - position: absolute; - left: 40px; - top: 50%; - transform: translateY(calc(-50% + 120px)) rotate(0deg); + position: static; + left: auto; + top: auto; + transform: none; text-align: center; visibility: visible !important; opacity: 1 !important; display: block !important; - background-color: rgba(255, 255, 255, 0.95); - border: 1px solid #ddd; + background-color: transparent; + border: none; color: #333; z-index: 10; } .list.list-collapsed .list-header .js-collapse { - margin: 0 auto 20px auto; + margin: 5px auto; } } @media (min-width: 1024px) { .list.list-collapsed { + min-width: 30px; + max-width: 30px; + width: 30px; min-height: 60vh; height: 60vh; } .list.list-collapsed .list-header { - min-height: 2.5vh !important; - height: auto !important; + width: 30px; + max-width: 30px; + min-height: 100% !important; + height: 100% !important; } .list.list-collapsed .list-header .list-rotated { width: auto !important; height: auto !important; margin: 20px 0 0 0 !important; position: relative !important; + transform: rotate(90deg); + flex: 1; } .list.list-collapsed .list-header .list-rotated h2.list-header-name { - width: 100vh; + width: auto; font-size: 12px; - height: 30px; + height: auto; line-height: 1.2; - padding: 0; + padding: 4px 8px; margin: 0; overflow: visible; - position: absolute; - left: 40px; - top: 50%; - transform: translateY(calc(-50% + 120px)) rotate(0deg); + position: static; + left: auto; + top: auto; + transform: none; text-align: center; visibility: visible !important; opacity: 1 !important; display: block !important; - background-color: rgba(255, 255, 255, 0.95); - border: 1px solid #ddd; + background-color: transparent; + border: none; color: #333; z-index: 10; } .list.list-collapsed .list-header .js-collapse { - margin: 0 auto 20px auto; + margin: 5px auto; } } @media (min-width: 1200px) { .list.list-collapsed { + min-width: 30px; + max-width: 30px; + width: 30px; min-height: 60vh; height: 60vh; } .list.list-collapsed .list-header { - min-height: 2.5vh !important; - height: auto !important; + width: 30px; + max-width: 30px; + min-height: 100% !important; + height: 100% !important; } .list.list-collapsed .list-header .list-rotated { width: auto !important; height: auto !important; margin: 20px 0 0 0 !important; position: relative !important; + transform: rotate(90deg); + flex: 1; } .list.list-collapsed .list-header .list-rotated h2.list-header-name { - width: 100vh; + width: auto; font-size: 12px; - height: 30px; + height: auto; line-height: 1.2; - padding: 0; + padding: 4px 8px; margin: 0; overflow: visible; - position: absolute; - left: 40px; - top: 50%; - transform: translateY(calc(-50% + 40px)) rotate(0deg); - text-align: left; + position: static; + left: auto; + top: auto; + transform: none; + text-align: center; visibility: visible !important; opacity: 1 !important; display: block !important; - background-color: rgba(255, 255, 255, 0.95); - border: 1px solid #ddd; + background-color: transparent; + border: none; color: #333; z-index: 10; } .list.list-collapsed .list-header .js-collapse { - margin: 0 auto 20px auto; + margin: 5px auto; } } .list-header .list-header-collapse { @@ -596,6 +657,8 @@ body.list-resizing-active * { } .js-open-list-menu { font-size: 18px; + vertical-align: middle; + line-height: 1.2; } .list-body { flex: 1 1 auto; @@ -1078,9 +1141,9 @@ body.list-resizing-active * { white-space: normal !important; overflow: visible !important; text-overflow: clip !important; - display: inline-block !important; - /* Reserve space for right-side controls (menu, handle, count) */ - max-width: calc(100% - 120px) !important; + display: block !important; + /* Full width since buttons are absolutely positioned */ + width: 100% !important; /* Break long words to avoid overflow */ word-break: break-word !important; } @@ -1173,3 +1236,48 @@ body.list-resizing-active * { .list-header-indigo { border-bottom: 6px solid #4b0082; } + +.list.list-collapsed .collapsed-list-drag-area { + width: 100%; + height: 60px; + display: flex; + align-items: center; + justify-content: center; + cursor: grab; + user-select: none; +} +.list.list-collapsed .collapsed-list-drag-area:active { + cursor: grabbing; +} +.list.list-collapsed .list-header-name-collapsed { + writing-mode: vertical-rl; + text-align: center; + font-size: 12px; + color: #333; + margin: 0; + padding: 0; + width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} + +.list.list-collapsed .list-header .js-collapse { + position: relative !important; + left: -10px !important; + color: #333; + background: transparent; + border: none; + border-radius: 0; + width: auto; + height: auto; + min-width: 0; + min-height: 0; + display: block !important; + align-items: initial; + justify-content: initial; + font-size: 16px !important; + box-shadow: none; + margin: 5px auto; + z-index: 10; +} diff --git a/client/components/lists/list.js b/client/components/lists/list.js index 2938b2be3..8a8d7c90d 100644 --- a/client/components/lists/list.js +++ b/client/components/lists/list.js @@ -276,20 +276,21 @@ BlazeComponent.extendComponent({ return; } - - // Only enable resize for non-collapsed, non-auto-width lists - const isAutoWidth = this.autoWidth(); - const isCollapsed = Utils.getListCollapseState(list); - if (isCollapsed || isAutoWidth) { - $resizeHandle.hide(); - return; - } + // Reactively show/hide resize handle based on collapse and auto-width state + this.autorun(() => { + const isAutoWidth = this.autoWidth(); + const isCollapsed = Utils.getListCollapseState(list); + if (isCollapsed || isAutoWidth) { + $resizeHandle.hide(); + } else { + $resizeHandle.show(); + } + }); let isResizing = false; let startX = 0; let startWidth = 0; let minWidth = 100; // Minimum width as defined in the existing code - let maxWidth = this.listConstraint() || 1000; // Use constraint as max width let listConstraint = this.listConstraint(); // Store constraint value for use in event handlers const component = this; // Store reference to component for use in event handlers @@ -318,7 +319,7 @@ BlazeComponent.extendComponent({ const currentX = e.pageX || e.originalEvent.touches[0].pageX; const deltaX = currentX - startX; - const newWidth = Math.max(minWidth, Math.min(maxWidth, startWidth + deltaX)); + const newWidth = Math.max(minWidth, startWidth + deltaX); // Apply the new width immediately for real-time feedback $list[0].style.setProperty('--list-width', `${newWidth}px`); @@ -343,7 +344,7 @@ BlazeComponent.extendComponent({ // Calculate final width const currentX = e.pageX || e.originalEvent.touches[0].pageX; const deltaX = currentX - startX; - const finalWidth = Math.max(minWidth, Math.min(maxWidth, startWidth + deltaX)); + const finalWidth = Math.max(minWidth, startWidth + deltaX); // Ensure the final width is applied $list[0].style.setProperty('--list-width', `${finalWidth}px`); @@ -466,3 +467,16 @@ Template.miniList.events({ Session.set('currentList', listId); }, }); + +// Enable drag-reorder for collapsed lists from .js-collapsed-list-drag area + this.$('.js-collapsed-list-drag').draggable({ + axis: 'x', + helper: 'clone', + revert: 'invalid', + start(evt, ui) { + boardComponent.setIsDragging(true); + }, + stop(evt, ui) { + boardComponent.setIsDragging(false); + } + }); diff --git a/client/components/lists/listBody.jade b/client/components/lists/listBody.jade index 7128148b8..dccab05d0 100644 --- a/client/components/lists/listBody.jade +++ b/client/components/lists/listBody.jade @@ -2,9 +2,8 @@ template(name="listBody") unless collapsed .list-body(class="{{#unless isVerticalScrollbars}}no-scrollbars{{/unless}}") .minicards.clearfix.js-minicards(class="{{#if reachedWipLimit}}js-list-full{{/if}}") - if cards.length - +inlinedForm(autoclose=false position="top") - +addCardForm(listId=_id position="top") + +inlinedForm(autoclose=false position="top") + +addCardForm(listId=_id position="top") ul.sidebar-list each customFieldsSum li @@ -26,13 +25,8 @@ template(name="listBody") +minicard(this) if (showSpinner (idOrNull ../../_id)) +spinnerList - - if canSeeAddCard - +inlinedForm(autoclose=false position="bottom") - +addCardForm(listId=_id position="bottom") - else - a.open-minicard-composer.js-card-composer.js-open-inlined-form(title="{{_ 'add-card-to-bottom-of-list'}}") - | ➕ + +inlinedForm(autoclose=false position="bottom") + +addCardForm(listId=_id position="bottom") template(name="spinnerList") .sk-spinner.sk-spinner-list( @@ -54,7 +48,8 @@ template(name="addCardForm") .add-controls.clearfix button.primary.confirm(type="submit") {{_ 'add'}} - a.js-close-inlined-form | ❌ + a.js-close-inlined-form + i.fa.fa-times-thin .add-controls.clearfix unless currentBoard.isTemplatesBoard unless currentBoard.isTemplateBoard diff --git a/client/components/lists/listHeader.jade b/client/components/lists/listHeader.jade index 7d637e3d7..0697684dc 100644 --- a/client/components/lists/listHeader.jade +++ b/client/components/lists/listHeader.jade @@ -8,7 +8,7 @@ template(name="listHeader") if isMiniScreen if currentList a.list-header-left-icon.js-unselect-list - | ◀️ + i.fa.fa-caret-left else if collapsed if showCardsCountForList cards.length @@ -30,22 +30,21 @@ template(name="listHeader") |   span.list-sum-badge(title="{{_ 'sum-of-number-fields'}}") ∑ {{numberFieldsSum}} else - div.list-header-collapse-container - a.list-collapse-indicator.js-collapse(title="{{_ 'collapse'}}") - if collapsed - | ▶ - else - | 🔽 - div(class="{{#if collapsed}}list-rotated{{/if}}") - h2.list-header-name( - title="{{ moment modifiedAt 'LLL' }}" - class="{{#if currentUser.isBoardMember}}{{#unless currentUser.isCommentOnly}}{{#unless currentUser.isWorker}}js-open-inlined-form is-editable{{/unless}}{{/unless}}{{/if}}") - +viewer - = title - if wipLimit.enabled - | ( - span(class="{{#if exceededWipLimit}}highlight{{/if}}") {{cards.length}} - |/#{wipLimit.value}) + a.list-collapse-indicator.js-collapse(title="{{_ 'collapse'}}") + if collapsed + i.fa.fa-caret-right + else + i.fa.fa-caret-down + div(class="{{#if collapsed}}list-rotated{{/if}}") + h2.list-header-name( + title="{{ moment modifiedAt 'LLL' }}" + class="{{#unless collapsed}}{{#if currentUser.isBoardMember}}{{#unless currentUser.isCommentOnly}}{{#unless currentUser.isWorker}}js-open-inlined-form is-editable{{/unless}}{{/unless}}{{/if}}{{/unless}}") + +viewer + = title + if wipLimit.enabled + | ( + span(class="{{#if exceededWipLimit}}highlight{{/if}}") {{cards.length}} + |/#{wipLimit.value}) unless collapsed if showCardsCountForList cards.length span.cardCount {{cardsCount}} {{cardsCountForListIsOne cards.length}} @@ -55,22 +54,29 @@ template(name="listHeader") if isMiniScreen if currentList if isWatching - i.list-header-watch-icon | 👁️ + i.list-header-watch-icon i.fa.fa-eye div.list-header-menu unless currentUser.isCommentOnly unless currentUser.isReadOnly unless currentUser.isReadAssignedOnly - if canSeeAddCard - a.js-add-card.list-header-plus-top(title="{{_ 'add-card-to-top-of-list'}}") ➕ - a.js-open-list-menu(title="{{_ 'listActionPopup-title'}}") ☰ + a.js-open-list-menu(title="{{_ 'listActionPopup-title'}}") + i.fa.fa-bars else - a.list-header-menu-icon.js-select-list ▶️ + a.list-header-menu-icon.js-select-list + i.fa.fa-caret-right unless currentUser.isWorker if isTouchScreenOrShowDesktopDragHandles - a.list-header-handle.handle.js-list-handle ↕️ + a.list-header-handle.handle.js-list-handle + i.fa.fa-arrows else if currentUser.isBoardMember if isWatching - i.list-header-watch-icon | 👁️ + i.list-header-watch-icon i.fa.fa-eye + unless currentUser.isCommentOnly + unless currentUser.isReadOnly + unless currentUser.isReadAssignedOnly + if isTouchScreenOrShowDesktopDragHandles + a.list-header-handle-desktop.handle.js-list-handle(title="{{_ 'drag-list'}}") + i.fa.fa-arrows unless collapsed div.list-header-menu unless currentUser.isCommentOnly @@ -78,11 +84,8 @@ template(name="listHeader") unless currentUser.isReadAssignedOnly //if isBoardAdmin // a.fa.js-list-star.list-header-plus-top(class="fa-star{{#unless starred}}-o{{/unless}}") - if isTouchScreenOrShowDesktopDragHandles - a.list-header-handle-desktop.handle.js-list-handle(title="{{_ 'drag-list'}}") ↕️ - if canSeeAddCard - a.js-add-card.list-header-plus-top(title="{{_ 'add-card-to-top-of-list'}}") ➕ - a.js-open-list-menu(title="{{_ 'listActionPopup-title'}}") ☰ + a.js-open-list-menu(title="{{_ 'listActionPopup-title'}}") + i.fa.fa-bars template(name="editListTitleForm") .list-composer @@ -90,31 +93,42 @@ template(name="editListTitleForm") .edit-controls.clearfix button.primary.confirm(type="submit") {{_ 'save'}} a.js-close-inlined-form - | ❌ + i.fa.fa-times-thin template(name="listActionPopup") unless currentUser.isReadOnly unless currentUser.isReadAssignedOnly ul.pop-over-list + li + a.js-add-card.list-header-plus-top + i.fa.fa-plus + i.fa.fa-arrow-up + | {{_ 'add-card-to-top-of-list'}} li a.js-add-card.list-header-plus-bottom - | ➕ - | ⬇️ + i.fa.fa-plus + i.fa.fa-arrow-down | {{_ 'add-card-to-bottom-of-list'}} hr + ul.pop-over-list + li + a.js-add-list + i.fa.fa-plus + | {{_ 'add-list'}} + hr ul.pop-over-list li a.js-set-list-width - | ↔️ + i.fa.fa-arrows-h | {{_ 'set-list-width'}} ul.pop-over-list li a.js-toggle-watch-list if isWatching - | 👁️ + i.fa.fa-eye | {{_ 'unwatch'}} else - | 🙈 + i.fa.fa-eye-slash | {{_ 'watch'}} unless currentUser.isCommentOnly unless currentUser.isReadOnly @@ -123,33 +137,33 @@ template(name="listActionPopup") ul.pop-over-list li a.js-set-color-list - | 🎨 + i.fa.fa-paint-brush | {{_ 'set-color-list'}} ul.pop-over-list if cards.length li a.js-select-cards - | ☑️ + i.fa.fa-select-square | {{_ 'list-select-cards'}} if currentUser.isBoardAdmin ul.pop-over-list li a.js-set-wip-limit - | 🚫 + i.fa.fa-ban | {{#if isWipLimitEnabled }}{{_ 'edit-wip-limit'}}{{else}}{{_ 'setWipLimitPopup-title'}}{{/if}} unless currentUser.isWorker hr ul.pop-over-list li a.js-close-list - | ➡️ - | 📦 + i.fa.fa-arrow-right + i.fa.fa-archive | {{_ 'archive-list'}} hr ul.pop-over-list li a.js-more - | 🔗 + i.fa.fa-link | {{_ 'listMorePopup-title'}} template(name="boardLists") @@ -166,7 +180,7 @@ template(name="listMorePopup") span.clearfix span {{_ 'link-list'}} = ' ' - | {{#if board.isPublic}}🌐{{else}}🔒{{/if}} + i.fa(class="{{#if currentBoard.isPublic}}fa-globe{{else}}fa-lock{{/if}}") input.inline-input(type="text" readonly value="{{ rootUrl }}") | {{_ 'added'}} span.date(title=list.createdAt) {{ moment createdAt 'LLL' }} @@ -186,7 +200,7 @@ template(name="setWipLimitPopup") ul.pop-over-list li: a.js-enable-wip-limit {{_ 'enable-wip-limit'}} if isWipLimitEnabled - | ✅ + i.fa.fa-check if isWipLimitEnabled p input.wip-limit-value(type="number" value="{{ wipLimitValue }}" min="1" max="99") @@ -228,6 +242,29 @@ template(name="setListColorPopup") // note: we use the swimlane palette to have more than just the border span.card-label.palette-color.js-palette-color(class="card-details-{{color}}") if(isSelected color) - | ✅ + i.fa.fa-check button.primary.confirm.js-submit {{_ 'save'}} button.js-remove-color.negate.wide.right {{_ 'unset-color'}} + +template(name="addListPopup") + form.js-add-list-form + input.list-name-input.full-line(type="text" placeholder="{{_ 'add-list'}}" autocomplete="off" autofocus) + if currentSwimlaneData + if swimlaneLists.length + label {{_ 'add-after-list'}} + select.list-position-input.full-line + each swimlaneLists + option(value="{{_id}}" selected="{{$eq _id currentListIdValue}}") {{increment @index}} {{title}} + else + if currentBoard.lists.length + label {{_ 'add-after-list'}} + select.list-position-input.full-line + each currentBoard.lists + option(value="{{_id}}" selected="{{$eq _id currentListIdValue}}") {{increment @index}} {{title}} + .edit-controls.clearfix + button.primary.confirm.js-submit-add-list(type="submit") {{_ 'save'}} + unless currentBoard.isTemplatesBoard + unless currentBoard.isTemplateBoard + span.quiet + | {{_ 'or'}} + a.js-list-template {{_ 'template'}} diff --git a/client/components/lists/listHeader.js b/client/components/lists/listHeader.js index cf860877f..d00e0b5ce 100644 --- a/client/components/lists/listHeader.js +++ b/client/components/lists/listHeader.js @@ -123,15 +123,6 @@ BlazeComponent.extendComponent({ this.collapsed(!this.collapsed()); }, 'click .js-open-list-menu': Popup.open('listAction'), - 'click .js-add-card.list-header-plus-top'(event) { - const listDom = $(event.target).parents( - `#js-list-${this.currentData()._id}`, - )[0]; - const listComponent = BlazeComponent.getComponentForElement(listDom); - listComponent.openForm({ - position: 'top', - }); - }, 'click .js-unselect-list'() { Session.set('currentList', null); }, @@ -204,14 +195,27 @@ Template.listActionPopup.helpers({ Template.listActionPopup.events({ 'click .js-list-subscribe'() {}, + 'click .js-add-card.list-header-plus-top'(event) { + const listDom = $(`#js-list-${this._id}`)[0]; + const listComponent = BlazeComponent.getComponentForElement(listDom); + if (listComponent) { + listComponent.openForm({ + position: 'top', + }); + } + Popup.back(); + }, 'click .js-add-card.list-header-plus-bottom'(event) { const listDom = $(`#js-list-${this._id}`)[0]; const listComponent = BlazeComponent.getComponentForElement(listDom); - listComponent.openForm({ - position: 'bottom', - }); + if (listComponent) { + listComponent.openForm({ + position: 'bottom', + }); + } Popup.back(); }, + 'click .js-add-list': Popup.open('addList'), 'click .js-set-list-width': Popup.open('setListWidth'), 'click .js-set-color-list': Popup.open('setListColor'), 'click .js-select-cards'() { @@ -440,3 +444,105 @@ BlazeComponent.extendComponent({ ]; }, }).register('setListWidthPopup'); + +BlazeComponent.extendComponent({ + onCreated() { + this.currentBoard = Utils.getCurrentBoard(); + this.currentSwimlaneId = new ReactiveVar(null); + this.currentListId = new ReactiveVar(null); + + // Get the swimlane context from opener + const openerData = Popup.getOpenerComponent()?.data(); + + // If opened from swimlane menu, openerData is the swimlane + if (openerData?.type === 'swimlane' || openerData?.type === 'template-swimlane') { + this.currentSwimlane = openerData; + this.currentSwimlaneId.set(openerData._id); + } else if (openerData?._id) { + // If opened from list menu, get swimlane from the list + const list = ReactiveCache.getList({ _id: openerData._id }); + this.currentSwimlane = list?.swimlaneId ? ReactiveCache.getSwimlane({ _id: list.swimlaneId }) : null; + this.currentSwimlaneId.set(this.currentSwimlane?._id || null); + this.currentListId.set(openerData._id); + } + }, + + currentSwimlaneData() { + const swimlaneId = this.currentSwimlaneId.get(); + return swimlaneId ? ReactiveCache.getSwimlane({ _id: swimlaneId }) : null; + }, + + currentListIdValue() { + return this.currentListId.get(); + }, + + swimlaneLists() { + const swimlaneId = this.currentSwimlaneId.get(); + if (swimlaneId) { + return ReactiveCache.getLists({ swimlaneId, archived: false }).sort((a, b) => a.sort - b.sort); + } + return this.currentBoard.lists; + }, + + events() { + return [ + { + 'submit .js-add-list-form'(evt) { + evt.preventDefault(); + + const titleInput = this.find('.list-name-input'); + const title = titleInput?.value.trim(); + + if (!title) return; + + let sortIndex = 0; + const boardId = Utils.getCurrentBoardId(); + const swimlaneId = this.currentSwimlane?._id; + + const positionInput = this.find('.list-position-input'); + + if (positionInput && positionInput.value) { + const positionId = positionInput.value.trim(); + const selectedList = ReactiveCache.getList({ boardId, _id: positionId, archived: false }); + + if (selectedList) { + sortIndex = selectedList.sort + 1; + } else { + // No specific position, add at end of swimlane + if (swimlaneId) { + const swimlaneLists = ReactiveCache.getLists({ swimlaneId, archived: false }); + const lastSwimlaneList = swimlaneLists.sort((a, b) => b.sort - a.sort)[0]; + sortIndex = Utils.calculateIndexData(lastSwimlaneList, null).base; + } else { + const lastList = this.currentBoard.getLastList(); + sortIndex = Utils.calculateIndexData(lastList, null).base; + } + } + } else { + // No position input, add at end of swimlane + if (swimlaneId) { + const swimlaneLists = ReactiveCache.getLists({ swimlaneId, archived: false }); + const lastSwimlaneList = swimlaneLists.sort((a, b) => b.sort - a.sort)[0]; + sortIndex = Utils.calculateIndexData(lastSwimlaneList, null).base; + } else { + const lastList = this.currentBoard.getLastList(); + sortIndex = Utils.calculateIndexData(lastList, null).base; + } + } + + Lists.insert({ + title, + boardId: Session.get('currentBoard'), + sort: sortIndex, + type: 'list', + swimlaneId: swimlaneId, + }); + + Popup.back(); + }, + 'click .js-list-template': Popup.open('searchElement'), + }, + ]; + }, +}).register('addListPopup'); + diff --git a/client/components/lists/minilist.jade b/client/components/lists/minilist.jade index 142308da8..6603e0bdf 100644 --- a/client/components/lists/minilist.jade +++ b/client/components/lists/minilist.jade @@ -3,6 +3,7 @@ template(name="minilist") class="minicard-{{colorClass}}") .minicard-title .handle - span.drag-handle(title="{{_ 'dragList'}}") ↕️ + span.drag-handle(title="{{_ 'dragList'}}") + i.fa.fa-arrows +viewer = title diff --git a/client/components/main/dueCards.jade b/client/components/main/dueCards.jade index f482c9233..6d9b46e5e 100644 --- a/client/components/main/dueCards.jade +++ b/client/components/main/dueCards.jade @@ -1,23 +1,23 @@ template(name="dueCardsHeaderBar") if currentUser h1 - | 📅 + i.fa.fa-calendar | {{_ 'dueCards-title'}} .board-header-btns.left a.board-header-btn.js-due-cards-view-change(title="{{_ 'dueCardsViewChange-title'}}") - | ▼ + i.fa.fa-caret-down if $eq dueCardsView 'me' - | 👤 + i.fa.fa-user | {{_ 'dueCardsViewChange-choice-me'}} if $eq dueCardsView 'all' - | 👥 + i.fa.fa-users | {{_ 'dueCardsViewChange-choice-all'}} template(name="dueCardsModalTitle") if currentUser h2 - | ⌨️ + i.fa.fa-keyboard-o | {{_ 'dueCards-title'}} template(name="dueCards") @@ -49,18 +49,17 @@ template(name="dueCardsViewChangePopup") li with "dueCardsViewChange-choice-me" a.js-due-cards-view-me - | 👤 + i.fa.fa-user | {{_ 'dueCardsViewChange-choice-me'}} if $eq Utils.dueCardsView "me" - | ✅ - hr + i.fa.fa-check hr li with "dueCardsViewChange-choice-all" a.js-due-cards-view-all - | 👥 + i.fa.fa-users | {{_ 'dueCardsViewChange-choice-all'}} span.sub-name +viewer | {{_ 'dueCardsViewChange-choice-all-description' }} if $eq Utils.dueCardsView "all" - | ✅ + i.fa.fa-check \ No newline at end of file diff --git a/client/components/main/editor.jade b/client/components/main/editor.jade index 802a8745d..4d7117ca3 100644 --- a/client/components/main/editor.jade +++ b/client/components/main/editor.jade @@ -1,8 +1,6 @@ template(name="editor") - a(title="{{_ 'convert-to-markdown'}}") - | 📝 - a(title="{{_ 'copy-text-to-clipboard'}}") - | 📋 + a.fa.fa-brands.fa-markdown(title="{{_ 'convert-to-markdown'}}") + a.fa.fa-copy(title="{{_ 'copy-text-to-clipboard'}}") span.copied-tooltip {{_ 'copied'}} textarea.editor( dir="auto" diff --git a/client/components/main/globalSearch.jade b/client/components/main/globalSearch.jade index da00bbf03..df8a52a38 100644 --- a/client/components/main/globalSearch.jade +++ b/client/components/main/globalSearch.jade @@ -1,13 +1,13 @@ template(name="globalSearchHeaderBar") if currentUser h1 - | 🔍 + i.fa.fa-search | {{_ 'globalSearch-title'}} template(name="globalSearchModalTitle") if currentUser h2 - | ⌨️ + i.fa.fa-keyboard-o | {{_ 'globalSearch-title'}} template(name="resultsPaged") diff --git a/client/components/main/header.jade b/client/components/main/header.jade index d4a0da8ae..fd3087732 100644 --- a/client/components/main/header.jade +++ b/client/components/main/header.jade @@ -9,7 +9,7 @@ template(name="header") // Home icon - always at left side of logo span.home-icon.allBoards a(href="{{pathFor 'home'}}") - | 🏠 + i.fa.fa-home | {{_ 'all-boards'}} // Logo - visible; on mobile constrained by CSS @@ -32,11 +32,11 @@ template(name="header") // Drag handles toggle - between zoom and mobile mode toggle a.board-header-btn.js-toggle-desktop-drag-handles(title="{{_ 'show-desktop-drag-handles'}}") - | ↕️ + i.fa.fa-arrows if isShowDesktopDragHandles - | ✅ + i.fa.fa-check unless isShowDesktopDragHandles - | 🚫 + i.fa.fa-ban if isMiniScreen ul.header-quick-access-list @@ -64,8 +64,9 @@ template(name="header") a(href="{{pathFor 'board' id=_id slug=slug}}") +viewer = title - else - li.current.empty {{_ 'quick-access-description'}} + //else + // li.current.empty + // {{_ 'quick-access-description'}} #header-new-board-icon // Next line is used only for spacing at header, // there is no visible clickable icon. @@ -77,8 +78,10 @@ template(name="header") .mobile-mode-toggle a.board-header-btn.js-mobile-mode-toggle(title="{{_ 'mobile-desktop-toggle'}}" class="{{#if mobileMode}}mobile-active{{else}}desktop-active{{/if}}") - i.mobile-icon(class="{{#if mobileMode}}active{{/if}}") 📱 - i.desktop-icon(class="{{#unless mobileMode}}active{{/unless}}") 🖥️ + i.mobile-icon(class="{{#if mobileMode}}active{{/if}}") + i.fa.fa-mobile + i.desktop-icon(class="{{#unless mobileMode}}active{{/unless}}") + i.fa.fa-desktop // Notifications +notifications @@ -86,7 +89,7 @@ template(name="header") if currentSetting.customHelpLinkUrl #header-help a(href="{{currentSetting.customHelpLinkUrl}}", title="{{_ 'help'}}", target="_blank", rel="noopener noreferrer") - | ❓ + i.fa.fa-question-circle +headerUserBar @@ -105,17 +108,17 @@ template(name="header") if hasAnnouncement .announcement p - | 📢 + i.fa.fa-bullhorn +viewer | #{announcement} a .js-close-announcement - | ❌ + i.fa.fa-times-thin template(name="offlineWarning") .offline-warning p - | ⚠️ + i.fa.fa-warning | {{_ 'app-is-offline'}} a.app-try-reconnect {{_ 'app-try-reconnect'}} diff --git a/client/components/main/keyboardShortcuts.jade b/client/components/main/keyboardShortcuts.jade index 1eee1d220..1d8ca981d 100644 --- a/client/components/main/keyboardShortcuts.jade +++ b/client/components/main/keyboardShortcuts.jade @@ -6,7 +6,7 @@ template(name="shortcutsHeaderBar") template(name="shortcutsModalTitle") h2 - | ⌨️ + i.fa.fa-keyboard-o | {{_ 'keyboard-shortcuts'}} template(name="keyboardShortcuts") diff --git a/client/components/main/layouts.jade b/client/components/main/layouts.jade index 7f50d0438..7bd257fbd 100644 --- a/client/components/main/layouts.jade +++ b/client/components/main/layouts.jade @@ -69,9 +69,15 @@ template(name="userFormsLayout") select.select-lang.js-userform-set-language#userform-set-language-select(aria-label="{{_ 'changeLanguagePopup-title'}}") each languages if isCurrentLanguage - option(value="{{tag}}" selected="selected") {{name}} + if rtl + option(value="{{tag}}" selected="selected") {{name}} (RTL) + else + option(value="{{tag}}" selected="selected") {{name}} else - option(value="{{tag}}") {{name}} + if rtl + option(value="{{tag}}") {{name}} (RTL) + else + option(value="{{tag}}") {{name}} template(name="defaultLayout") +header @@ -86,13 +92,13 @@ template(name="defaultLayout") if (Modal.isWide) .modal-content-wide.modal-container a.modal-close-btn.js-close-modal - | ❌ + i.fa.fa-times-thin +Template.dynamic(template=Modal.getHeaderName) +Template.dynamic(template=Modal.getTemplateName) else .modal-content.modal-container a.modal-close-btn.js-close-modal - | ❌ + i.fa.fa-times-thin +Template.dynamic(template=Modal.getHeaderName) +Template.dynamic(template=Modal.getTemplateName) @@ -103,8 +109,7 @@ template(name="message") .big-message.quiet(class=color) h1 {{_ label}} unless currentUser - with(pathFor route='atSignIn') - p {{{_ 'page-maybe-private' this}}} + p {{{_ 'page-maybe-private' '/sign-in'}}} template(name="loader") h1.loadingText {{_ 'loading'}} diff --git a/client/components/main/layouts.js b/client/components/main/layouts.js index 8257ed41e..0943d6b36 100644 --- a/client/components/main/layouts.js +++ b/client/components/main/layouts.js @@ -85,6 +85,70 @@ Template.userFormsLayout.onRendered(() => { validator, ); EscapeActions.executeAll(); + + // Set up MutationObserver for OIDC button instead of deprecated DOMSubtreeModified + const oidcButton = document.getElementById('at-oidc'); + if (oidcButton) { + const observer = new MutationObserver((mutations) => { + if (alreadyCheck <= 2) { + let currSetting = ReactiveCache.getCurrentSetting(); + let oidcBtnElt = $('#at-oidc'); + if ( + currSetting && + currSetting !== undefined && + currSetting.oidcBtnText !== undefined && + oidcBtnElt != null && + oidcBtnElt != undefined + ) { + let htmlvalue = "" + currSetting.oidcBtnText; + if (alreadyCheck == 1) { + alreadyCheck++; + oidcBtnElt.html(''); + } else { + alreadyCheck++; + oidcBtnElt.html(htmlvalue); + } + } + } else { + alreadyCheck = 1; + } + }); + observer.observe(oidcButton, { childList: true, subtree: true }); + } + + // Set up MutationObserver for .at-form instead of deprecated DOMSubtreeModified + const atForm = document.querySelector('.at-form'); + if (atForm) { + const formObserver = new MutationObserver((mutations) => { + if (alreadyCheck <= 2 && !isCheckDone) { + if (document.getElementById('at-oidc') != null) { + let currSetting = ReactiveCache.getCurrentSetting(); + let oidcBtnElt = $('#at-oidc'); + if ( + currSetting && + currSetting !== undefined && + currSetting.oidcBtnText !== undefined && + oidcBtnElt != null && + oidcBtnElt != undefined + ) { + let htmlvalue = + "" + currSetting.oidcBtnText; + if (alreadyCheck == 1) { + alreadyCheck++; + oidcBtnElt.html(''); + } else { + alreadyCheck++; + isCheckDone = true; + oidcBtnElt.html(htmlvalue); + } + } + } + } else { + alreadyCheck = 1; + } + }); + formObserver.observe(atForm, { childList: true, subtree: true }); + } // Add autocomplete attribute to login input for WCAG compliance const loginInput = document.querySelector( @@ -152,7 +216,7 @@ Template.userFormsLayout.helpers({ languages() { return TAPi18n.getSupportedLanguages() - .map(({ tag, name }) => ({ tag: tag, name })) + .map(({ tag, name, rtl }) => ({ tag, name, rtl })) .sort((a, b) => { if (a.name === b.name) { return 0; @@ -183,61 +247,6 @@ Template.userFormsLayout.events({ } isCheckDone = false; }, - 'click #at-signUp'(event, templateInstance) { - isCheckDone = false; - }, - 'DOMSubtreeModified #at-oidc'(event) { - if (alreadyCheck <= 2) { - let currSetting = ReactiveCache.getCurrentSetting(); - let oidcBtnElt = $('#at-oidc'); - if ( - currSetting && - currSetting !== undefined && - currSetting.oidcBtnText !== undefined && - oidcBtnElt != null && - oidcBtnElt != undefined - ) { - let htmlvalue = "" + currSetting.oidcBtnText; - if (alreadyCheck == 1) { - alreadyCheck++; - oidcBtnElt.html(''); - } else { - alreadyCheck++; - oidcBtnElt.html(htmlvalue); - } - } - } else { - alreadyCheck = 1; - } - }, - 'DOMSubtreeModified .at-form'(event) { - if (alreadyCheck <= 2 && !isCheckDone) { - if (document.getElementById('at-oidc') != null) { - let currSetting = ReactiveCache.getCurrentSetting(); - let oidcBtnElt = $('#at-oidc'); - if ( - currSetting && - currSetting !== undefined && - currSetting.oidcBtnText !== undefined && - oidcBtnElt != null && - oidcBtnElt != undefined - ) { - let htmlvalue = - "" + currSetting.oidcBtnText; - if (alreadyCheck == 1) { - alreadyCheck++; - oidcBtnElt.html(''); - } else { - alreadyCheck++; - isCheckDone = true; - oidcBtnElt.html(htmlvalue); - } - } - } - } else { - alreadyCheck = 1; - } - }, }); Template.defaultLayout.events({ diff --git a/client/components/main/myCards.jade b/client/components/main/myCards.jade index 86105ced4..33c8afa01 100644 --- a/client/components/main/myCards.jade +++ b/client/components/main/myCards.jade @@ -3,23 +3,23 @@ template(name="myCardsHeaderBar") h1 //a.back-btn(href="{{pathFor 'home'}}") // i.fa.fa-chevron-left - | 📋 + i.fa.fa-list | {{_ 'my-cards'}} .board-header-btns.left a.board-header-btn.js-my-cards-view-change(title="{{_ 'myCardsViewChange-title'}}") - | ▼ + i.fa.fa-caret-down if $eq myCardsView 'boards' - | 📋 + i.fa.fa-list | {{_ 'myCardsViewChange-choice-boards'}} if $eq myCardsView 'table' - | 📊 + i.fa.fa-bar-chart | {{_ 'myCardsViewChange-choice-table'}} template(name="myCardsModalTitle") if currentUser h2 - | ⌨️ + i.fa.fa-keyboard-o | {{_ 'my-cards'}} template(name="myCards") @@ -102,15 +102,15 @@ template(name="myCardsViewChangePopup") li with "myCardsViewChange-choice-boards" a.js-my-cards-view-boards - | 📋 + i.fa.fa-list | {{_ 'myCardsViewChange-choice-boards'}} if $eq Utils.myCardsView "boards" - | ✅ + i.fa.fa-check hr li with "myCardsViewChange-choice-table" a.js-my-cards-view-table - | 📊 + i.fa.fa-bar-chart | {{_ 'myCardsViewChange-choice-table'}} if $eq Utils.myCardsView "table" - | ✅ + i.fa.fa-check diff --git a/client/components/main/popup.css b/client/components/main/popup.css index 2fed6211b..b9d942238 100644 --- a/client/components/main/popup.css +++ b/client/components/main/popup.css @@ -478,6 +478,7 @@ /* flex-wrap:wrap;*/ gap:5px; align-items: center; + color: #000 !important; } .pop-over-list li > a > .member{ align-self: flex-start; diff --git a/client/components/main/popup.tpl.jade b/client/components/main/popup.tpl.jade index 630998962..463b2a5d0 100644 --- a/client/components/main/popup.tpl.jade +++ b/client/components/main/popup.tpl.jade @@ -6,10 +6,10 @@ style="left:{{offset.left}}px; top:{{offset.top}}px;{{#if offset.maxHeight}} max-height:{{offset.maxHeight}}px;{{/if}}") .header a.back-btn.js-back-view(class="{{#unless hasPopupParent}}is-hidden{{/unless}}") - | ◀️ + i.fa.fa-caret-left span.header-title= title a.close-btn.js-close-pop-over - | ❌ + i.fa.fa-times-thin .content-wrapper //- We display the all stack of popup content next to each other and move diff --git a/client/components/notifications/notification.css b/client/components/notifications/notification.css index 2de0dd05f..4426a0f8d 100644 --- a/client/components/notifications/notification.css +++ b/client/components/notifications/notification.css @@ -25,7 +25,7 @@ height: 1.2em; font-size: clamp(14px, 2vw, 17px); display: block; - color: #bbb; + color: #000; } #notifications-drawer .notification .read-status .activity-type.hidden { display: none; diff --git a/client/components/notifications/notifications.jade b/client/components/notifications/notifications.jade index 75391f349..b2209a72c 100644 --- a/client/components/notifications/notifications.jade +++ b/client/components/notifications/notifications.jade @@ -1,6 +1,6 @@ template(name='notifications') #notifications.board-header-btns.right a.notifications-drawer-toggle(class="{{#if $gt unreadNotifications 0}}alert{{/if}}" title="{{_ 'notifications'}}") - | 🔔 + i.fa.fa-bell if $.Session.get 'showNotificationsDrawer' +notificationsDrawer(unreadNotifications=unreadNotifications) diff --git a/client/components/notifications/notificationsDrawer.jade b/client/components/notifications/notificationsDrawer.jade index 17200d43d..0c6070459 100644 --- a/client/components/notifications/notificationsDrawer.jade +++ b/client/components/notifications/notificationsDrawer.jade @@ -1,42 +1,54 @@ template(name='notificationsDrawer') section#notifications-drawer(class="{{#if $.Session.get 'showReadNotifications'}}show-read{{/if}}") .header - a.notification-menu-toggle ☰ + a.notification-menu-toggle + i.fa.fa-bars .notification-menu(class="{{#if $.Session.get 'showNotificationMenu'}}is-open{{/if}}") .menu-section a.menu-item(class="{{#unless $.Session.get 'showReadNotifications'}}selected{{/unless}}") - span.check-icon {{#unless $.Session.get 'showReadNotifications'}}✓{{/unless}} - span.menu-icon 📭 + span.check-icon + if $not $.Session.get 'showReadNotifications' + i.fa.fa-check + span.menu-icon + i.fa.fa-envelope-open span {{_ 'filter-by-unread'}} a.menu-item(class="{{#if $.Session.get 'showReadNotifications'}}selected{{/if}}") - span.check-icon {{#if $.Session.get 'showReadNotifications'}}✓{{/if}} - span.menu-icon 📋 + span.check-icon + if $.Session.get 'showReadNotifications' + i.fa.fa-check + span.menu-icon + i.fa.fa-copy span {{_ 'view-all'}} .menu-divider .menu-section if($gt unreadNotifications 0) a.menu-item.mark-all-read span.check-icon - span.menu-icon ✅ + span.menu-icon + i.fa.fa-check span {{_ 'mark-all-as-read'}} if ($and ($.Session.get 'showReadNotifications') ($gt readNotifications 0)) a.menu-item.mark-all-unread span.check-icon - span.menu-icon 📬 + span.menu-icon + i.fa.fa-envelope-open span {{_ 'mark-all-as-unread'}} if ($and ($.Session.get 'showReadNotifications') ($gt readNotifications 0)) a.menu-item.delete-read span.check-icon - span.menu-icon 🗑️ + span.menu-icon + i.fa.fa-trash span {{_ 'remove-all-read'}} a.menu-item.delete-all span.check-icon - span.menu-icon 🗑️ + span.menu-icon + i.fa.fa-trash span {{_ 'delete-all-notifications'}} h5 {{_ 'notifications'}} if($gt unreadNotifications 0) |(#{unreadNotifications}) - a.close ❌ + a.close + i.fa.fa-times-thin ul.notifications each notifications +notification(activityData=activityObj index=dbIndex read=read) diff --git a/client/components/rules/actions/boardActions.jade b/client/components/rules/actions/boardActions.jade index 85ff97ebe..1a49d5eca 100644 --- a/client/components/rules/actions/boardActions.jade +++ b/client/components/rules/actions/boardActions.jade @@ -10,7 +10,7 @@ template(name="boardActions") div.trigger-text | {{_'r-its-list'}} div.trigger-button.js-add-gen-move-action.js-goto-rules - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content @@ -39,7 +39,7 @@ template(name="boardActions") div.trigger-dropdown input(id="swimlaneName",type=text,placeholder="{{_'r-name'}}") div.trigger-button.js-add-spec-move-action.js-goto-rules - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content @@ -50,7 +50,7 @@ template(name="boardActions") div.trigger-text | {{_'r-card'}} div.trigger-button.js-add-arch-action.js-goto-rules - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content @@ -59,7 +59,7 @@ template(name="boardActions") div.trigger-dropdown input(id="swimlane-name",type=text,placeholder="{{_'r-name'}}") div.trigger-button.js-add-swimlane-action.js-goto-rules - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content @@ -76,7 +76,7 @@ template(name="boardActions") div.trigger-dropdown input(id="swimlane-name2",type=text,placeholder="{{_'r-name'}}") div.trigger-button.js-create-card-action.js-goto-rules - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content @@ -101,7 +101,7 @@ template(name="boardActions") div.trigger-dropdown input(id="swimlaneName-link",type=text,placeholder="{{_'r-name'}}") div.trigger-button.js-link-card-action.js-goto-rules - | ➕ + i.fa.fa-plus diff --git a/client/components/rules/actions/cardActions.jade b/client/components/rules/actions/cardActions.jade index baaf883af..b5c834469 100644 --- a/client/components/rules/actions/cardActions.jade +++ b/client/components/rules/actions/cardActions.jade @@ -16,7 +16,7 @@ template(name="cardActions") div.trigger-text | {{_'r-to-current-datetime'}} div.trigger-button.js-set-date-action.js-goto-rules - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content @@ -30,7 +30,7 @@ template(name="cardActions") option(value="endAt") {{_'r-df-end-at'}} option(value="receivedAt") {{_'r-df-received-at'}} div.trigger-button.js-remove-datevalue-action.js-goto-rules - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content @@ -46,7 +46,7 @@ template(name="cardActions") option(value="#{_id}") = name div.trigger-button.js-add-label-action.js-goto-rules - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content @@ -59,14 +59,14 @@ template(name="cardActions") div.trigger-dropdown input(id="member-name",type=text,placeholder="{{_'r-name'}}") div.trigger-button.js-add-member-action.js-goto-rules - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content div.trigger-text | {{_'r-remove-all'}} div.trigger-button.js-add-removeall-action.js-goto-rules - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content @@ -77,12 +77,11 @@ template(name="cardActions") class="card-details-{{cardColorButton}}") | {{_ cardColorButtonText }} div.trigger-button.js-set-color-action.js-goto-rules - | ➕ + i.fa.fa-plus template(name="setCardActionsColorPopup") form.edit-label .palette-colors: each colors span.card-label.palette-color.js-palette-color(class="card-details-{{color}}") if(isSelected color) - | ✅ - button.primary.confirm.js-submit {{_ 'save'}} + i.fa.fa-check button.primary.confirm.js-submit {{_ 'save'}} diff --git a/client/components/rules/actions/checklistActions.jade b/client/components/rules/actions/checklistActions.jade index 399483ec8..d3d587c42 100644 --- a/client/components/rules/actions/checklistActions.jade +++ b/client/components/rules/actions/checklistActions.jade @@ -10,7 +10,7 @@ template(name="checklistActions") div.trigger-dropdown input(id="checklist-name",type=text,placeholder="{{_'r-name'}}") div.trigger-button.js-add-checklist-action.js-goto-rules - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content @@ -23,7 +23,7 @@ template(name="checklistActions") div.trigger-dropdown input(id="checklist-name2",type=text,placeholder="{{_'r-name'}}") div.trigger-button.js-add-checkall-action.js-goto-rules - | ➕ + i.fa.fa-plus div.trigger-item @@ -41,7 +41,7 @@ template(name="checklistActions") div.trigger-dropdown input(id="checklist-name3",type=text,placeholder="{{_'r-name'}}") div.trigger-button.js-add-check-item-action.js-goto-rules - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content @@ -54,17 +54,10 @@ template(name="checklistActions") div.trigger-dropdown input(id="checklist-items",type=text,placeholder="{{_'r-items-list'}}") div.trigger-button.js-add-checklist-items-action.js-goto-rules - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content div.trigger-text | {{_'r-checklist-note'}} - - - - - - - diff --git a/client/components/rules/actions/mailActions.jade b/client/components/rules/actions/mailActions.jade index 098629e10..7be78c751 100644 --- a/client/components/rules/actions/mailActions.jade +++ b/client/components/rules/actions/mailActions.jade @@ -8,4 +8,4 @@ template(name="mailActions") input(id="email-subject",type=text,placeholder="{{_'r-subject'}}") textarea(id="email-msg") div.trigger-button.trigger-button-email.js-mail-action.js-goto-rules - | ➕ + i.fa.fa-plus diff --git a/client/components/rules/ruleDetails.jade b/client/components/rules/ruleDetails.jade index d0c10e559..64819d057 100644 --- a/client/components/rules/ruleDetails.jade +++ b/client/components/rules/ruleDetails.jade @@ -1,7 +1,7 @@ template(name="ruleDetails") .rules h2 - | ✨ + i.fa.fa-magic | {{_ 'r-rule-details' }} .triggers-content .triggers-body @@ -20,5 +20,5 @@ template(name="ruleDetails") = action div.rules-back button.js-goback - | ◀️ + i.fa.fa-arrow-left | {{_ 'back'}} diff --git a/client/components/rules/rulesActions.jade b/client/components/rules/rulesActions.jade index 3deb7ba6d..8f6af2e0c 100644 --- a/client/components/rules/rulesActions.jade +++ b/client/components/rules/rulesActions.jade @@ -1,18 +1,17 @@ template(name="rulesActions") h2 - | ✨ + i.fa.fa-magic | {{_ 'r-rule' }} "{{ruleNameStr}}" - {{_ 'r-add-action'}} .triggers-content .triggers-body .triggers-side-menu ul li.active.js-set-board-actions - | 📊 + i.fa.fa-bar-chart li.js-set-card-actions - | 📝 + i.fa.fa-file-text-o li.js-set-checklist-actions - | ✅ - li.js-set-mail-actions + i.fa.fa-check li.js-set-mail-actions | @ .triggers-main-body if $eq currentActions.get 'board' @@ -25,5 +24,5 @@ template(name="rulesActions") +mailActions(ruleName=data.ruleName triggerVar=data.triggerVar) div.rules-back button.js-goback - | ◀️ + i.fa.fa-arrow-left | {{_ 'back'}} diff --git a/client/components/rules/rulesList.jade b/client/components/rules/rulesList.jade index f13255cb1..f3f734ebb 100644 --- a/client/components/rules/rulesList.jade +++ b/client/components/rules/rulesList.jade @@ -1,7 +1,7 @@ template(name="rulesList") .rules h2 - | ✨ + i.fa.fa-magic | {{_ 'r-board-rules' }} ul.rules-list @@ -11,27 +11,27 @@ template(name="rulesList") = title div.rules-btns-group button.js-goto-details - | 👁️ + i.fa.fa-eye | {{_ 'r-view-rule'}} if currentUser.isAdmin button.js-delete-rule - | 🗑️ + i.fa.fa-trash | {{_ 'r-delete-rule'}} else if currentUser.isBoardAdmin button.js-delete-rule - | 🗑️ + i.fa.fa-trash | {{_ 'r-delete-rule'}} else li.no-items-message {{_ 'r-no-rules' }} if currentUser.isAdmin div.rules-add button.js-goto-trigger - | ➕ + i.fa.fa-plus | {{_ 'r-add-rule'}} input(type=text,placeholder="{{_ 'r-new-rule-name' }}",id="ruleTitle") else if currentUser.isBoardAdmin div.rules-add button.js-goto-trigger - | ➕ + i.fa.fa-plus | {{_ 'r-add-rule'}} input(type=text,placeholder="{{_ 'r-new-rule-name' }}",id="ruleTitle") diff --git a/client/components/rules/rulesTriggers.jade b/client/components/rules/rulesTriggers.jade index e110198c5..1e6c1cb6f 100644 --- a/client/components/rules/rulesTriggers.jade +++ b/client/components/rules/rulesTriggers.jade @@ -1,18 +1,17 @@ template(name="rulesTriggers") h2 - | ✨ + i.fa.fa-magic | {{_ 'r-rule' }} "{{ruleNameStr}}" - {{_ 'r-add-trigger'}} .triggers-content .triggers-body .triggers-side-menu ul li.active.js-set-board-triggers - | 📊 + i.fa.fa-bar-chart li.js-set-card-triggers - | 📝 + i.fa.fa-file-text-o li.js-set-checklist-triggers - | ✅ - .triggers-main-body + i.fa.fa-check .triggers-main-body if showBoardTrigger.get +boardTriggers else if showCardTrigger.get @@ -21,5 +20,5 @@ template(name="rulesTriggers") +checklistTriggers div.rules-back button.js-goback - | ◀️ + i.fa.fa-arrow-left | {{_ 'back'}} diff --git a/client/components/rules/triggers/boardTriggers.jade b/client/components/rules/triggers/boardTriggers.jade index 419c5faaf..85524892a 100644 --- a/client/components/rules/triggers/boardTriggers.jade +++ b/client/components/rules/triggers/boardTriggers.jade @@ -4,7 +4,7 @@ template(name="boardTriggers") div.trigger-text | {{_'r-when-a-card'}} div.trigger-inline-button.js-open-card-title-popup - | 🔍 + i.fa.fa-search div.trigger-text | {{_'r-is'}} div.trigger-text @@ -18,39 +18,39 @@ template(name="boardTriggers") div.trigger-dropdown input(id="create-swimlane-name",type=text,placeholder="{{_'r-swimlane-name'}}") div.trigger-button.trigger-button-person.js-show-user-field - | 👤 + i.fa.fa-user div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-create-trigger.js-goto-action - | ➕ + i.fa.fa-plus div.trigger-item#trigger-three div.trigger-content div.trigger-text | {{_'r-when-a-card'}} div.trigger-inline-button.js-open-card-title-popup - | 🔍 + i.fa.fa-search div.trigger-text | {{_'r-is-moved'}} div.trigger-button.trigger-button-person.js-show-user-field - | 👤 + i.fa.fa-user div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-gen-moved-trigger.js-goto-action - | ➕ + i.fa.fa-plus div.trigger-item#trigger-four div.trigger-content div.trigger-text | {{_'r-when-a-card'}} div.trigger-inline-button.js-open-card-title-popup - | 🔍 + i.fa.fa-search div.trigger-text | {{_'r-is'}} div.trigger-dropdown @@ -66,21 +66,21 @@ template(name="boardTriggers") div.trigger-dropdown input(id="create-swimlane-name-2",type=text,placeholder="{{_'r-swimlane-name'}}") div.trigger-button.trigger-button-person.js-show-user-field - | 👤 + i.fa.fa-user div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-moved-trigger.js-goto-action - | ➕ + i.fa.fa-plus div.trigger-item#trigger-five div.trigger-content div.trigger-text | {{_'r-when-a-card'}} div.trigger-inline-button.js-open-card-title-popup - | 🔍 + i.fa.fa-search div.trigger-text | {{_'r-is'}} div.trigger-dropdown @@ -88,14 +88,14 @@ template(name="boardTriggers") option(value="archived") {{_'r-archived'}} option(value="unarchived") {{_'r-unarchived'}} div.trigger-button.trigger-button-person.js-show-user-field - | 👤 + i.fa.fa-user div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-arch-trigger.js-goto-action - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content diff --git a/client/components/rules/triggers/cardTriggers.jade b/client/components/rules/triggers/cardTriggers.jade index 60c024452..ba4276a51 100644 --- a/client/components/rules/triggers/cardTriggers.jade +++ b/client/components/rules/triggers/cardTriggers.jade @@ -10,14 +10,14 @@ template(name="cardTriggers") div.trigger-text | {{_'r-a-card'}} div.trigger-button.trigger-button-person.js-show-user-field - | 👤 + i.fa.fa-user div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-gen-label-trigger.js-goto-action - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content @@ -37,14 +37,14 @@ template(name="cardTriggers") div.trigger-text | {{_'r-a-card'}} div.trigger-button.trigger-button-person.js-show-user-field - | 👤 + i.fa.fa-user div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-spec-label-trigger.js-goto-action - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content @@ -57,14 +57,14 @@ template(name="cardTriggers") div.trigger-text | {{_'r-a-card'}} div.trigger-button.trigger-button-person.js-show-user-field - | 👤 + i.fa.fa-user div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-gen-member-trigger.js-goto-action - | ➕ + i.fa.fa-plus div.trigger-item @@ -82,14 +82,14 @@ template(name="cardTriggers") div.trigger-text | {{_'r-a-card'}} div.trigger-button.trigger-button-person.js-show-user-field - | 👤 + i.fa.fa-user div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-spec-member-trigger.js-goto-action - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content @@ -104,11 +104,11 @@ template(name="cardTriggers") div.trigger-text | {{_'r-a-card'}} div.trigger-button.trigger-button-person.js-show-user-field - | 👤 + i.fa.fa-user div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-attachment-trigger.js-goto-action - | ➕ + i.fa.fa-plus diff --git a/client/components/rules/triggers/checklistTriggers.jade b/client/components/rules/triggers/checklistTriggers.jade index b6c16f1de..841ec6f7d 100644 --- a/client/components/rules/triggers/checklistTriggers.jade +++ b/client/components/rules/triggers/checklistTriggers.jade @@ -10,14 +10,14 @@ template(name="checklistTriggers") div.trigger-text | {{_'r-a-card'}} div.trigger-button.trigger-button-person.js-show-user-field - | 👤 + i.fa.fa-user div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-gen-check-trigger.js-goto-action - | ➕ + i.fa.fa-plus div.trigger-item @@ -35,14 +35,14 @@ template(name="checklistTriggers") div.trigger-text | {{_'r-a-card'}} div.trigger-button.trigger-button-person.js-show-user-field - | 👤 + i.fa.fa-user div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-spec-check-trigger.js-goto-action - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content @@ -53,14 +53,14 @@ template(name="checklistTriggers") option(value="completed") {{_'r-completed'}} option(value="uncompleted") {{_'r-made-incomplete'}} div.trigger-button.trigger-button-person.js-show-user-field - | 👤 + i.fa.fa-user div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-gen-comp-trigger.js-goto-action - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content @@ -75,14 +75,14 @@ template(name="checklistTriggers") option(value="completed") {{_'r-completed'}} option(value="uncompleted") {{_'r-made-incomplete'}} div.trigger-button.trigger-button-person.js-show-user-field - | 👤 + i.fa.fa-user div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-spec-comp-trigger.js-goto-action - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content @@ -93,14 +93,14 @@ template(name="checklistTriggers") option(value="checked") {{_'r-checked'}} option(value="unchecked") {{_'r-unchecked'}} div.trigger-button.trigger-button-person.js-show-user-field - | 👤 + i.fa.fa-user div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-gen-check-item-trigger.js-goto-action - | ➕ + i.fa.fa-plus div.trigger-item div.trigger-content @@ -115,11 +115,11 @@ template(name="checklistTriggers") option(value="checked") {{_'r-checked'}} option(value="unchecked") {{_'r-unchecked'}} div.trigger-button.trigger-button-person.js-show-user-field - | 👤 + i.fa.fa-user div.user-details.hide-element div.trigger-text | {{_'r-by'}} div.trigger-dropdown input(class="user-name",type=text,placeholder="{{_'username'}}") div.trigger-button.js-add-spec-check-item-trigger.js-goto-action - | ➕ + i.fa.fa-plus diff --git a/client/components/settings/attachments.jade b/client/components/settings/attachments.jade index 111bd4db8..31a0e219f 100644 --- a/client/components/settings/attachments.jade +++ b/client/components/settings/attachments.jade @@ -8,7 +8,7 @@ template(name="attachments") ul li a.js-move-attachments(data-id="move-attachments") - | ➡️ + i.fa.fa-arrow-right | {{_ 'attachment-move'}} .main-body @@ -80,17 +80,17 @@ template(name="moveAttachment") td if $neq version.storageName "fs" button.js-move-storage-fs - | ➡️ + i.fa.fa-arrow-right | {{_ 'attachment-move-storage-fs'}} if $neq version.storageName "gridfs" if version.storageName button.js-move-storage-gridfs - | ➡️ + i.fa.fa-arrow-right | {{_ 'attachment-move-storage-gridfs'}} if $neq version.storageName "s3" if version.storageName button.js-move-storage-s3 - | ➡️ + i.fa.fa-arrow-right | {{_ 'attachment-move-storage-s3'}} diff --git a/client/components/settings/cronSettings.jade b/client/components/settings/cronSettings.jade index 2d229c8c3..4ff74fa5f 100644 --- a/client/components/settings/cronSettings.jade +++ b/client/components/settings/cronSettings.jade @@ -82,13 +82,13 @@ template(name="cronMigrations") | {{_ 'database-migrations'}} .migration-controls button.btn.btn-primary.js-start-all-migrations - | ▶️ + i.fa.fa-play | {{_ 'start-all-migrations'}} button.btn.btn-warning.js-pause-all-migrations - | ⏸️ + i.fa.fa-pause | {{_ 'pause-all-migrations'}} button.btn.btn-danger.js-stop-all-migrations - | ⏹️ + i.fa.fa-stop | {{_ 'stop-all-migrations'}} .migration-progress @@ -99,11 +99,11 @@ template(name="cronMigrations") .progress-label {{_ 'overall-progress'}} .current-step - | ⚙️ + i.fa.fa-cog | {{migrationCurrentStep}} .migration-status - | ℹ️ + i.fa.fa-info-circle | {{migrationStatus}} .migration-steps @@ -114,11 +114,11 @@ template(name="cronMigrations") .step-header .step-icon if completed - | ✅ + i.fa.fa-check else if isCurrentStep - | ⚙️ + i.fa.fa-cog else - | ⭕ + i.fa.fa-circle-o .step-info .step-name {{name}} .step-description {{description}} @@ -137,17 +137,17 @@ template(name="cronBoardOperations") .cron-board-operations .board-operations-header h2 - | 📋 + i.fa.fa-list | {{_ 'board-operations'}} .board-operations-controls button.btn.btn-success.js-refresh-board-operations - | 🔄 + i.fa.fa-recycle | {{_ 'refresh'}} button.btn.btn-primary.js-start-test-operation - | ▶️ + i.fa.fa-play | {{_ 'start-test-operation'}} button.btn.btn-info.js-force-board-scan - | 🔍 + i.fa.fa-search | {{_ 'force-board-scan'}} .board-operations-stats @@ -195,7 +195,7 @@ template(name="cronBoardOperations") .board-operations-search .search-box input.form-control.js-search-board-operations(type="text" placeholder="{{_ 'search-boards-or-operations'}}") - | 🔍.search-icon + i.fa.fa-search.search-icon .board-operations-list .operations-header @@ -234,36 +234,36 @@ template(name="cronBoardOperations") .btn-group if isRunning button.btn.btn-sm.btn-warning.js-pause-operation(data-operation="{{id}}") - | ⏸️ + i.fa.fa-pause else button.btn.btn-sm.btn-success.js-resume-operation(data-operation="{{id}}") - | ▶️ + i.fa.fa-play button.btn.btn-sm.btn-danger.js-stop-operation(data-operation="{{id}}") - | ⏹️ + i.fa.fa-stop button.btn.btn-sm.btn-info.js-view-details(data-operation="{{id}}") - | ℹ️ + i.fa.fa-info-circle .pagination if pagination.hasPrev button.btn.btn-sm.btn-default.js-prev-page - | ◀️ + i.fa.fa-caret-left | {{_ 'previous'}} .page-info | {{_ 'page'}} {{pagination.page}} {{_ 'of'}} {{pagination.totalPages}} if pagination.hasNext button.btn.btn-sm.btn-default.js-next-page | {{_ 'next'}} - | ▶️ + i.fa.fa-caret-right template(name="cronJobs") .cron-jobs .jobs-header h2 - | ⏰ + i.fa.fa-clock-o | {{_ 'cron-jobs'}} .jobs-controls button.btn.btn-success.js-refresh-jobs - | 🔄 + i.fa.fa-refresh | {{_ 'refresh'}} .jobs-list @@ -289,20 +289,20 @@ template(name="cronJobs") .btn-group if isRunning button.btn.btn-sm.btn-warning.js-pause-job(data-job="{{name}}") - | ⏸️ + i.fa.fa-pause else button.btn.btn-sm.btn-success.js-start-job(data-job="{{name}}") - | ▶️ + i.fa.fa-caret-right button.btn.btn-sm.btn-danger.js-stop-job(data-job="{{name}}") - | ⏹️ + i.fa.fa-stop button.btn.btn-sm.btn-danger.js-remove-job(data-job="{{name}}") - | 🗑️ + i.fa.fa-trash template(name="cronAddJob") .cron-add-job .add-job-header h2 - | ➕ + i.fa.fa-plus | {{_ 'add-cron-job'}} .add-job-form @@ -333,8 +333,8 @@ template(name="cronAddJob") .form-actions button.btn.btn-primary(type="submit") - | ➕ + i.fa.fa-plus | {{_ 'add-job'}} button.btn.btn-default.js-cancel-add-job - | ❌ + i.fa.fa-times-thin | {{_ 'cancel'}} diff --git a/client/components/settings/informationBody.jade b/client/components/settings/informationBody.jade index 6907ac9d0..6b0265a29 100644 --- a/client/components/settings/informationBody.jade +++ b/client/components/settings/informationBody.jade @@ -5,14 +5,14 @@ template(name='information') else .content-title span - | ℹ️ + i.fa.fa-info-circle | {{_ 'info'}} .content-body .side-menu ul li.active a.js-setting-menu(data-id="information-display") - | ℹ️ + i.fa.fa-info-circle | {{_ 'info'}} .main-body +statistics diff --git a/client/components/settings/migrationProgress.jade b/client/components/settings/migrationProgress.jade index c68a3836a..253317b2b 100644 --- a/client/components/settings/migrationProgress.jade +++ b/client/components/settings/migrationProgress.jade @@ -4,9 +4,10 @@ template(name="migrationProgress") .migration-progress-modal .migration-progress-header h3.migration-progress-title - | 🔄 {{_ 'migration-progress-title'}} + i.fa.fa-recycle + | {{_ 'migration-progress-title'}} .migration-progress-close.js-close-migration-progress - | ❌ + i.fa.fa-times-thin .migration-progress-content .migration-progress-overall diff --git a/client/components/settings/peopleBody.jade b/client/components/settings/peopleBody.jade index 59b4718cc..6b6aef469 100644 --- a/client/components/settings/peopleBody.jade +++ b/client/components/settings/peopleBody.jade @@ -9,34 +9,34 @@ template(name="people") +spinner else if orgSetting.get span - | 🌐 + i.fa.fa-globe unless isMiniScreen | {{_ 'organizations'}} input#searchOrgInput(placeholder="{{_ 'search'}}") button#searchOrgButton - | 🔍 + i.fa.fa-search | {{_ 'search'}} .ext-box-right span {{#unless isMiniScreen}}{{_ 'org-number'}}{{/unless}} #{orgNumber} else if teamSetting.get span - | 👥 + i.fa.fa-users unless isMiniScreen | {{_ 'teams'}} input#searchTeamInput(placeholder="{{_ 'search'}}") button#searchTeamButton - | 🔍 + i.fa.fa-search | {{_ 'search'}} .ext-box-right span {{#unless isMiniScreen}}{{_ 'team-number'}}{{/unless}} #{teamNumber} else if peopleSetting.get span - | 👤 + i.fa.fa-user unless isMiniScreen | {{_ 'people'}} input#searchInput(placeholder="{{_ 'search'}}") button#searchButton - | 🔍 + i.fa.fa-search | {{_ 'search'}} .divLockedUsersFilter .flex-container @@ -48,17 +48,19 @@ template(name="people") option(value="inactive") {{_ 'admin-people-filter-inactive'}} option(value="admin") Admin button#unlockAllUsers.unlock-all-btn - span.emoji-icon 🔓 + span.emoji-icon + i.fa.fa-unlock | {{_ 'accounts-lockout-unlock-all'}} .ext-box-right span {{#unless isMiniScreen}}{{_ 'people-number'}}{{/unless}} #{peopleNumber} .divAddOrRemoveTeam#divAddOrRemoveTeam button#addOrRemoveTeam - | ✏️ + i.fa.fa-pencil-square-o | {{_ 'add'}} / {{_ 'delete'}} {{_ 'teams'}} else if lockedUsersSetting.get span - span.emoji-icon.text-red 🔒 + span.emoji-icon.text-red + i.fa.fa-lock unless isMiniScreen | {{_ 'accounts-lockout-locked-users'}} @@ -67,19 +69,20 @@ template(name="people") ul li.active a.js-org-menu(data-id="org-setting") - | 🌐 + i.fa.fa-globe | {{_ 'organizations'}} li a.js-team-menu(data-id="team-setting") - | 👥 + i.fa.fa-users | {{_ 'teams'}} li a.js-people-menu(data-id="people-setting") - | 👤 + i.fa.fa-user | {{_ 'people'}} li a.js-locked-users-menu(data-id="locked-users-setting") - span.emoji-icon.text-red 🔒 + span.emoji-icon.text-red + i.fa.fa-lock | {{_ 'accounts-lockout-locked-users'}} .main-body if loading.get @@ -155,17 +158,17 @@ template(name="selectAllUser") template(name="newOrgRow") a.new-org - | ➕ + i.fa.fa-plus | {{_ 'new'}} template(name="newTeamRow") a.new-team - | ➕ + i.fa.fa-plus | {{_ 'new'}} template(name="newUserRow") a.new-user - | ➕ + i.fa.fa-plus | {{_ 'new'}} template(name="orgRow") @@ -197,7 +200,7 @@ template(name="orgRow") | {{_ 'no'}} td a.edit-org - | ✏️ + i.fa.fa-pencil-square-o | {{_ 'edit'}} a.more-settings-org | ⋯ @@ -231,7 +234,7 @@ template(name="teamRow") | {{_ 'no'}} td a.edit-team - | ✏️ + i.fa.fa-pencil-square-o | {{_ 'edit'}} a.more-settings-team | ⋯ @@ -240,7 +243,7 @@ template(name="peopleRow") tr td a.edit-user - | ✏️ + i.fa.fa-pencil-square-o | {{_ 'edit'}} a.more-settings-user | ⋯ @@ -268,14 +271,18 @@ template(name="peopleRow") | {{_ 'no'}} td.account-active-status if userData.loginDisabled - span.text-red.js-toggle-active-status(data-user-id=userData._id, data-is-active="false", title="{{_ 'admin-people-user-inactive'}}") 🚫 + span.text-red.js-toggle-active-status(data-user-id=userData._id, data-is-active="false", title="{{_ 'admin-people-user-inactive'}}") + i.fa.fa-ban else - span.text-green.js-toggle-active-status(data-user-id=userData._id, data-is-active="true", title="{{_ 'admin-people-user-active'}}") ✅ + span.text-green.js-toggle-active-status(data-user-id=userData._id, data-is-active="true", title="{{_ 'admin-people-user-active'}}") + i.fa.fa-check td.account-status if isUserLocked - span.text-red.js-toggle-lock-status.emoji-icon(data-user-id=userData._id, data-is-locked="true", title="{{_ 'accounts-lockout-click-to-unlock'}}") 🔒 + span.text-red.js-toggle-lock-status.emoji-icon(data-user-id=userData._id, data-is-locked="true", title="{{_ 'accounts-lockout-click-to-unlock'}}") + i.fa.fa-lock else - span.text-green.js-toggle-lock-status.emoji-icon(data-user-id=userData._id, data-is-locked="false", title="{{_ 'accounts-lockout-user-unlocked'}}") 🔓 + span.text-green.js-toggle-lock-status.emoji-icon(data-user-id=userData._id, data-is-locked="false", title="{{_ 'accounts-lockout-user-unlocked'}}") + i.fa.fa-unlock if userData.loginDisabled td {{ moment userData.createdAt 'LLL' }} else @@ -395,8 +402,10 @@ template(name="editUserPopup") option(value="{{value}}") {{_ value}} label | {{_ 'organizations'}} - span#addUserOrg ➕ - span#removeUserOrg ➖ + span#addUserOrg + i.fa.fa-plus + span#removeUserOrg + i.fa.fa-minus select.js-orgs#jsOrgs option(value="-1") {{_ 'organizations'}} : each value in orgsDatas @@ -405,8 +414,10 @@ template(name="editUserPopup") input#jsUserOrgIdsInPut.js-userOrgIds.hide(type="hidden" value=user.orgIdsUserBelongs) label | {{_ 'teams'}} - span#addUserTeam ➕ - span#removeUserTeam ➖ + span#addUserTeam + i.fa.fa-plus + span#removeUserTeam + i.fa.fa-minus select.js-teams#jsTeams option(value="-1") {{_ 'teams'}} : each value in teamsDatas @@ -538,8 +549,10 @@ template(name="newUserPopup") option(value="{{value}}") {{_ value}} label | {{_ 'organizations'}} - span#addUserOrgNewUser ➕ - span#removeUserOrgNewUser ➖ + span#addUserOrgNewUser + i.fa.fa-plus + span#removeUserOrgNewUser + i.fa.fa-minus select.js-orgsNewUser#jsOrgsNewUser option(value="-1") {{_ 'organizations'}} : each value in orgsDatas @@ -548,8 +561,10 @@ template(name="newUserPopup") input#jsUserOrgIdsInPutNewUser.js-userOrgIdsNewUser.hide(type="text" value=user.orgIdsUserBelongs) label | {{_ 'teams'}} - span#addUserTeamNewUser ➕ - span#removeUserTeamNewUser ➖ + span#addUserTeamNewUser + i.fa.fa-plus + span#removeUserTeamNewUser + i.fa.fa-minus select.js-teamsNewUser#jsTeamsNewUser option(value="-1") {{_ 'teams'}} : each value in teamsDatas @@ -583,7 +598,7 @@ template(name="settingsOrgPopup") // to impersonate organization? // li // a.impersonate-org - // | 👤 + // i.fa.fa-user // | {{_ 'impersonate-org'}} // // @@ -606,7 +621,7 @@ template(name="settingsUserPopup") ul.pop-over-list li a.impersonate-user - | 👤 + i.fa.fa-user | {{_ 'impersonate-user'}} br hr diff --git a/client/components/settings/settingBody.jade b/client/components/settings/settingBody.jade index bcf538b43..5bbbd5179 100644 --- a/client/components/settings/settingBody.jade +++ b/client/components/settings/settingBody.jade @@ -6,87 +6,107 @@ template(name="setting") .content-title.ext-box if isGeneralSetting span - span.emoji-icon 🔑 + span.emoji-icon + i.fa.fa-key | {{_ 'registration'}} else if isEmailSetting span - span.emoji-icon ✉️ + span.emoji-icon + i.fa.fa-envelope | {{_ 'email'}} else if isAccountSetting span - span.emoji-icon 👥 + span.emoji-icon + i.fa.fa-users | {{_ 'accounts'}} else if isTableVisibilityModeSetting span - span.emoji-icon 👁️ + span.emoji-icon + i.fa.fa-eye | {{_ 'tableVisibilityMode'}} else if isAnnouncementSetting span - span.emoji-icon 📢 + span.emoji-icon + i.fa.fa-bullhorn | {{_ 'admin-announcement'}} else if isAccessibilitySetting span - span.emoji-icon ♿ + span.emoji-icon + i.fa.fa-universal-access | {{_ 'accessibility'}} else if isLayoutSetting span - span.emoji-icon 🔗 + span.emoji-icon + i.fa.fa-link | {{_ 'layout'}} else if isWebhookSetting span - span.emoji-icon 🌐 + span.emoji-icon + i.fa.fa-globe | {{_ 'global-webhook'}} else if isAttachmentSettings span - span.emoji-iconpan.emoji-icon 📎 + span.emoji-icon + i.fa.fa-paperclip | {{_ 'attachments'}} else if isCronSettings span - span.emoji-icon ⏰ + span.emoji-icon + i.fa.fa-clock | {{_ 'cron'}} .content-body .side-menu ul li(class="{{#if isGeneralSetting}}active{{/if}}") a.js-setting-menu(data-id="registration-setting") - span.emoji-icon 🔑 + span.emoji-icon + i.fa.fa-key | {{_ 'registration'}} unless isSandstorm li(class="{{#if isEmailSetting}}active{{/if}}") a.js-setting-menu(data-id="email-setting") - span.emoji-icon ✉️ + span.emoji-icon + i.fa.fa-envelope | {{_ 'email'}} li(class="{{#if isAccountSetting}}active{{/if}}") a.js-setting-menu(data-id="account-setting") - span.emoji-icon 👥 + span.emoji-icon + i.fa.fa-users | {{_ 'accounts'}} li(class="{{#if isTableVisibilityModeSetting}}active{{/if}}") a.js-setting-menu(data-id="tableVisibilityMode-setting") - span.emoji-icon 👁️ + span.emoji-icon + i.fa.fa-eye | {{_ 'tableVisibilityMode'}} li(class="{{#if isAnnouncementSetting}}active{{/if}}") a.js-setting-menu(data-id="announcement-setting") - span.emoji-icon 📢 + span.emoji-icon + i.fa.fa-bullhorn | {{_ 'admin-announcement'}} li(class="{{#if isAccessibilitySetting}}active{{/if}}") a.js-setting-menu(data-id="accessibility-setting") - span.emoji-icon ♿ + span.emoji-icon + i.fa.fa-universal-access | {{_ 'accessibility'}} li(class="{{#if isLayoutSetting}}active{{/if}}") a.js-setting-menu(data-id="layout-setting") - span.emoji-icon 🔗 + span.emoji-icon + i.fa.fa-link | {{_ 'layout'}} li(class="{{#if isWebhookSetting}}active{{/if}}") a.js-setting-menu(data-id="webhook-setting") - span.emoji-icon 🌐 + span.emoji-icon + i.fa.fa-globe | {{_ 'global-webhook'}} li(class="{{#if isAttachmentSettings}}active{{/if}}") a.js-setting-menu(data-id="attachment-settings") - span.emoji-icon 📎 + span.emoji-icon + i.fa.fa-paperclip | {{_ 'attachments'}} li(class="{{#if isCronSettings}}active{{/if}}") a.js-setting-menu(data-id="cron-settings") - span.emoji-icon ⏰ + span.emoji-icon + i.fa.fa-clock | {{_ 'cron'}} .main-body if isLoading diff --git a/client/components/settings/settingHeader.jade b/client/components/settings/settingHeader.jade index 9fbc89394..8d554ab94 100644 --- a/client/components/settings/settingHeader.jade +++ b/client/components/settings/settingHeader.jade @@ -5,31 +5,38 @@ template(name="settingHeaderBar") .setting-header-btns.left if currentUser a.setting-header-btn.settings(class=isSettingsActive href="{{pathFor 'setting'}}") - span.emoji-icon ⚙️ + span.emoji-icon + i.fa.fa-cog span {{_ 'settings'}} a.setting-header-btn.people(class=isPeopleActive href="{{pathFor 'people'}}") - span.emoji-icon 👥 + span.emoji-icon + i.fa.fa-users span {{_ 'people'}} a.setting-header-btn.informations(class=isAdminReportsActive href="{{pathFor 'admin-reports'}}") - span.emoji-icon 📋 + span.emoji-icon + i.fa.fa-file-text-o span {{_ 'reports'}} a.setting-header-btn.informations(class=isAttachmentsActive href="{{pathFor 'attachments'}}") - span.emoji-icon 📎 + span.emoji-icon + i.fa.fa-paperclip span {{_ 'attachments'}} a.setting-header-btn.informations(class=isTranslationActive href="{{pathFor 'translation'}}") - span.emoji-icon 🔤 + span.emoji-icon + i.fa.fa-globe span {{_ 'translation'}} a.setting-header-btn.informations(class=isInformationActive href="{{pathFor 'information'}}") - span.emoji-icon ℹ️ + span.emoji-icon + i.fa.fa-info-circle span {{_ 'info'}} else a.setting-header-btn.js-log-in( title="{{_ 'log-in'}}") - span.emoji-icon 🚪 + span.emoji-icon + i.fa.fa-sign-in span {{_ 'log-in'}} diff --git a/client/components/settings/translationBody.jade b/client/components/settings/translationBody.jade index deb721a22..5c19533e2 100644 --- a/client/components/settings/translationBody.jade +++ b/client/components/settings/translationBody.jade @@ -9,12 +9,12 @@ template(name="translation") +spinner else if translationSetting.get span - | 🔤 + i.fa.fa-globe unless isMiniScreen | {{_ 'translation'}} input#searchTranslationInput(placeholder="{{_ 'search'}}") button#searchTranslationButton - | 🔍 + i.fa.fa-search | {{_ 'search'}} .ext-box-right span {{#unless isMiniScreen}}{{_ 'translation-number'}}{{/unless}} #{translationNumber} @@ -24,7 +24,7 @@ template(name="translation") ul li.active a.js-translation-menu(data-id="translation-setting") - | 🔤 + i.fa.fa-globe | {{_ 'translation'}} .main-body if loading.get @@ -47,7 +47,7 @@ template(name="translationGeneral") template(name="newTranslationRow") a.new-translation - | ➕ + i.fa.fa-plus | {{_ 'new'}} template(name="translationRow") @@ -57,7 +57,7 @@ template(name="translationRow") td {{translationData.translationText}} td a.edit-translation - | ✏️ + i.fa.fa-pencil-square-o | {{_ 'edit'}} a.more-settings-translation | ⋯ diff --git a/client/components/sidebar/sidebar.jade b/client/components/sidebar/sidebar.jade index 463a365d7..e3772a9a3 100644 --- a/client/components/sidebar/sidebar.jade +++ b/client/components/sidebar/sidebar.jade @@ -7,14 +7,14 @@ template(name="sidebar") .sidebar-actions .sidebar-shortcuts a.sidebar-btn.js-shortcuts(title="{{_ 'keyboard-shortcuts' }}") - | ⌨️ + i.fa.fa-keyboard-o span {{_ 'keyboard-shortcuts' }} a.sidebar-btn.js-keyboard-shortcuts-toggle( title="{{#if isKeyboardShortcuts}}{{_ 'keyboard-shortcuts-enabled'}}{{else}}{{_ 'keyboard-shortcuts-disabled'}}{{/if}}") - | {{#if isKeyboardShortcuts}}✅{{else}}🚫{{/if}} + i.fa(class="{{#if isKeyboardShortcuts}}fa-check{{else}}fa-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 @@ -22,7 +22,7 @@ template(name="sidebar") // i.fa.fa-navicon unless isDefaultView h2 - a.js-back-home ⬅️ + a.fa.fa-arrow-left.js-back-home = getViewTitle if isOpen +Template.dynamic(template=getViewTemplate) @@ -34,25 +34,25 @@ template(name='homeSidebar') hr ul#cards.label-text-hidden a.flex.js-toggle-minicard-label-text(title="{{_ 'hide-minicard-label-text'}}") - span {{#if hiddenMinicardLabelText}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if hiddenMinicardLabelText}}fa-check{{else}}fa-square-o{{/if}}") span {{_ 'hide-minicard-label-text'}} if currentUser ul#cards.vertical-scrollbars-toggle a.flex.js-vertical-scrollbars-toggle(title="{{_ 'enable-vertical-scrollbars'}}") - span {{#if isVerticalScrollbars}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if isVerticalScrollbars}}fa-check{{else}}fa-square-o{{/if}}") span {{_ 'enable-vertical-scrollbars'}} ul#cards.show-week-of-year-toggle a.flex.js-show-week-of-year-toggle(title="{{_ 'show-week-of-year'}}") - span {{#if isShowWeekOfYear}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if isShowWeekOfYear}}fa-check{{else}}fa-square-o{{/if}}") span {{_ 'show-week-of-year'}} hr if currentUser.isBoardAdmin h3.activity-title - | 💬 + i.fa.fa-comment-o | {{_ 'activities'}} a.flex.js-toggle-show-activities(title="{{_ 'show-activities'}}") - span {{#if showActivities}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if showActivities}}fa-check{{else}}fa-square-o{{/if}}") span {{_ 'show-activities'}} +activities(mode="board") @@ -61,11 +61,11 @@ template(name="membersWidget") unless currentUser.isWorker h3 a.board-header-btn.js-open-board-menu(title="{{_ 'boardMenuPopup-title'}}") - | ⚙️ + i.fa.fa-cog | {{_ 'boardMenuPopup-title'}} hr h3 - | 👥 + i.fa.fa-users | {{_ 'members'}} +basicTabs(tabs=tabs) +tabContent(slug="people") @@ -77,15 +77,15 @@ template(name="membersWidget") if isSandstorm if currentUser.isBoardMember a.member.add-member.sandstorm-powerbox-request-identity(title="{{_ 'add-members'}}") - | ➕ + i.fa.fa-plus else if currentUser.isBoardAdmin a.member.add-member.js-manage-board-members(title="{{_ 'add-members'}}") - | ➕ + i.fa.fa-plus .clearfix if isInvited hr p - | ⚠️ + i.fa.fa-exclamation-triangle | {{_ 'just-invited'}} button.js-member-invite-accept.primary {{_ 'accept'}} button.js-member-invite-decline {{_ 'decline'}} @@ -121,7 +121,7 @@ template(name="boardOrgGeneral") th if currentUser.isBoardAdmin a.member.orgOrTeamMember.add-member.js-manage-board-addOrg(title="{{_ 'add-members'}}") - | ➕ + i.fa.fa-plus .divaddfaplusminus | {{_ 'add'}} each org in currentBoard.activeOrgs @@ -142,7 +142,7 @@ template(name="boardTeamGeneral") th if currentUser.isBoardAdmin a.member.orgOrTeamMember.add-member.js-manage-board-addTeam(title="{{_ 'add-members'}}") - | ➕ + i.fa.fa-plus .divaddfaplusminus | {{_ 'add'}} each currentBoard.activeTeams @@ -155,7 +155,7 @@ template(name="boardChangeColorPopup") span.background-box(class="board-color-{{this}}") span {{this}} if isSelected - span.checkmark-no-grey ✅ + i.fa.fa-check template(name="boardChangeBackgroundImagePopup") form @@ -179,16 +179,16 @@ template(name="boardInfoOnMyBoardsPopup") unless currentSetting.hideCardCounterList div.check-div a.flex.js-field-has-cardcounterlist(class="{{#if allowsCardCounterList}}is-checked{{/if}}") - span {{#if allowsCardCounterList}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsCardCounterList}}fa-check{{else}}fa-square-o{{/if}}") span - | 🚪 + i.fa.fa-sign-in | {{_ 'show-card-counter-per-list'}} unless currentSetting.hideBoardMemberList div.check-div a.flex.js-field-has-boardmemberlist(class="{{#if allowsBoardMemberList}}is-checked{{/if}}") - span {{#if allowsBoardMemberList}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsBoardMemberList}}fa-check{{else}}fa-square-o{{/if}}") span - | ⏳ + i.fa.fa-hourglass | {{_ 'show-board_members-avatar'}} template(name="boardCardSettingsPopup") @@ -203,169 +203,170 @@ template(name="boardCardSettingsPopup") .card-settings-row .card-settings-column a.flex.js-field-has-receiveddate(title="{{_ 'card-received'}}" class="{{#if allowsReceivedDate}}is-checked{{/if}}") - span {{#if allowsReceivedDate}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsReceivedDate}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column a.flex.js-field-has-receiveddate(title="{{_ 'card-received'}}" class="{{#if allowsReceivedDate}}is-checked{{/if}}") - span {{#if allowsReceivedDate}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsReceivedDate}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | 🚪 + i.fa.fa-sign-in | {{_ 'card-received'}} .card-settings-row .card-settings-column a.flex.js-field-has-startdate(title="{{_ 'card-start'}}" class="{{#if allowsStartDate}}is-checked{{/if}}") - span {{#if allowsStartDate}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsStartDate}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column a.flex.js-field-has-startdate(title="{{_ 'card-start'}}" class="{{#if allowsStartDate}}is-checked{{/if}}") - span {{#if allowsStartDate}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsStartDate}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | ⏳ + i.fa.fa-hourglass | {{_ 'card-start'}} .card-settings-row .card-settings-column a.flex.js-field-has-duedate(title="{{_ 'card-due'}}" class="{{#if allowsDueDate}}is-checked{{/if}}") - span {{#if allowsDueDate}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsDueDate}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column a.flex.js-field-has-duedate(title="{{_ 'card-due'}}" class="{{#if allowsDueDate}}is-checked{{/if}}") - span {{#if allowsDueDate}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsDueDate}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | 🚪 + i.fa.fa-sign-in | {{_ 'card-due'}} .card-settings-row .card-settings-column a.flex.js-field-has-enddate(title="{{_ 'card-end'}}" class="{{#if allowsEndDate}}is-checked{{/if}}") - span {{#if allowsEndDate}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsEndDate}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column a.flex.js-field-has-enddate(title="{{_ 'card-end'}}" class="{{#if allowsEndDate}}is-checked{{/if}}") - span {{#if allowsEndDate}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsEndDate}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | ⏰ + i.fa.fa-clock-o | {{_ 'card-end'}} .card-settings-row .card-settings-column a.flex.js-field-has-members(title="{{_ 'members'}}" class="{{#if allowsMembers}}is-checked{{/if}}") - span {{#if allowsMembers}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsMembers}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column a.flex.js-field-has-members(title="{{_ 'members'}}" class="{{#if allowsMembers}}is-checked{{/if}}") - span {{#if allowsMembers}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsMembers}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | 👥 + i.fa.fa-users | {{_ 'members'}} .card-settings-row .card-settings-column a.flex.js-field-has-creator(title="{{_ 'creator'}}" class="{{#if allowsCreator}}is-checked{{/if}}") - span {{#if allowsCreator}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsCreator}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span .card-settings-column span - | 👤 + i.fa.fa-user | {{_ 'creator'}} .card-settings-row .card-settings-column span .card-settings-column a.flex.js-field-has-creator-on-minicard(title="{{_ 'creator-on-minicard'}}" class="{{#if allowsCreatorOnMinicard}}is-checked{{/if}}") - span {{#if allowsCreatorOnMinicard}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsCreatorOnMinicard}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | 👤 + i.fa.fa-user | {{_ 'creator-on-minicard'}} .card-settings-row .card-settings-column a.flex.js-field-has-assignee(title="{{_ 'assignee'}}" class="{{#if allowsAssignee}}is-checked{{/if}}") - span {{#if allowsAssignee}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsAssignee}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column a.flex.js-field-has-assignee(title="{{_ 'assignee'}}" class="{{#if allowsAssignee}}is-checked{{/if}}") - span {{#if allowsAssignee}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsAssignee}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | 👤 + i.fa.fa-user | {{_ 'assignee'}} .card-settings-row .card-settings-column a.flex.js-field-has-assigned-by(title="{{_ 'assigned-by'}}" class="{{#if allowsAssignedBy}}is-checked{{/if}}") - span {{#if allowsAssignedBy}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsAssignedBy}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column a.flex.js-field-has-assigned-by(title="{{_ 'assigned-by'}}" class="{{#if allowsAssignedBy}}is-checked{{/if}}") - span {{#if allowsAssignedBy}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsAssignedBy}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | 🛒 + i.fa.fa-shopping-cart | {{_ 'assigned-by'}} .card-settings-row .card-settings-column a.flex.js-field-has-requested-by(title="{{_ 'requested-by'}}" class="{{#if allowsRequestedBy}}is-checked{{/if}}") - span {{#if allowsRequestedBy}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsRequestedBy}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column a.flex.js-field-has-requested-by(title="{{_ 'requested-by'}}" class="{{#if allowsRequestedBy}}is-checked{{/if}}") - span {{#if allowsRequestedBy}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsRequestedBy}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | 👤➕ + i.fa.fa-user + | ➕ | {{_ 'requested-by'}} .card-settings-row .card-settings-column a.flex.js-field-has-card-sorting-by-number(title="{{_ 'card-sorting-by-number'}}" class="{{#if allowsCardSortingByNumber}}is-checked{{/if}}") - span {{#if allowsCardSortingByNumber}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsCardSortingByNumber}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span .card-settings-column span - | 🔢 + i.fa.fa-sort-numeric-asc | {{_ 'card-sorting-by-number'}} .card-settings-row .card-settings-column span .card-settings-column a.flex.js-field-has-card-sorting-by-number-on-minicard(title="{{_ 'card-sorting-by-number-on-minicard'}}" class="{{#if allowsCardSortingByNumberOnMinicard}}is-checked{{/if}}") - span {{#if allowsCardSortingByNumberOnMinicard}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsCardSortingByNumberOnMinicard}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | 🔢 + i.fa.fa-sort-numeric-asc | {{_ 'card-sorting-by-number-on-minicard'}} .card-settings-row .card-settings-column a.flex.js-field-has-card-show-lists(title="{{_ 'card-show-lists'}}" class="{{#if allowsShowLists}}is-checked{{/if}}") - span {{#if allowsShowLists}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsShowLists}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span .card-settings-column span - | 📋 + i.fa.fa-list | {{_ 'card-show-lists'}} .card-settings-row .card-settings-column a.flex.js-field-has-labels(title="{{_ 'labels'}}" class="{{#if allowsLabels}}is-checked{{/if}}") - span {{#if allowsLabels}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsLabels}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column a.flex.js-field-has-labels(title="{{_ 'labels'}}" class="{{#if allowsLabels}}is-checked{{/if}}") - span {{#if allowsLabels}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsLabels}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | 🏷️ + i.fa.fa-tag | {{_ 'labels'}} .card-settings-row .card-settings-column span .card-settings-column a.flex.js-field-has-card-show-lists-on-minicard(title="{{_ 'card-show-lists-on-minicard'}}" class="{{#if allowsShowListsOnMinicard}}is-checked{{/if}}") - span {{#if allowsShowListsOnMinicard}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsShowListsOnMinicard}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | 📋 + i.fa.fa-list | {{_ 'card-show-lists-on-minicard'}} .card-settings-row .card-settings-column a.flex.js-field-has-card-number(title="{{_ 'card'}} {{_ 'number'}}" class="{{#if allowsCardNumber}}is-checked{{/if}}") - span {{#if allowsCardNumber}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsCardNumber}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column a.flex.js-field-has-card-number(title="{{_ 'card'}} {{_ 'number'}}" class="{{#if allowsCardNumber}}is-checked{{/if}}") - span {{#if allowsCardNumber}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsCardNumber}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span | #️⃣ @@ -374,25 +375,25 @@ template(name="boardCardSettingsPopup") .card-settings-row .card-settings-column a.flex.js-field-has-description-title(title="{{_ 'description'}} {{_ 'title'}}" class="{{#if allowsDescriptionTitle}}is-checked{{/if}}") - span {{#if allowsDescriptionTitle}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsDescriptionTitle}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column a.flex.js-field-has-description-title(title="{{_ 'description'}} {{_ 'title'}}" class="{{#if allowsDescriptionTitle}}is-checked{{/if}}") - span {{#if allowsDescriptionTitle}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsDescriptionTitle}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | 📝 + i.fa.fa-file-text-o | {{_ 'description'}} | {{_ 'title'}} .card-settings-row .card-settings-column a.flex.js-field-has-description-text(title="{{_ 'description'}} {{_ 'custom-field-text'}}" class="{{#if allowsDescriptionText}}is-checked{{/if}}") - span {{#if allowsDescriptionText}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsDescriptionText}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column a.flex.js-field-has-description-text(title="{{_ 'description'}} {{_ 'custom-field-text'}}" class="{{#if allowsDescriptionText}}is-checked{{/if}}") - span {{#if allowsDescriptionText}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsDescriptionText}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | 📝 + i.fa.fa-file-text-o | {{_ 'description'}} | {{_ 'custom-field-text'}} .card-settings-row @@ -400,64 +401,63 @@ template(name="boardCardSettingsPopup") span .card-settings-column a.flex.js-field-has-description-text-on-minicard(title="{{_ 'description-on-minicard'}}" class="{{#if allowsDescriptionTextOnMinicard}}is-checked{{/if}}") - span {{#if allowsDescriptionTextOnMinicard}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsDescriptionTextOnMinicard}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | 📝 + i.fa.fa-file-text-o | {{_ 'description-on-minicard'}} .card-settings-row .card-settings-column a.flex.js-field-has-checklists(title="{{_ 'checklists'}}" class="{{#if allowsChecklists}}is-checked{{/if}}") - span {{#if allowsChecklists}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsChecklists}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column a.flex.js-field-has-checklists(title="{{_ 'checklists'}}" class="{{#if allowsChecklists}}is-checked{{/if}}") - span {{#if allowsChecklists}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsChecklists}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | ✅ + i.fa.fa-check | {{_ 'checklists'}} .card-settings-row .card-settings-column a.flex.js-field-has-subtasks(title="{{_ 'subtasks'}}" class="{{#if allowsSubtasks}}is-checked{{/if}}") - span {{#if allowsSubtasks}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsSubtasks}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column a.flex.js-field-has-subtasks(title="{{_ 'subtasks'}}" class="{{#if allowsSubtasks}}is-checked{{/if}}") - span {{#if allowsSubtasks}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsSubtasks}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | 🌐 + i.fa.fa-globe | {{_ 'subtasks'}} .card-settings-row .card-settings-column a.flex.js-field-has-attachments(title="{{_ 'attachments'}}" class="{{#if allowsAttachments}}is-checked{{/if}}") - span {{#if allowsAttachments}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsAttachments}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column a.flex.js-field-has-attachments(title="{{_ 'attachments'}}" class="{{#if allowsAttachments}}is-checked{{/if}}") - span {{#if allowsAttachments}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsAttachments}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | 📎 + i.fa.fa-paperclip | {{_ 'attachments'}} .card-settings-row .card-settings-column span .card-settings-column a.flex.js-field-has-badge-attachment-on-minicard(title="{{_ 'badge-attachment-on-minicard'}}" class="{{#if allowsBadgeAttachmentOnMinicard}}is-checked{{/if}}") - span {{#if allowsBadgeAttachmentOnMinicard}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsBadgeAttachmentOnMinicard}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | 📎 + i.fa.fa-paperclip | {{_ 'badge-attachment-on-minicard'}} .card-settings-row .card-settings-column span .card-settings-column a.flex.js-field-has-cover-attachment-on-minicard(title="{{_ 'cover-attachment-on-minicard'}}" class="{{#if allowsCoverAttachmentOnMinicard}}is-checked{{/if}}") - span {{#if allowsCoverAttachmentOnMinicard}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsCoverAttachmentOnMinicard}}fa-check{{else}}fa-square-o{{/if}}") .card-settings-column span - | 📖 - | 🖼️ + i.fa.fa-picture-o | {{_ 'cover-attachment-on-minicard'}} //div.check-div // a.flex.js-field-has-comments(class="{{#if allowsComments}}is-checked{{/if}}") @@ -476,26 +476,26 @@ template(name="boardSubtaskSettingsPopup") form.board-subtask-settings h3 {{_ 'show-parent-in-minicard'}} a#prefix-with-full-path.flex.js-field-show-parent-in-minicard(title="{{_ 'prefix-with-full-path'}}" class="{{#if $eq presentParentTask 'prefix-with-full-path'}}is-checked{{/if}}") - span {{#if $eq presentParentTask 'prefix-with-full-path'}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if $eq presentParentTask 'prefix-with-full-path'}}fa-check{{else}}fa-square-o{{/if}}") span {{_ 'prefix-with-full-path'}} a#prefix-with-parent.flex.js-field-show-parent-in-minicard(title="{{_ 'prefix-with-parent'}}" class="{{#if $eq presentParentTask 'prefix-with-parent'}}is-checked{{/if}}") - span {{#if $eq presentParentTask 'prefix-with-parent'}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if $eq presentParentTask 'prefix-with-parent'}}fa-check{{else}}fa-square-o{{/if}}") span {{_ 'prefix-with-parent'}} a#subtext-with-full-path.flex.js-field-show-parent-in-minicard(title="{{_ 'subtext-with-full-path'}}" class="{{#if $eq presentParentTask 'subtext-with-full-path'}}is-checked{{/if}}") - span {{#if $eq presentParentTask 'subtext-with-full-path'}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if $eq presentParentTask 'subtext-with-full-path'}}fa-check{{else}}fa-square-o{{/if}}") span {{_ 'subtext-with-full-path'}} a#subtext-with-parent.flex.js-field-show-parent-in-minicard(title="{{_ 'subtext-with-parent'}}" class="{{#if $eq presentParentTask 'subtext-with-parent'}}is-checked{{/if}}") - span {{#if $eq presentParentTask 'subtext-with-parent'}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if $eq presentParentTask 'subtext-with-parent'}}fa-check{{else}}fa-square-o{{/if}}") span {{_ 'subtext-with-parent'}} a#no-parent.flex.js-field-show-parent-in-minicard(title="{{_ 'no-parent'}}" class="{{#if $eq presentParentTask 'no-parent'}}is-checked{{/if}}") - span {{#if $eq presentParentTask 'no-parent'}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if $eq presentParentTask 'no-parent'}}fa-check{{else}}fa-square-o{{/if}}") span {{_ 'no-parent'}} div hr div.check-div a.flex.js-field-has-subtasks(title="{{_ 'show-subtasks-field'}}" class="{{#if allowsSubtasks}}is-checked{{/if}}") - span {{#if allowsSubtasks}}✅{{else}}⬜{{/if}} + i.fa(class="{{#if allowsSubtasks}}fa-check{{else}}fa-square-o{{/if}}") span {{_ 'show-subtasks-field'}} label @@ -534,20 +534,20 @@ template(name="chooseBoardSource") template(name="archiveBoardPopup") p {{_ 'close-board-pop'}} button.js-confirm.negate.full(type="submit") - | 📦 + i.fa.fa-archive | {{_ 'archive'}} template(name="deleteDuplicateListsPopup") p {{_ 'delete-duplicate-lists-confirm'}} button.js-confirm.negate.full(type="submit") - | 🗑️ + i.fa.fa-trash | {{_ 'delete'}} template(name="outgoingWebhooksPopup") each integrations form.integration-form a.flex - span {{#unless enabled}}✅{{else}}⬜{{/unless}} + i.fa(class="{{#unless enabled}}fa-check{{else}}fa-square-o{{/unless}}") span {{_ 'disable-webhook'}} input.js-outgoing-webhooks-title(placeholder="{{_ 'webhook-title'}}" type="text" name="title" value=title) input.js-outgoing-webhooks-url(type="text" name="url" value=url) @@ -575,26 +575,25 @@ template(name="boardMenuPopup") if currentUser.isBoardAdmin li a.js-open-rules-view(title="{{_ 'rules'}}") - span.emoji-icon - | ✨ + i.fa.fa-magic | {{_ 'rules'}} if currentUser.isBoardAdmin li a.js-custom-fields - | 📝 + i.fa.fa-file-text-o | {{_ 'custom-fields'}} li a.js-open-archives - | 📦 + i.fa.fa-archive | {{_ 'archived-items'}} if currentUser.isBoardAdmin li a.js-change-board-color - | 🎨 + i.fa.fa-paint-brush | {{_ 'board-change-color'}} li a.js-change-background-image - | 🖼️ + i.fa.fa-picture-o | {{_ 'board-change-background-image'}} //Bug Board icons random dance https://github.com/wekan/wekan/issues/4214 //if currentUser.isBoardAdmin @@ -609,20 +608,20 @@ template(name="boardMenuPopup") if withApi li a.js-export-board - | 📤 + i.fa.fa-upload | {{_ 'export-board'}} if currentUser.isBoardAdmin li a.js-outgoing-webhooks - | 🌐 + i.fa.fa-globe | {{_ 'outgoing-webhooks'}} li a.js-card-settings - | 🃏 + i.fa.fa-id-card | {{_ 'card-settings'}} li a.js-subtask-settings - | 🌐 + i.fa.fa-globe | {{_ 'subtask-settings'}} unless currentBoard.isTemplatesBoard if currentUser.isBoardAdmin @@ -634,41 +633,40 @@ template(name="boardMenuPopup") // | {{_ 'delete-duplicate-lists'}} li a.js-archive-board - span.emoji-icon - | ➡️📦 + i.fa.fa-archive | {{_ 'archive-board'}} template(name="exportBoard") ul.pop-over-list li a.download-json-link(href="{{exportUrl}}", download="{{exportJsonFilename}}") - | 📤 + i.fa.fa-upload | {{_ 'export-board-json'}} li a(href="{{exportUrlExcel}}", download="{{exportFilenameExcel}}") - | 📤 + i.fa.fa-upload | {{_ 'export-board-excel'}} li a(href="{{exportCsvUrl}}", download="{{exportCsvFilename}}") - | 📤 + i.fa.fa-upload | {{_ 'export-board-csv'}} , li a(href="{{exportScsvUrl}}", download="{{exportCsvFilename}}") - | 📤 + i.fa.fa-upload | {{_ 'export-board-csv'}} ; li a(href="{{exportTsvUrl}}", download="{{exportTsvFilename}}") - | 📤 + i.fa.fa-upload | {{_ 'export-board-tsv'}} li a.html-export-board - | 📦 + i.fa.fa-archive | {{_ 'export-board-html'}} template(name="labelsWidget") .board-widget.board-widget-labels h3 - | 🏷️ + i.fa.fa-tag | {{_ 'labels'}} .board-widget-content each currentBoard.labels @@ -679,7 +677,7 @@ template(name="labelsWidget") = name if currentUser.isBoardAdmin a.card-label.add-label.js-add-label(title="{{_ 'label-create'}}") - | ➕ + i.fa.fa-plus template(name="memberPopup") .board-member-menu @@ -691,7 +689,7 @@ template(name="memberPopup") p.quiet @#{user.username} if isInvited p - | ⚠️ + i.fa.fa-exclamation-triangle | {{_ 'not-accepted-yet'}} ul.pop-over-list @@ -789,55 +787,55 @@ template(name="changePermissionsPopup") a(class="{{#if isLastAdmin}}disabled{{else}}js-set-admin{{/if}}") | {{_ 'admin'}} if isAdmin - | ✅ + i.fa.fa-check span.sub-name {{_ 'admin-desc'}} li a(class="{{#if isLastAdmin}}disabled{{else}}js-set-normal{{/if}}") | {{_ 'normal'}} if isNormal - | ✅ + i.fa.fa-check span.sub-name {{_ 'normal-desc'}} li a(class="{{#if isLastAdmin}}disabled{{else}}js-set-normal-assigned-only{{/if}}") | {{_ 'normal-assigned-only'}} if isNormalAssignedOnly - | ✅ + i.fa.fa-check span.sub-name {{_ 'normal-assigned-only-desc'}} li a(class="{{#if isLastAdmin}}disabled{{else}}js-set-no-comments{{/if}}") | {{_ 'no-comments'}} if isNoComments - | ✅ + i.fa.fa-check span.sub-name {{_ 'no-comments-desc'}} li a(class="{{#if isLastAdmin}}disabled{{else}}js-set-comment-only{{/if}}") | {{_ 'comment-only'}} if isCommentOnly - | ✅ + i.fa.fa-check span.sub-name {{_ 'comment-only-desc'}} li a(class="{{#if isLastAdmin}}disabled{{else}}js-set-comment-assigned-only{{/if}}") | {{_ 'comment-assigned-only'}} if isCommentAssignedOnly - | ✅ + i.fa.fa-check span.sub-name {{_ 'comment-assigned-only-desc'}} li a(class="{{#if isLastAdmin}}disabled{{else}}js-set-worker{{/if}}") | {{_ 'worker'}} if isWorker - | ✅ + i.fa.fa-check span.sub-name {{_ 'worker-desc'}} li a(class="{{#if isLastAdmin}}disabled{{else}}js-set-read-only{{/if}}") | {{_ 'read-only'}} if isReadOnly - | ✅ + i.fa.fa-check span.sub-name {{_ 'read-only-desc'}} li a(class="{{#if isLastAdmin}}disabled{{else}}js-set-read-assigned-only{{/if}}") | {{_ 'read-assigned-only'}} if isReadAssignedOnly - | ✅ + i.fa.fa-check span.sub-name {{_ 'read-assigned-only-desc'}} if isLastAdmin hr diff --git a/client/components/sidebar/sidebarCustomFields.jade b/client/components/sidebar/sidebarCustomFields.jade index 0d16559f8..d8df8e157 100644 --- a/client/components/sidebar/sidebarCustomFields.jade +++ b/client/components/sidebar/sidebarCustomFields.jade @@ -14,7 +14,7 @@ template(name="customFieldsSidebar") if currentUser.isBoardMember hr a.sidebar-btn.js-open-create-custom-field - | ➕ + i.fa.fa-plus span {{_ 'createCustomField'}} template(name="createCustomFieldPopup") diff --git a/client/components/sidebar/sidebarFilters.jade b/client/components/sidebar/sidebarFilters.jade index 9e091322e..069e759eb 100644 --- a/client/components/sidebar/sidebarFilters.jade +++ b/client/components/sidebar/sidebarFilters.jade @@ -5,19 +5,19 @@ template(name="filterSidebar") h3 - | 📋 + i.fa.fa-list | {{_ 'list-filter-label'}} ul.sidebar-list form.js-list-filter input(type="text") hr h3 - | 📋 + i.fa.fa-list | {{_ 'filter-card-title-label'}} input.js-field-card-filter(type="text") hr h3 - | 🏷️ + i.fa.fa-tag | {{_ 'filter-labels-label'}} ul.sidebar-list li(class="{{#if Filter.labelIds.isSelected undefined}}active{{/if}}") @@ -25,7 +25,7 @@ template(name="filterSidebar") span.sidebar-list-item-description | {{_ 'filter-no-label'}} if Filter.labelIds.isSelected undefined - | ✅ + i.fa.fa-check each currentBoard.labels li a.name.js-toggle-label-filter @@ -36,10 +36,10 @@ template(name="filterSidebar") else span.quiet {{_ "label-default" (_ (concat "color-" color))}} if Filter.labelIds.isSelected _id - | ✅ + i.fa.fa-check hr h3 - | 👥 + i.fa.fa-users | {{_ 'filter-member-label'}} ul.sidebar-list li(class="{{#if Filter.members.isSelected undefined}}active{{/if}}") @@ -47,7 +47,7 @@ template(name="filterSidebar") span.sidebar-list-item-description | {{_ 'filter-no-member'}} if Filter.members.isSelected undefined - | ✅ + i.fa.fa-check each currentBoard.activeMembers with getUser userId li(class="{{#if Filter.members.isSelected _id}}active{{/if}}") @@ -57,10 +57,9 @@ template(name="filterSidebar") = profile.fullname | ({{ username }}) if Filter.members.isSelected _id - | ✅ - hr + i.fa.fa-check hr h3 - | 👤 + i.fa.fa-user | {{_ 'filter-assignee-label'}} ul.sidebar-list li(class="{{#if Filter.assignees.isSelected undefined}}active{{/if}}") @@ -68,7 +67,7 @@ template(name="filterSidebar") span.sidebar-list-item-description | {{_ 'filter-no-assignee'}} if Filter.assignees.isSelected undefined - | ✅ + i.fa.fa-check each currentBoard.activeMembers with getUser userId li(class="{{#if Filter.assignees.isSelected _id}}active{{/if}}") @@ -78,11 +77,10 @@ template(name="filterSidebar") = profile.fullname | ({{ username }}) if Filter.assignees.isSelected _id - | ✅ - + i.fa.fa-check hr h3 - | 📅 + i.fa.fa-calendar | {{_ 'filter-dates-label' }} ul.sidebar-list li(class="{{#if Filter.dueAt.isSelected 'noDate'}}active{{/if}}") @@ -90,40 +88,40 @@ template(name="filterSidebar") span.sidebar-list-item-description | {{_ 'filter-no-due-date' }} if Filter.dueAt.isSelected 'noDate' - | ✅ + i.fa.fa-check li(class="{{#if Filter.dueAt.isSelected 'past'}}active{{/if}}") a.name.js-toggle-overdue-filter span.sidebar-list-item-description | {{_ 'filter-overdue' }} if Filter.dueAt.isSelected 'past' - | ✅ + i.fa.fa-check li(class="{{#if Filter.dueAt.isSelected 'today'}}active{{/if}}") a.name.js-toggle-due-today-filter span.sidebar-list-item-description | {{_ 'filter-due-today' }} if Filter.dueAt.isSelected 'today' - | ✅ + i.fa.fa-check li(class="{{#if Filter.dueAt.isSelected 'tomorrow'}}active{{/if}}") a.name.js-toggle-due-tomorrow-filter span.sidebar-list-item-description | {{_ 'filter-due-tomorrow' }} if Filter.dueAt.isSelected 'tomorrow' - | ✅ + i.fa.fa-check li(class="{{#if Filter.dueAt.isSelected 'thisweek'}}active{{/if}}") a.name.js-toggle-due-this-week-filter span.sidebar-list-item-description | {{_ 'filter-due-this-week' }} if Filter.dueAt.isSelected 'thisweek' - | ✅ + i.fa.fa-check li(class="{{#if Filter.dueAt.isSelected 'nextweek'}}active{{/if}}") a.name.js-toggle-due-next-week-filter span.sidebar-list-item-description | {{_ 'filter-due-next-week' }} if Filter.dueAt.isSelected 'nextweek' - | ✅ + i.fa.fa-check hr h3 - | 📋 + i.fa.fa-list | {{_ 'filter-custom-fields-label'}} ul.sidebar-list li(class="{{#if Filter.customFields.isSelected undefined}}active{{/if}}") @@ -131,14 +129,14 @@ template(name="filterSidebar") span.sidebar-list-item-description | {{_ 'filter-no-custom-fields'}} if Filter.customFields.isSelected undefined - | ✅ + i.fa.fa-check each currentBoard.customFields li(class="{{#if Filter.customFields.isSelected _id}}active{{/if}}") a.name.js-toggle-custom-fields-filter span.sidebar-list-item-description | {{ name }} if Filter.customFields.isSelected _id - | ✅ + i.fa.fa-check hr h3 | {{_ 'other-filters-label'}} @@ -148,14 +146,14 @@ template(name="filterSidebar") span.sidebar-list-item-description | {{_ 'filter-show-archive'}} if Filter.archive.isSelected _id - | ✅ + i.fa.fa-check ul.sidebar-list li(class="{{#if Filter.hideEmpty.isSelected _id}}active{{/if}}") a.name.js-toggle-hideEmpty-filter span.sidebar-list-item-description | {{_ 'filter-hide-empty'}} if Filter.hideEmpty.isSelected _id - | ✅ + i.fa.fa-check hr h3 {{_ 'advanced-filter-label'}} input.js-field-advanced-filter(type="text") @@ -163,15 +161,15 @@ template(name="filterSidebar") if Filter.isActive hr a.sidebar-btn.js-clear-all - | 🔍 + i.fa.fa-search span {{_ 'filter-clear'}} a.sidebar-btn.js-filter-to-selection - | ☑️ + i.fa.fa-check span {{_ 'filter-to-selection'}} template(name="multiselectionSidebar") h3 - | 🏷️ + i.fa.fa-tag | {{_ 'multi-selection-label'}} ul.sidebar-list each currentBoard.labels @@ -184,12 +182,12 @@ template(name="multiselectionSidebar") else span.quiet {{_ "label-default" (_ (concat "color-" color))}} if allSelectedElementHave 'label' _id - | ✅ + i.fa.fa-check else if someSelectedElementHave 'label' _id | ⋯ hr h3 - | 👥 + i.fa.fa-users | {{_ 'multi-selection-member'}} ul.sidebar-list each currentBoard.activeMembers @@ -201,22 +199,22 @@ template(name="multiselectionSidebar") = profile.fullname | ({{ username }}) if allSelectedElementHave 'member' _id - | ✅ + i.fa.fa-check else if someSelectedElementHave 'member' _id | ⋯ if currentUser.isBoardAdmin hr a.sidebar-btn.js-selection-color - | 🎨 + i.fa.fa-paint-brush span {{_ 'selection-color'}} a.sidebar-btn.js-copy-selection - | 📋 + i.fa.fa-clipboard span {{_ 'copy-selection'}} a.sidebar-btn.js-move-selection - | 📤 + i.fa.fa-upload span {{_ 'move-selection'}} a.sidebar-btn.js-archive-selection - | 📦 + i.fa.fa-archive span {{_ 'archive-selection'}} template(name="disambiguateMultiLabelPopup") @@ -300,6 +298,6 @@ template(name="setSelectionColorPopup") unless $eq color 'white' span.card-label.palette-color.js-palette-color(class="card-details-{{color}}") if(isSelected color) - | ✅ + i.fa.fa-check button.primary.confirm.js-submit {{_ 'save'}} button.js-remove-color.negate.wide.right {{_ 'unset-color'}} diff --git a/client/components/swimlanes/miniswimlane.jade b/client/components/swimlanes/miniswimlane.jade index 890187795..fda17c8ca 100644 --- a/client/components/swimlanes/miniswimlane.jade +++ b/client/components/swimlanes/miniswimlane.jade @@ -3,6 +3,6 @@ template(name="miniswimlane") class="minicard-{{colorClass}}") .minicard-title .handle - | ↕️ + i.fa.fa-arrows +viewer = title diff --git a/client/components/swimlanes/swimlaneHeader.jade b/client/components/swimlanes/swimlaneHeader.jade index 6cfa52150..b7b6988b0 100644 --- a/client/components/swimlanes/swimlaneHeader.jade +++ b/client/components/swimlanes/swimlaneHeader.jade @@ -30,20 +30,18 @@ template(name="swimlaneFixedHeader") unless currentUser.isWorker a.swimlane-collapse-indicator.js-collapse-swimlane.swimlane-header-collapse(title="{{_ 'collapse'}}") if collapseSwimlane - | ▶ + i.fa.fa-caret-right else - | 🔽 - a.js-open-add-swimlane-menu.swimlane-header-plus-icon(title="{{_ 'add-swimlane'}}") - | ➕ + i.fa.fa-caret-down + a.js-open-swimlane-menu(title="{{_ 'swimlaneActionPopup-title'}}") + i.fa.fa-bars if isTouchScreenOrShowDesktopDragHandles unless isTouchScreen a.swimlane-header-handle.handle.js-swimlane-header-handle - | ↕️ + i.fa.fa-arrows if isTouchScreen a.swimlane-header-miniscreen-handle.handle.js-swimlane-header-handle - | ↕️ - a.js-open-swimlane-menu(title="{{_ 'swimlaneActionPopup-title'}}") - | ☰ + i.fa.fa-arrows template(name="editSwimlaneTitleForm") .list-composer @@ -51,36 +49,45 @@ template(name="editSwimlaneTitleForm") .edit-controls.clearfix button.primary.confirm(type="submit") {{_ 'save'}} a.js-close-inlined-form - | ❌ + i.fa.fa-times-thin template(name="swimlaneActionPopup") if currentUser unless currentUser.isCommentOnly unless currentUser.isReadOnly unless currentUser.isReadAssignedOnly + ul.pop-over-list + li: a.js-add-swimlane + i.fa.fa-plus + span {{_ 'add-swimlane'}} + hr + ul.pop-over-list + li: a.js-add-list-from-swimlane + i.fa.fa-plus + span {{_ 'add-list'}} + hr ul.pop-over-list if currentUser.isBoardAdmin li: a.js-set-swimlane-color - | 🎨 + i.fa.fa-paint-brush | {{_ 'select-color'}} li: a.js-set-swimlane-height - | ↕️ + i.fa.fa-arrows | {{_ 'set-swimlane-height'}} if currentUser.isBoardAdmin unless this.isTemplateContainer hr ul.pop-over-list li: a.js-close-swimlane - | ▶️ - | 📦 + i.fa.fa-archive | {{_ 'archive-swimlane'}} ul.pop-over-list li: a.js-copy-swimlane - | 📋 + i.fa.fa-clipboard | {{_ 'copy-swimlane'}} ul.pop-over-list li: a.js-move-swimlane - | ⬆️ + i.fa.fa-arrow-up | {{_ 'move-swimlane'}} template(name="swimlaneAddPopup") @@ -107,8 +114,7 @@ template(name="setSwimlaneColorPopup") each colors span.card-label.palette-color.js-palette-color(class="card-details-{{color}}") if(isSelected color) - | ✅ - // Buttons aligned left too + i.fa.fa-check // Buttons aligned left too .flush-left button.primary.confirm.js-submit(style="margin-left:0") {{_ 'save'}} button.js-remove-color.negate.wide.right(style="margin-left:8px") {{_ 'unset-color'}} diff --git a/client/components/swimlanes/swimlaneHeader.js b/client/components/swimlanes/swimlaneHeader.js index 943e003cd..0c57bd47e 100644 --- a/client/components/swimlanes/swimlaneHeader.js +++ b/client/components/swimlanes/swimlaneHeader.js @@ -39,7 +39,6 @@ BlazeComponent.extendComponent({ this.collapsed(!this.collapsed()); }, 'click .js-open-swimlane-menu': Popup.open('swimlaneAction'), - 'click .js-open-add-swimlane-menu': Popup.open('swimlaneAdd'), submit: this.editTitle, }, ]; @@ -104,6 +103,8 @@ Template.editSwimlaneTitleForm.helpers({ }); Template.swimlaneActionPopup.events({ + 'click .js-add-swimlane': Popup.open('swimlaneAdd'), + 'click .js-add-list-from-swimlane': Popup.open('addList'), 'click .js-set-swimlane-color': Popup.open('setSwimlaneColor'), 'click .js-set-swimlane-height': Popup.open('setSwimlaneHeight'), async 'click .js-close-swimlane'(event) { diff --git a/client/components/swimlanes/swimlanes.css b/client/components/swimlanes/swimlanes.css index 6da140351..81e130c8a 100644 --- a/client/components/swimlanes/swimlanes.css +++ b/client/components/swimlanes/swimlanes.css @@ -10,6 +10,9 @@ max-height: 100%; position: relative; } +.swimlane.js-lists.js-swimlane { + min-height: 150px; +} .swimlane-header-menu .swimlane-header-collapse-down { font-size: 50%; color: #a6a6a6; @@ -73,6 +76,10 @@ position: relative; z-index: 10; pointer-events: auto; + display: flex; + align-items: center; + justify-content: center; + line-height: 1.2; } .swimlane .swimlane-header-wrap .swimlane-header-menu { position: absolute; @@ -89,7 +96,10 @@ top: calc(50% + 6px); padding: 5px; display: inline-block; - margin-left: 74px; + margin-left: 30px; + color: #a6a6a6; + vertical-align: middle; + line-height: 1.2; } @media print { .swimlane .swimlane-header-wrap .swimlane-header-menu { @@ -100,6 +110,7 @@ top: calc(50% + 6px); padding: 5px; font-size: 22px; + color: #a6a6a6; } .swimlane .swimlane-header-wrap .swimlane-header-menu-icon { top: calc(50% + 6px); @@ -107,29 +118,29 @@ font-size: 22px; } .swimlane .swimlane-header-wrap .swimlane-header-handle { - position: absolute; + position: relative; top: calc(50% + 2px); - right: 60px; - padding: 2px; + padding: 2px 5px; font-size: clamp(16px, 3vw, 20px); - transform: translateY(-50%); - display: flex; - align-items: center; - justify-content: center; + display: inline-block; + vertical-align: middle; + margin-left: 30px; cursor: move; - z-index: 15; pointer-events: auto; + color: #a6a6a6; + line-height: 1.2; } .swimlane .swimlane-header-wrap .swimlane-header-miniscreen-handle { - position: absolute; - padding: 2px; + position: relative; + padding: 2px 5px; top: calc(50% + 2px); - transform: translateY(-50%); - right: 60px; font-size: 24px; + display: inline-block; + vertical-align: middle; + margin-left: 30px; cursor: move; - z-index: 15; pointer-events: auto; + color: #a6a6a6; } /* Swimlane collapse button styling - matches list collapse button */ @@ -137,14 +148,13 @@ color: #a6a6a6; display: inline-block; vertical-align: middle; - padding: 5px 8px; + padding: 5px; border: none; border-radius: 0; background-color: transparent; cursor: pointer; font-size: 18px; - line-height: 1; - min-width: 30px; + line-height: 1.2; text-align: center; text-decoration: none; margin: 0; @@ -155,6 +165,19 @@ color: #333; } +.swimlane .swimlane-header-wrap .swimlane-header-menu .js-open-swimlane-menu:hover { + color: #333; +} + +.swimlane .swimlane-header-wrap .swimlane-header-plus-icon:hover { + color: #333; +} + +.swimlane .swimlane-header-wrap .swimlane-header-handle:hover, +.swimlane .swimlane-header-wrap .swimlane-header-miniscreen-handle:hover { + color: #333; +} + #js-swimlane-height-edit .swimlane-height-error { display: none; } diff --git a/client/components/swimlanes/swimlanes.jade b/client/components/swimlanes/swimlanes.jade index be39d4eac..beec47185 100644 --- a/client/components/swimlanes/swimlanes.jade +++ b/client/components/swimlanes/swimlanes.jade @@ -9,15 +9,9 @@ template(name="swimlane") if currentListIsInThisSwimlane _id +list(currentList) unless currentList - if currentUser.isBoardMember - unless currentUser.isCommentOnly - +addListForm each lists +miniList(this) else - if currentUser.isBoardMember - unless currentUser.isCommentOnly - +addListForm each lists if visible this +list(this) @@ -30,15 +24,9 @@ template(name="listsGroup") if currentList +list(currentList) else - if currentUser.isBoardMember - unless currentUser.isCommentOnly - +addListForm each lists +miniList(this) else - if currentUser.isBoardMember - unless currentUser.isCommentOnly - +addListForm each lists if visible this +list(this) @@ -63,7 +51,7 @@ template(name="addListForm") .edit-controls.clearfix button.primary.confirm(type="submit") {{_ 'save'}} .js-close-inlined-form - | ❌ + i.fa.fa-times-thin unless currentBoard.isTemplatesBoard unless currentBoard.isTemplateBoard span.quiet @@ -71,7 +59,7 @@ template(name="addListForm") a.js-list-template {{_ 'template'}} else a.open-list-composer.js-open-inlined-form(title="{{_ 'add-list'}}") - | ➕ + i.fa.fa-plus template(name="moveSwimlanePopup") if currentUser diff --git a/client/components/users/passwordInput.jade b/client/components/users/passwordInput.jade index 98a918ade..9cc750c73 100644 --- a/client/components/users/passwordInput.jade +++ b/client/components/users/passwordInput.jade @@ -3,11 +3,9 @@ template(name='passwordInput') label(for='at-field-{{_id}}') {{displayName}} .password-input-container input.password-field(type="{{type}}" placeholder="{{displayName}}" autocomplete="{{autocomplete}}" required="{{required}}") - button.password-toggle-btn(type="button" aria-label="Toggle password visibility" title="Toggle password visibility") - .eye-container - span.eye-text 👁️ - svg.eye-slash(width="20" height="20" viewBox="0 0 20 20" class="eye-slash-line") - line(x1="6" y1="14" x2="32" y2="-14" stroke="#000" stroke-width="2" stroke-linecap="round") + button.password-toggle-btn(type="button" tabindex="-1" aria-label="Toggle password visibility" title="Toggle password visibility") + i.fa.fa-eye.eye-icon + i.fa.fa-eye-slash.eye-slash-icon if errs .at-error each errs diff --git a/client/components/users/passwordInput.js b/client/components/users/passwordInput.js index 625e51193..c4e725683 100644 --- a/client/components/users/passwordInput.js +++ b/client/components/users/passwordInput.js @@ -15,10 +15,14 @@ Template.passwordInput.onRendered(function() { // Ensure the input starts as password type for password fields input.type = 'password'; - // Initially hide the slash line since password starts hidden - const slashLine = template.find('.eye-slash-line'); - if (slashLine) { - slashLine.style.display = 'none'; + // Initially show eye icon (password is hidden) and hide eye-slash icon + const eyeIcon = template.find('.eye-icon'); + const eyeSlashIcon = template.find('.eye-slash-icon'); + if (eyeIcon) { + eyeIcon.style.display = 'inline-block'; + } + if (eyeSlashIcon) { + eyeSlashIcon.style.display = 'none'; } } }); @@ -27,19 +31,26 @@ Template.passwordInput.events({ 'click .password-toggle-btn'(event, template) { event.preventDefault(); const input = template.find('input.password-field'); - const slashLine = template.find('.eye-slash-line'); + const eyeIcon = template.find('.eye-icon'); + const eyeSlashIcon = template.find('.eye-slash-icon'); if (input.type === 'password') { input.type = 'text'; - // Show the slash line when password is visible - if (slashLine) { - slashLine.style.display = 'block'; + // Show eye-slash icon when password is visible + if (eyeIcon) { + eyeIcon.style.display = 'none'; + } + if (eyeSlashIcon) { + eyeSlashIcon.style.display = 'inline-block'; } } else { input.type = 'password'; - // Hide the slash line when password is hidden - if (slashLine) { - slashLine.style.display = 'none'; + // Show eye icon when password is hidden + if (eyeIcon) { + eyeIcon.style.display = 'inline-block'; + } + if (eyeSlashIcon) { + eyeSlashIcon.style.display = 'none'; } } }, diff --git a/client/components/users/userAvatar.jade b/client/components/users/userAvatar.jade index 549b742f8..342523eb7 100644 --- a/client/components/users/userAvatar.jade +++ b/client/components/users/userAvatar.jade @@ -16,7 +16,7 @@ template(name="userAvatar") if showEdit if $eq currentUser._id userData._id a.edit-avatar.js-change-avatar - | ✏️ + i.fa.fa-pencil-square-o template(name="userAvatarInitials") svg.avatar.avatar-initials(viewBox="0 0 {{viewPortWidth}} 15") @@ -92,8 +92,7 @@ template(name="changeAvatarPopup") .member img.avatar.avatar-image(src="{{link}}") if isSelected - | ✅ - p.sub-name + i.fa.fa-check p.sub-name a.js-delete-avatar {{_ 'delete'}} | - = name @@ -102,8 +101,7 @@ template(name="changeAvatarPopup") +userAvatarInitials(userId=currentUser._id) | {{_ 'initials' }} if noAvatarUrl - | ✅ - p.sub-name {{_ 'default-avatar'}} + i.fa.fa-check p.sub-name {{_ 'default-avatar'}} input.hide.js-upload-avatar-input(accept="image/*;capture=camera" type="file") if Meteor.settings.public.avatarsUploadMaxSize | {{_ 'max-avatar-filesize'}} {{Meteor.settings.public.avatarsUploadMaxSize}} @@ -113,7 +111,7 @@ template(name="changeAvatarPopup") br | {{_ 'invalid-file'}} button.full.js-upload-avatar - | 📤 + i.fa.fa-upload | {{_ 'upload-avatar' }} template(name="deleteAvatarPopup") diff --git a/client/components/users/userForm.css b/client/components/users/userForm.css index ae8392421..be5e0522d 100644 --- a/client/components/users/userForm.css +++ b/client/components/users/userForm.css @@ -37,14 +37,14 @@ .password-toggle-btn { position: absolute; right: 5px; /* Adjusted for larger button */ - top: calc(50% - 6px); /* Moved up by 6px total */ + top: calc(50% - 26px); /* Moved up by 20px + 6px = 26px total */ transform: translateY(-50%); background: #f8f8f8 !important; border: 1px solid #ddd !important; border-radius: 3px !important; color: #000 !important; /* Black color for the icon */ cursor: pointer; - padding: 8px 12px; /* 2x bigger padding */ + padding: 8px 6px 8px 12px; /* 2x bigger padding, 6px less on right */ font-size: 16px; /* 2x bigger font size */ width: auto !important; height: auto !important; @@ -56,6 +56,10 @@ min-width: 40px; /* 2x bigger minimum width */ min-height: 32px; /* 2x bigger minimum height */ } +/* Adjust position for login and register pages */ +.auth-layout .password-toggle-btn { + top: calc(50% - 11px); /* Move 15px down for login/register */ +} .password-toggle-btn .eye-text { color: #000 !important; font-size: 16px !important; diff --git a/client/components/users/userHeader.jade b/client/components/users/userHeader.jade index 1b9411085..eb076213a 100644 --- a/client/components/users/userHeader.jade +++ b/client/components/users/userHeader.jade @@ -15,95 +15,95 @@ template(name="memberMenuPopup") with currentUser li a.js-toggle-grey-icons(href="#") - | 🎨 + i.fa.fa-paint-brush | {{_ 'grey-icons'}} if currentUser.profile if currentUser.profile.GreyIcons - span(key="grey-icons-checkmark") ✅ + i.fa.fa-check li a.js-my-cards(href="{{pathFor 'my-cards'}}") - | 📋 + i.fa.fa-list | {{_ 'my-cards'}} li a.js-due-cards(href="{{pathFor 'due-cards'}}") - | 📅 + i.fa.fa-calendar | {{_ 'dueCards-title'}} li a.js-global-search(href="{{pathFor 'global-search'}}") - | 🔍 + i.fa.fa-search | {{_ 'globalSearch-title'}} li a(href="{{pathFor 'home'}}") - | 🏠 + i.fa.fa-home | {{_ 'all-boards'}} li a(href="{{pathFor 'public'}}") - | 🌐 + i.fa.fa-globe | {{_ 'public'}} li a.board-header-btn.js-open-archived-board - | 📦 + i.fa.fa-archive span {{_ 'archives'}} li a.js-notifications-drawer-toggle - | 🔔 + i.fa.fa-bell | {{_ 'notifications'}} if currentSetting.customHelpLinkUrl li a(href="{{currentSetting.customHelpLinkUrl}}", title="{{_ 'help'}}", target="_blank", rel="noopener noreferrer") - | ❓ + i.fa.fa-question-circle | {{_ 'help'}} unless currentUser.isWorker ul.pop-over-list li a(href="{{pathFor 'board' id=templatesBoardId slug=templatesBoardSlug}}") - | 📋 + i.fa.fa-list | {{_ 'templates'}} if currentUser.isAdmin li a.js-go-setting(href="{{pathFor 'setting'}}") - | 🔒 + i.fa.fa-lock | {{_ 'admin-panel'}} hr if isSameDomainNameSettingValue li a.js-invite-people - | ✉️ + i.fa.fa-envelope | {{_ 'invite-people'}} if isNotOAuth2AuthenticationMethod li a.js-edit-profile - | 👤 + i.fa.fa-user | {{_ 'edit-profile'}} li a.js-change-settings - | ⚙️ + i.fa.fa-cog | {{_ 'change-settings'}} li a.js-change-avatar - | 🖼️ + i.fa.fa-picture-o | {{_ 'edit-avatar'}} unless isSandstorm if isNotOAuth2AuthenticationMethod li a.js-change-password - | 🔑 + i.fa.fa-key | {{_ 'changePasswordPopup-title'}} li a.js-change-language - | 🏁 + i.fa.fa-flag | {{_ 'changeLanguagePopup-title'}} if isSupportPageEnabled li a(href="{{pathFor 'support'}}") - | ❓ + i.fa.fa-question-circle | {{_ 'support'}} unless isSandstorm hr ul.pop-over-list li a.js-logout - | 🚪 + i.fa.fa-sign-out | {{_ 'log-out'}} template(name="invitePeoplePopup") @@ -177,25 +177,25 @@ template(name="changeLanguagePopup") a.js-set-language span.emoji-icon {{languageFlag}} | {{name}} + if rtl + | (RTL) if isCurrentLanguage - | ✅ - + i.fa.fa-check template(name="changeSettingsPopup") ul.pop-over-list li a.js-toggle-desktop-drag-handles - | ↕️ + i.fa.fa-arrows | {{_ 'show-desktop-drag-handles'}} if isShowDesktopDragHandles - | ✅ - unless currentUser.isWorker + i.fa.fa-check unless currentUser.isWorker li label.bold.clear - | 🔢 + i.fa.fa-sort-numeric-asc | {{_ 'show-cards-minimum-count'}} input#show-cards-count-at.inline-input.left(type="number" value="#{showCardsCountAt}" min="-1") label.bold.clear - | 📅 + i.fa.fa-calendar | {{_ 'start-day-of-week'}} select#start-day-of-week.inline-input.left each day in weekDays startDayOfWeek diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index 45e3dae4b..8c892e747 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -295,7 +295,7 @@ Template.changePasswordPopup.onRendered(function() { Template.changeLanguagePopup.helpers({ languages() { return TAPi18n.getSupportedLanguages() - .map(({ tag, name }) => ({ tag: tag, name })) + .map(({ tag, name, rtl }) => ({ tag, name, rtl })) .sort((a, b) => { if (a.name === b.name) { return 0; diff --git a/client/config/blazeHelpers.js b/client/config/blazeHelpers.js index 87418921a..059802e39 100644 --- a/client/config/blazeHelpers.js +++ b/client/config/blazeHelpers.js @@ -82,3 +82,5 @@ Blaze.registerHelper('canModifyBoard', () => ); Blaze.registerHelper('add', (a, b) => a + b); + +Blaze.registerHelper('increment', (n) => (n || 0) + 1); diff --git a/client/lib/inlinedform.js b/client/lib/inlinedform.js index 409b259d0..62da01993 100644 --- a/client/lib/inlinedform.js +++ b/client/lib/inlinedform.js @@ -24,6 +24,26 @@ InlinedForm = BlazeComponent.extendComponent({ this.isOpen = new ReactiveVar(false); }, + onRendered() { + // Autofocus when form becomes open + this.autorun(() => { + if (this.isOpen.get()) { + Tracker.afterFlush(() => { + const input = this.find('textarea,input[type=text]'); + if (input && typeof input.focus === 'function') { + setTimeout(() => { + input.focus(); + // Select content if it exists (useful for editing) + if (input.value && input.select) { + input.select(); + } + }, 50); + } + }); + } + }); + }, + onDestroyed() { currentlyOpenedForm.set(null); },