mirror of
https://github.com/wekan/wekan.git
synced 2025-12-26 12:18:49 +01:00
Number of cards per list and sum of custom number field in list head.
Thanks to xet7 ! Fixes #3796
This commit is contained in:
parent
4292302c3c
commit
e569c2957e
29 changed files with 239 additions and 142 deletions
|
|
@ -108,15 +108,12 @@
|
|||
text-decoration: none;
|
||||
height: 24px;
|
||||
}
|
||||
.comments .comment .comment-desc .reactions .open-comment-reaction-popup i.fa.fa-smile-o {
|
||||
font-size: 17px;
|
||||
.comments .comment .comment-desc .reactions .open-comment-reaction-popup span {
|
||||
display: inline-block;
|
||||
font-size: clamp(14px, 2vw, 18px);
|
||||
font-weight: 500;
|
||||
margin-left: 2px;
|
||||
}
|
||||
.comments .comment .comment-desc .reactions .open-comment-reaction-popup i.fa.fa-plus {
|
||||
font-size: 8px;
|
||||
margin-top: -7px;
|
||||
margin-left: 1px;
|
||||
line-height: 1;
|
||||
margin-left: 4px;
|
||||
}
|
||||
.comments .comment .comment-desc .reactions .reaction {
|
||||
cursor: pointer;
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@ template(name="comment")
|
|||
= text
|
||||
.edit-controls
|
||||
button.primary(type="submit") {{_ 'edit'}}
|
||||
.fa.fa-times-thin.js-close-inlined-form
|
||||
a.js-close-inlined-form(title="{{_ 'close' }}") ❌
|
||||
else
|
||||
.comment-text
|
||||
+viewer
|
||||
|
|
@ -55,8 +55,8 @@ template(name="commentReactions")
|
|||
span.reaction-count #{reaction.userIds.length}
|
||||
if (currentUser.isBoardMember)
|
||||
a.open-comment-reaction-popup(title="{{_ 'addReactionPopup-title'}}")
|
||||
i.fa.fa-smile-o
|
||||
i.fa.fa-plus
|
||||
span(title="{{_ 'reaction' }}") 😀
|
||||
span(title="{{_ 'add' }}") ➕
|
||||
|
||||
template(name="addReactionPopup")
|
||||
.reactions-popup
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
template(name="archivedBoards")
|
||||
h2
|
||||
i.fa.fa-archive
|
||||
span(title="{{_ 'archived-boards'}}") 📦
|
||||
| {{_ 'archived-boards'}}
|
||||
|
||||
ul.archived-lists
|
||||
|
|
@ -8,10 +8,10 @@ template(name="archivedBoards")
|
|||
li.archived-lists-item
|
||||
div.board-header-btns
|
||||
button.board-header-btn.js-delete-board
|
||||
i.fa.fa-trash-o
|
||||
| 🗑️
|
||||
| {{_ 'delete-board'}}
|
||||
button.board-header-btn.js-restore-board
|
||||
i.fa.fa-undo
|
||||
| ↩️
|
||||
| {{_ 'restore-board'}}
|
||||
= title
|
||||
span {{ moment archivedAt 'LLL' }}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,6 @@ template(name="miniboard")
|
|||
class="minicard-{{colorClass}}")
|
||||
.minicard-title
|
||||
.handle
|
||||
.fa.fa-arrows
|
||||
span.drag-handle(title="{{_ 'dragBoard'}}") ↕️
|
||||
+viewer
|
||||
= title
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@
|
|||
display: block;
|
||||
position: relative;
|
||||
float: left;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
height: clamp(24px, 3.5vw, 36px);
|
||||
width: clamp(24px, 3.5vw, 36px);
|
||||
margin: .3vh;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
|
|
|||
|
|
@ -26,10 +26,10 @@ template(name="cardDetails")
|
|||
| ☰
|
||||
a.card-copy-button.js-copy-link(
|
||||
id="cardURL_copy"
|
||||
class="fa-link"
|
||||
title="{{_ 'copy-card-link-to-clipboard'}}"
|
||||
href="{{ originRelativeUrl }}"
|
||||
)
|
||||
| 🔗
|
||||
span.copied-tooltip {{_ 'copied'}}
|
||||
else
|
||||
unless isPopup
|
||||
|
|
@ -40,10 +40,10 @@ template(name="cardDetails")
|
|||
| ☰
|
||||
a.card-copy-mobile-button.js-copy-link(
|
||||
id="cardURL_copy"
|
||||
class="fa-link"
|
||||
title="{{_ 'copy-card-link-to-clipboard'}}"
|
||||
href="{{ originRelativeUrl }}"
|
||||
)
|
||||
| 🔗
|
||||
span.copied-tooltip {{_ 'copied'}}
|
||||
h2.card-details-title.js-card-title(
|
||||
class="{{#if canModifyCard}}js-open-inlined-form is-editable{{/if}}")
|
||||
|
|
@ -304,7 +304,7 @@ template(name="cardDetails")
|
|||
hr
|
||||
.card-details-item.card-details-item-customfield
|
||||
h3.card-details-item-title
|
||||
| 📋-alt
|
||||
| 📋
|
||||
= definition.name
|
||||
+cardCustomField
|
||||
|
||||
|
|
@ -678,7 +678,7 @@ template(name="cardDetailsActionsPopup")
|
|||
| 👁️
|
||||
| {{_ 'unwatch'}}
|
||||
else
|
||||
| 👁️-slash
|
||||
| 👁️
|
||||
| {{_ 'watch'}}
|
||||
hr
|
||||
if canModifyCard
|
||||
|
|
@ -698,7 +698,7 @@ template(name="cardDetailsActionsPopup")
|
|||
if currentUser.isBoardAdmin
|
||||
li
|
||||
a.js-custom-fields
|
||||
| 📋-alt
|
||||
| 📋
|
||||
| {{_ 'card-edit-custom-fields'}}
|
||||
//li: a.js-received-date {{_ 'editCardReceivedDatePopup-title'}}
|
||||
//li: a.js-start-date {{_ 'editCardStartDatePopup-title'}}
|
||||
|
|
@ -718,7 +718,7 @@ template(name="cardDetailsActionsPopup")
|
|||
| 👁️
|
||||
| {{_ 'hide-list-on-minicard'}}
|
||||
else
|
||||
| 👁️-slash
|
||||
| 👁️
|
||||
| {{_ 'show-list-on-minicard'}}
|
||||
hr
|
||||
ul.pop-over-list
|
||||
|
|
|
|||
|
|
@ -67,14 +67,14 @@ textarea.js-edit-checklist-item {
|
|||
.checklist-title .checklist-stat.is-finished {
|
||||
color: #3cb500;
|
||||
}
|
||||
.checklist-title span.fa.checklist-handle {
|
||||
.checklist-title span.checklist-handle {
|
||||
padding-right: 20px;
|
||||
padding-top: 3px;
|
||||
float: left;
|
||||
}
|
||||
.checklist-title span.fa.checklist-handle.fa-arrows::before {
|
||||
content: "↕️" !important;
|
||||
font-family: inherit !important;
|
||||
display: inline-block;
|
||||
width: 1.2em;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
}
|
||||
#card-details-overlay {
|
||||
top: 0;
|
||||
|
|
@ -148,13 +148,13 @@ textarea.js-edit-checklist-item {
|
|||
word-wrap: break-word;
|
||||
max-width: 420px;
|
||||
}
|
||||
.checklist-item span.fa.checklistitem-handle {
|
||||
.checklist-item span.checklistitem-handle {
|
||||
padding-top: 2px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
.checklist-item span.fa.checklistitem-handle.fa-arrows::before {
|
||||
content: "↕️" !important;
|
||||
font-family: inherit !important;
|
||||
display: inline-block;
|
||||
width: 1.2em;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
}
|
||||
.js-delete-checklist-item,
|
||||
.js-convert-checklist-item-to-card {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ template(name="checklistDetail")
|
|||
if canModifyCard
|
||||
h4.title.js-open-inlined-form.is-editable
|
||||
if isTouchScreenOrShowDesktopDragHandles
|
||||
span.fa.checklist-handle(class="fa-arrows" title="{{_ 'dragChecklist'}}")
|
||||
span.checklist-handle(title="{{_ 'dragChecklist'}}") ↕️
|
||||
+viewer
|
||||
= checklist.title
|
||||
else
|
||||
|
|
@ -127,7 +127,7 @@ template(name='checklistItemDetail')
|
|||
if canModifyCard
|
||||
.check-box-container
|
||||
.check-box.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}")
|
||||
span.fa.checklistitem-handle(class="fa-arrows" title="{{_ 'dragChecklistItem'}}")
|
||||
span.checklistitem-handle(title="{{_ 'dragChecklistItem'}}") ↕️
|
||||
.item-title.js-open-inlined-form.is-editable(class="{{#if item.isFinished }}is-checked{{/if}}")
|
||||
+viewer
|
||||
= item.title
|
||||
|
|
|
|||
|
|
@ -223,9 +223,13 @@
|
|||
.card-label-edit-button:hover {
|
||||
background: #dbdbdb;
|
||||
}
|
||||
ul.edit-labels-pop-over span.fa.label-handle {
|
||||
ul.edit-labels-pop-over span.label-handle {
|
||||
padding-right: 10px;
|
||||
display: inline-block;
|
||||
width: 1.2em;
|
||||
text-align: center;
|
||||
color: #999;
|
||||
}
|
||||
ul.edit-labels-pop-over span.fa.label-handle + .card-label {
|
||||
ul.edit-labels-pop-over span.label-handle + .card-label {
|
||||
max-width: 180px;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ template(name="cardLabelsPopup")
|
|||
a.card-label-edit-button.js-edit-label
|
||||
| ✏️
|
||||
if isTouchScreenOrShowDesktopDragHandles
|
||||
span.fa.label-handle(class="fa-arrows" title="{{_ 'dragLabel'}}")
|
||||
span.label-handle(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
|
||||
|
|
|
|||
|
|
@ -142,9 +142,12 @@
|
|||
display: block;
|
||||
}
|
||||
}
|
||||
.minicard .handle .fa-arrows {
|
||||
.minicard .handle .drag-handle {
|
||||
font-size: clamp(16px, 3vw, 20px);
|
||||
color: #ccc;
|
||||
display: inline-block;
|
||||
width: 1.4em;
|
||||
text-align: center;
|
||||
}
|
||||
.minicard .minicard-title .card-number {
|
||||
color: #b3b3b3;
|
||||
|
|
@ -297,19 +300,6 @@
|
|||
background-color: #1976d2 !important;
|
||||
}
|
||||
|
||||
/* Font Awesome icons in minicard dates */
|
||||
.minicard .card-date i.fa {
|
||||
margin-right: 0.3vw;
|
||||
font-size: 0.9em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
/* Font Awesome icons in minicard spent time */
|
||||
.minicard .card-time i.fa {
|
||||
margin-right: 0.3vw;
|
||||
font-size: 0.9em;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.minicard .badges {
|
||||
float: left;
|
||||
margin-top: 1vh;
|
||||
|
|
@ -740,8 +730,3 @@
|
|||
align-items: center;
|
||||
gap: 0.3vw;
|
||||
}
|
||||
|
||||
.minicard-list-name i.fa {
|
||||
font-size: 0.8em;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -251,6 +251,6 @@ template(name="minicardDetailsActionsPopup")
|
|||
| 👁️
|
||||
| {{_ 'unwatch'}}
|
||||
else
|
||||
| 👁️-slash
|
||||
| 👁️
|
||||
| {{_ 'watch'}}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,19 +2,17 @@
|
|||
<div class="original-position-info">
|
||||
{{#if isLoading}}
|
||||
<div class="original-position-loading">
|
||||
<i class="fa fa-spinner fa-spin"></i> Loading original position...
|
||||
⏳ Loading original position...
|
||||
</div>
|
||||
{{else if showOriginalPosition}}
|
||||
<div class="original-position-details">
|
||||
{{#if hasMovedFromOriginal}}
|
||||
<div class="original-position-moved">
|
||||
<i class="fa fa-info-circle"></i>
|
||||
<span class="original-position-text">{{getOriginalPositionDescription}}</span>
|
||||
<span class="original-position-text">ℹ️ {{getOriginalPositionDescription}}</span>
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="original-position-unchanged">
|
||||
<i class="fa fa-check-circle"></i>
|
||||
<span class="original-position-text">In original position</span>
|
||||
<span class="original-position-text">✅ In original position</span>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
template(name="importHeaderBar")
|
||||
h1
|
||||
a.back-btn(href="{{pathFor 'home'}}")
|
||||
i.fa.fa-chevron-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.
|
||||
|
|
|
|||
|
|
@ -368,6 +368,18 @@ body.list-resizing-active * {
|
|||
text-overflow: ellipsis;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
/* Sum badge shown before list title */
|
||||
.list-header .list-sum-badge {
|
||||
display: inline-block;
|
||||
margin-right: 8px;
|
||||
padding: 0;
|
||||
border-radius: 0;
|
||||
background: transparent;
|
||||
color: #8c8c8c;
|
||||
font-weight: bold;
|
||||
font-size: 12px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.list-rotated {
|
||||
width: 1.3vw;
|
||||
height: 35vh;
|
||||
|
|
@ -750,6 +762,9 @@ body.list-resizing-active * {
|
|||
grid-row: 2;
|
||||
grid-column: 2;
|
||||
align-self: start;
|
||||
text-align: left;
|
||||
padding-left: 0;
|
||||
margin-left: 0;
|
||||
font-size: 16px !important;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
|
@ -964,6 +979,9 @@ body.list-resizing-active * {
|
|||
grid-row: 2 !important;
|
||||
grid-column: 2 !important;
|
||||
align-self: start !important;
|
||||
text-align: left !important;
|
||||
padding-left: 0 !important;
|
||||
margin-left: 0 !important;
|
||||
font-size: 16px !important;
|
||||
line-height: 1.2 !important;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,11 +16,50 @@ BlazeComponent.extendComponent({
|
|||
},
|
||||
|
||||
customFieldsSum() {
|
||||
const ret = ReactiveCache.getCustomFields({
|
||||
boardIds: { $in: [Session.get('currentBoard')] },
|
||||
const list = Template.currentData();
|
||||
if (!list) return [];
|
||||
const boardId = Session.get('currentBoard');
|
||||
const fields = ReactiveCache.getCustomFields({
|
||||
boardIds: { $in: [boardId] },
|
||||
showSumAtTopOfList: true,
|
||||
});
|
||||
return ret;
|
||||
|
||||
if (!fields || !fields.length) return [];
|
||||
|
||||
const cards = ReactiveCache.getCards({
|
||||
listId: list._id,
|
||||
archived: false,
|
||||
});
|
||||
|
||||
const result = fields.map(field => {
|
||||
let sum = 0;
|
||||
if (cards && cards.length) {
|
||||
cards.forEach(card => {
|
||||
const cfs = (card.customFields || []);
|
||||
const cf = cfs.find(f => f && f._id === field._id);
|
||||
if (!cf || cf.value === null || cf.value === undefined) return;
|
||||
let v = cf.value;
|
||||
if (typeof v === 'string') {
|
||||
// try to parse string numbers, accept comma decimal
|
||||
const parsed = parseFloat(v.replace(',', '.'));
|
||||
if (isNaN(parsed)) return;
|
||||
v = parsed;
|
||||
}
|
||||
if (typeof v === 'number' && isFinite(v)) {
|
||||
sum += v;
|
||||
}
|
||||
});
|
||||
}
|
||||
return {
|
||||
_id: field._id,
|
||||
name: field.name,
|
||||
type: field.type,
|
||||
settings: field.settings || {},
|
||||
value: sum,
|
||||
};
|
||||
});
|
||||
|
||||
return result;
|
||||
},
|
||||
|
||||
openForm(options) {
|
||||
|
|
@ -254,6 +293,22 @@ BlazeComponent.extendComponent({
|
|||
},
|
||||
}).register('listBody');
|
||||
|
||||
// Helpers for listBody template context
|
||||
Template.listBody.helpers({
|
||||
formattedCurrencyCustomFieldValue(val) {
|
||||
// `this` is the custom field sum object from customFieldsSum each-iteration
|
||||
const field = this || {};
|
||||
const code = (field.settings && field.settings.currencyCode) || 'USD';
|
||||
try {
|
||||
const n = typeof val === 'number' ? val : parseFloat(val);
|
||||
if (!isFinite(n)) return val;
|
||||
return new Intl.NumberFormat(undefined, { style: 'currency', currency: code }).format(n);
|
||||
} catch (e) {
|
||||
return `${code} ${val}`;
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
function toggleValueInReactiveArray(reactiveValue, value) {
|
||||
const array = reactiveValue.get();
|
||||
const valueIndex = array.indexOf(value);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,9 @@ template(name="listHeader")
|
|||
|/#{wipLimit.value})
|
||||
if showCardsCountForList cards.length
|
||||
span.cardCount {{cardsCount}} {{cardsCountForListIsOne cards.length}}
|
||||
if hasNumberFieldsSum
|
||||
|
|
||||
span.list-sum-badge(title="{{_ 'sum-of-number-fields'}}") ∑ {{numberFieldsSum}}
|
||||
else
|
||||
if collapsed
|
||||
a.js-collapse(title="{{_ 'uncollapse'}}")
|
||||
|
|
@ -44,6 +47,9 @@ template(name="listHeader")
|
|||
unless collapsed
|
||||
if showCardsCountForList cards.length
|
||||
span.cardCount {{cardsCount}} {{cardsCountForListIsOne cards.length}}
|
||||
if hasNumberFieldsSum
|
||||
|
|
||||
span.list-sum-badge(title="{{_ 'sum-of-number-fields'}}") ∑ {{numberFieldsSum}}
|
||||
if isMiniScreen
|
||||
if currentList
|
||||
if isWatching
|
||||
|
|
|
|||
|
|
@ -142,7 +142,48 @@ BlazeComponent.extendComponent({
|
|||
Template.listHeader.helpers({
|
||||
isBoardAdmin() {
|
||||
return ReactiveCache.getCurrentUser().isBoardAdmin();
|
||||
}
|
||||
},
|
||||
numberFieldsSum() {
|
||||
const list = Template.currentData();
|
||||
if (!list) return 0;
|
||||
const boardId = Session.get('currentBoard');
|
||||
const fields = ReactiveCache.getCustomFields({
|
||||
boardIds: { $in: [boardId] },
|
||||
showSumAtTopOfList: true,
|
||||
type: 'number',
|
||||
});
|
||||
if (!fields || !fields.length) return 0;
|
||||
const cards = ReactiveCache.getCards({ listId: list._id, archived: false });
|
||||
let total = 0;
|
||||
if (cards && cards.length) {
|
||||
cards.forEach(card => {
|
||||
const cfs = (card.customFields || []);
|
||||
fields.forEach(field => {
|
||||
const cf = cfs.find(f => f && f._id === field._id);
|
||||
if (!cf || cf.value === null || cf.value === undefined) return;
|
||||
let v = cf.value;
|
||||
if (typeof v === 'string') {
|
||||
const parsed = parseFloat(v.replace(',', '.'));
|
||||
if (isNaN(parsed)) return;
|
||||
v = parsed;
|
||||
}
|
||||
if (typeof v === 'number' && isFinite(v)) {
|
||||
total += v;
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
return total;
|
||||
},
|
||||
hasNumberFieldsSum() {
|
||||
const boardId = Session.get('currentBoard');
|
||||
const fields = ReactiveCache.getCustomFields({
|
||||
boardIds: { $in: [boardId] },
|
||||
showSumAtTopOfList: true,
|
||||
type: 'number',
|
||||
});
|
||||
return !!(fields && fields.length);
|
||||
},
|
||||
});
|
||||
|
||||
Template.listActionPopup.helpers({
|
||||
|
|
|
|||
|
|
@ -3,6 +3,6 @@ template(name="minilist")
|
|||
class="minicard-{{colorClass}}")
|
||||
.minicard-title
|
||||
.handle
|
||||
.fa.fa-arrows
|
||||
span.drag-handle(title="{{_ 'dragList'}}") ↕️
|
||||
+viewer
|
||||
= title
|
||||
|
|
|
|||
|
|
@ -527,7 +527,7 @@ a:not(.disabled).is-active i.fa {
|
|||
|
||||
/* Board canvas */
|
||||
.board-canvas {
|
||||
padding: 8px;
|
||||
padding: 0 8px 8px 0;
|
||||
overflow-x: auto;
|
||||
-webkit-overflow-scrolling: touch;
|
||||
}
|
||||
|
|
@ -675,7 +675,7 @@ a:not(.disabled).is-active i.fa {
|
|||
}
|
||||
|
||||
.board-canvas {
|
||||
padding: 12px;
|
||||
padding: 0 12px 12px 0;
|
||||
}
|
||||
|
||||
#header {
|
||||
|
|
@ -756,7 +756,7 @@ a:not(.disabled).is-active i.fa {
|
|||
.inline-input {
|
||||
height: 37px;
|
||||
margin: 8px 10px 0 0;
|
||||
width: 50px;
|
||||
width: 100px;
|
||||
}
|
||||
.select-authentication {
|
||||
width: 100%;
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@
|
|||
height: 3vw;
|
||||
}
|
||||
#notifications-drawer .notification .read-status .activity-type {
|
||||
margin: 2vh 0 0;
|
||||
width: 2.2vw;
|
||||
height: 2.2vw;
|
||||
font-size: clamp(14px, 2.5vw, 17px);
|
||||
margin: 8px 0 0;
|
||||
width: 1.2em;
|
||||
height: 1.2em;
|
||||
font-size: clamp(14px, 2vw, 17px);
|
||||
display: block;
|
||||
color: #bbb;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,4 +7,4 @@ template(name='notification')
|
|||
+activity(activity=activityData mode='none')
|
||||
if read
|
||||
.remove
|
||||
a.fa.fa-trash
|
||||
a(title="{{_ 'delete'}}") 🗑️
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
template(name='notificationIcon')
|
||||
if($in activityType 'deleteAttachment' 'addAttachment')
|
||||
i.fa.fa-paperclip.activity-type(title="attachment")
|
||||
span.activity-type(title="attachment") 📎
|
||||
else if($in activityType 'createBoard' 'importBoard')
|
||||
i.fa.fa-chalkboard.activity-type(title="board")
|
||||
span.activity-type(title="board") 🗂️
|
||||
|
||||
else if($in activityType 'createCard' 'importCard' 'moveCard')
|
||||
+cardNotificationIcon
|
||||
|
|
@ -19,17 +19,17 @@ template(name='notificationIcon')
|
|||
//- DRY and consistant
|
||||
|
||||
else if($in activityType 'checkedItem' 'uncheckedItem' 'addChecklistItem' 'removedChecklistItem')
|
||||
i.fa.fa-check-square.activity-type(title="checklist item")
|
||||
span.activity-type(title="checklist item") ☑️
|
||||
else if($in activityType 'addComment')
|
||||
i.fa.fa-comment-o.activity-type(title="comment")
|
||||
span.activity-type(title="comment") 💬
|
||||
else if($in activityType 'createCustomField' 'setCustomField' 'unsetCustomField')
|
||||
i.fa.fa-code.activity-type(title="custom field")
|
||||
span.activity-type(title="custom field") 🧩
|
||||
else if($in activityType 'addedLabel' 'removedLabel')
|
||||
i.fa.fa-tag.activity-type(title="label")
|
||||
span.activity-type(title="label") 🏷️
|
||||
else if($in activityType 'a-startAt' 'a-receivedAt')
|
||||
i.fa.fa-clock-o.activity-type(title="date")
|
||||
span.activity-type(title="date") ⏰
|
||||
else if($in activityType 'a-dueAt' 'a-endAt')
|
||||
i.fa.fa-clock-o.activity-type(title="date")
|
||||
span.activity-type(title="date") ⏰
|
||||
|
||||
else if($in activityType 'createList' 'removeList' 'archivedList')
|
||||
+listNotificationIcon
|
||||
|
|
@ -41,17 +41,17 @@ template(name='notificationIcon')
|
|||
//- elswhere in the app we use fa-trello to indicate lists...
|
||||
//- i personally like fa-columns a bit better
|
||||
else if($in activityType 'unjoinMember' 'addBoardMember' 'joinMember' 'removeBoardMember')
|
||||
i.fa.fa-user.activity-type(title="member")
|
||||
span.activity-type(title="member") 👤
|
||||
else if($in activityType 'createSwimlane' 'archivedSwimlane')
|
||||
i.fa.fa-th-large.activity-type(title="swimlane")
|
||||
span.activity-type(title="swimlane") 🧭
|
||||
else
|
||||
i.fa.fa-bug.activity-type(title="can't find icon for #{activityType}")
|
||||
span.activity-type(title="can't find icon for #{activityType}") 🐞
|
||||
|
||||
template(name='cardNotificationIcon')
|
||||
i.fa.fa-clone.activity-type(title="card")
|
||||
span.activity-type(title="card") 🗒️
|
||||
|
||||
template(name='checklistNotificationIcon')
|
||||
i.fa.fa-list.activity-type(title="checklist")
|
||||
span.activity-type(title="checklist") 📝
|
||||
|
||||
template(name='listNotificationIcon')
|
||||
i.fa.fa-columns.activity-type(title="list")
|
||||
span.activity-type(title="list") 📋
|
||||
|
|
|
|||
|
|
@ -55,9 +55,6 @@ section#notifications-drawer .remove-read {
|
|||
section#notifications-drawer .remove-read:hover {
|
||||
color: #eb4646 !important;
|
||||
}
|
||||
section#notifications-drawer .remove-read:hover i.fa {
|
||||
color: inherit;
|
||||
}
|
||||
section#notifications-drawer ul.notifications {
|
||||
display: block;
|
||||
padding: 0px 16px 0px 16px;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ template(name='notificationsDrawer')
|
|||
h5 {{_ 'notifications'}}
|
||||
if($gt unreadNotifications 0)
|
||||
|(#{unreadNotifications})
|
||||
a.fa.fa-times-thin.close
|
||||
a.close ❌
|
||||
ul.notifications
|
||||
each transformedProfile.notifications
|
||||
+notification(activityData=activityObj index=dbIndex read=read)
|
||||
|
|
@ -16,5 +16,5 @@ template(name='notificationsDrawer')
|
|||
a.all-read {{_ 'mark-all-as-read'}}
|
||||
if ($and ($.Session.get 'showReadNotifications') ($gt readNotifications 0))
|
||||
a.remove-read
|
||||
i.fa.fa-trash
|
||||
| 🗑️
|
||||
| {{_ 'remove-all-read'}}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ template(name="filterSidebar")
|
|||
else
|
||||
span.quiet {{_ "label-default" (_ (concat "color-" color))}}
|
||||
if Filter.labelIds.isSelected _id
|
||||
i.fa.fa-check
|
||||
| ✅
|
||||
hr
|
||||
h3
|
||||
| 👥
|
||||
|
|
@ -68,7 +68,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}}")
|
||||
|
|
@ -90,37 +90,37 @@ 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
|
||||
| 📋
|
||||
|
|
@ -138,7 +138,7 @@ template(name="filterSidebar")
|
|||
span.sidebar-list-item-description
|
||||
| {{ name }}
|
||||
if Filter.customFields.isSelected _id
|
||||
i.fa.fa-check
|
||||
| ✅
|
||||
hr
|
||||
h3
|
||||
| {{_ 'other-filters-label'}}
|
||||
|
|
@ -148,14 +148,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")
|
||||
|
|
|
|||
|
|
@ -28,23 +28,14 @@ template(name="swimlaneFixedHeader")
|
|||
unless currentUser.isWorker
|
||||
a.js-open-add-swimlane-menu.swimlane-header-plus-icon(title="{{_ 'add-swimlane'}}")
|
||||
| ➕
|
||||
a.js-open-swimlane-menu(title="{{_ 'swimlaneActionPopup-title'}}")
|
||||
| ☰
|
||||
//// TODO: Collapse Swimlane: make button working, etc.
|
||||
//unless collapsed
|
||||
// a.js-collapse-swimlane(title="{{_ 'collapse'}}")
|
||||
// i.fa.fa-arrow-down.swimlane-header-collapse-down
|
||||
// ⬆️.swimlane-header-collapse-up
|
||||
//if collapsed
|
||||
// a.js-collapse-swimlane(title="{{_ 'uncollapse'}}")
|
||||
// ⬆️.swimlane-header-collapse-up
|
||||
// i.fa.fa-arrow-down.swimlane-header-collapse-down
|
||||
unless isTouchScreen
|
||||
a.swimlane-header-handle.handle.js-swimlane-header-handle
|
||||
| ↕️
|
||||
if isTouchScreen
|
||||
a.swimlane-header-miniscreen-handle.handle.js-swimlane-header-handle
|
||||
| ↕️
|
||||
a.js-open-swimlane-menu(title="{{_ 'swimlaneActionPopup-title'}}")
|
||||
| ☰
|
||||
|
||||
template(name="editSwimlaneTitleForm")
|
||||
.list-composer
|
||||
|
|
|
|||
|
|
@ -54,12 +54,14 @@
|
|||
width: 100%;
|
||||
min-width: 100%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
overflow: visible;
|
||||
min-height: 33px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
.swimlane .swimlane-header-wrap .swimlane-header {
|
||||
font-size: 14px;
|
||||
padding: 5px 5px;
|
||||
padding: 0;
|
||||
font-weight: bold;
|
||||
min-height: 33px;
|
||||
width: 100%;
|
||||
|
|
@ -74,30 +76,39 @@
|
|||
}
|
||||
.swimlane .swimlane-header-wrap .swimlane-header-menu {
|
||||
position: absolute;
|
||||
padding: 5px 5px;
|
||||
top: 0;
|
||||
left: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
font-size: 22px;
|
||||
line-height: 1;
|
||||
z-index: 20;
|
||||
pointer-events: auto;
|
||||
}
|
||||
.swimlane .swimlane-header-wrap .swimlane-header-menu .js-open-swimlane-menu {
|
||||
top: calc(50% + 6px);
|
||||
padding: 5px;
|
||||
display: inline-block;
|
||||
margin-left: 74px;
|
||||
}
|
||||
@media print {
|
||||
.swimlane .swimlane-header-wrap .swimlane-header-menu {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
.swimlane .swimlane-header-wrap .swimlane-header-plus-icon {
|
||||
margin-left: 5px;
|
||||
padding-right: 20px;
|
||||
top: calc(50% + 6px);
|
||||
padding: 5px;
|
||||
font-size: 22px;
|
||||
}
|
||||
.swimlane .swimlane-header-wrap .swimlane-header-menu-icon {
|
||||
padding-right: 20px;
|
||||
top: calc(50% + 6px);
|
||||
padding: 5px;
|
||||
font-size: 22px;
|
||||
}
|
||||
.swimlane .swimlane-header-wrap .swimlane-header-handle {
|
||||
position: absolute;
|
||||
padding: 7px;
|
||||
top: 50%;
|
||||
left: 230px;
|
||||
top: calc(50% + 2px);
|
||||
padding: 2px;
|
||||
font-size: clamp(16px, 3vw, 20px);
|
||||
transform: translateY(-50%);
|
||||
display: flex;
|
||||
|
|
@ -109,22 +120,16 @@
|
|||
}
|
||||
.swimlane .swimlane-header-wrap .swimlane-header-miniscreen-handle {
|
||||
position: absolute;
|
||||
padding: 7px;
|
||||
top: 50%;
|
||||
padding: 2px;
|
||||
top: calc(50% + 2px);
|
||||
transform: translateY(-50%);
|
||||
right: 10px;
|
||||
right: 60px;
|
||||
font-size: 24px;
|
||||
cursor: move;
|
||||
z-index: 15;
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
/* Safety: ensure wrapper is interactive and above list content */
|
||||
.swimlane .swimlane-header-wrap {
|
||||
position: relative;
|
||||
z-index: 9;
|
||||
pointer-events: auto;
|
||||
}
|
||||
#js-swimlane-height-edit .swimlane-height-error {
|
||||
display: none;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@
|
|||
display: block;
|
||||
position: relative;
|
||||
float: left;
|
||||
height: 30px;
|
||||
width: 30px;
|
||||
height: clamp(24px, 3.5vw, 36px);
|
||||
width: clamp(24px, 3.5vw, 36px);
|
||||
margin: .3vh;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
|
@ -111,7 +111,7 @@
|
|||
padding-top: 0;
|
||||
}
|
||||
.mini-profile-info .member {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
width: clamp(40px, 5vw, 60px);
|
||||
height: clamp(40px, 5vw, 60px);
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue