mirror of
https://github.com/wekan/wekan.git
synced 2026-03-02 20:00:16 +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;
|
text-decoration: none;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
}
|
}
|
||||||
.comments .comment .comment-desc .reactions .open-comment-reaction-popup i.fa.fa-smile-o {
|
.comments .comment .comment-desc .reactions .open-comment-reaction-popup span {
|
||||||
font-size: 17px;
|
display: inline-block;
|
||||||
|
font-size: clamp(14px, 2vw, 18px);
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
margin-left: 2px;
|
line-height: 1;
|
||||||
}
|
margin-left: 4px;
|
||||||
.comments .comment .comment-desc .reactions .open-comment-reaction-popup i.fa.fa-plus {
|
|
||||||
font-size: 8px;
|
|
||||||
margin-top: -7px;
|
|
||||||
margin-left: 1px;
|
|
||||||
}
|
}
|
||||||
.comments .comment .comment-desc .reactions .reaction {
|
.comments .comment .comment-desc .reactions .reaction {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ template(name="comment")
|
||||||
= text
|
= text
|
||||||
.edit-controls
|
.edit-controls
|
||||||
button.primary(type="submit") {{_ 'edit'}}
|
button.primary(type="submit") {{_ 'edit'}}
|
||||||
.fa.fa-times-thin.js-close-inlined-form
|
a.js-close-inlined-form(title="{{_ 'close' }}") ❌
|
||||||
else
|
else
|
||||||
.comment-text
|
.comment-text
|
||||||
+viewer
|
+viewer
|
||||||
|
|
@ -55,8 +55,8 @@ template(name="commentReactions")
|
||||||
span.reaction-count #{reaction.userIds.length}
|
span.reaction-count #{reaction.userIds.length}
|
||||||
if (currentUser.isBoardMember)
|
if (currentUser.isBoardMember)
|
||||||
a.open-comment-reaction-popup(title="{{_ 'addReactionPopup-title'}}")
|
a.open-comment-reaction-popup(title="{{_ 'addReactionPopup-title'}}")
|
||||||
i.fa.fa-smile-o
|
span(title="{{_ 'reaction' }}") 😀
|
||||||
i.fa.fa-plus
|
span(title="{{_ 'add' }}") ➕
|
||||||
|
|
||||||
template(name="addReactionPopup")
|
template(name="addReactionPopup")
|
||||||
.reactions-popup
|
.reactions-popup
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
template(name="archivedBoards")
|
template(name="archivedBoards")
|
||||||
h2
|
h2
|
||||||
i.fa.fa-archive
|
span(title="{{_ 'archived-boards'}}") 📦
|
||||||
| {{_ 'archived-boards'}}
|
| {{_ 'archived-boards'}}
|
||||||
|
|
||||||
ul.archived-lists
|
ul.archived-lists
|
||||||
|
|
@ -8,10 +8,10 @@ template(name="archivedBoards")
|
||||||
li.archived-lists-item
|
li.archived-lists-item
|
||||||
div.board-header-btns
|
div.board-header-btns
|
||||||
button.board-header-btn.js-delete-board
|
button.board-header-btn.js-delete-board
|
||||||
i.fa.fa-trash-o
|
| 🗑️
|
||||||
| {{_ 'delete-board'}}
|
| {{_ 'delete-board'}}
|
||||||
button.board-header-btn.js-restore-board
|
button.board-header-btn.js-restore-board
|
||||||
i.fa.fa-undo
|
| ↩️
|
||||||
| {{_ 'restore-board'}}
|
| {{_ 'restore-board'}}
|
||||||
= title
|
= title
|
||||||
span {{ moment archivedAt 'LLL' }}
|
span {{ moment archivedAt 'LLL' }}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,6 @@ template(name="miniboard")
|
||||||
class="minicard-{{colorClass}}")
|
class="minicard-{{colorClass}}")
|
||||||
.minicard-title
|
.minicard-title
|
||||||
.handle
|
.handle
|
||||||
.fa.fa-arrows
|
span.drag-handle(title="{{_ 'dragBoard'}}") ↕️
|
||||||
+viewer
|
+viewer
|
||||||
= title
|
= title
|
||||||
|
|
|
||||||
|
|
@ -31,8 +31,8 @@
|
||||||
display: block;
|
display: block;
|
||||||
position: relative;
|
position: relative;
|
||||||
float: left;
|
float: left;
|
||||||
height: 30px;
|
height: clamp(24px, 3.5vw, 36px);
|
||||||
width: 30px;
|
width: clamp(24px, 3.5vw, 36px);
|
||||||
margin: .3vh;
|
margin: .3vh;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
|
||||||
|
|
@ -26,10 +26,10 @@ template(name="cardDetails")
|
||||||
| ☰
|
| ☰
|
||||||
a.card-copy-button.js-copy-link(
|
a.card-copy-button.js-copy-link(
|
||||||
id="cardURL_copy"
|
id="cardURL_copy"
|
||||||
class="fa-link"
|
|
||||||
title="{{_ 'copy-card-link-to-clipboard'}}"
|
title="{{_ 'copy-card-link-to-clipboard'}}"
|
||||||
href="{{ originRelativeUrl }}"
|
href="{{ originRelativeUrl }}"
|
||||||
)
|
)
|
||||||
|
| 🔗
|
||||||
span.copied-tooltip {{_ 'copied'}}
|
span.copied-tooltip {{_ 'copied'}}
|
||||||
else
|
else
|
||||||
unless isPopup
|
unless isPopup
|
||||||
|
|
@ -40,10 +40,10 @@ template(name="cardDetails")
|
||||||
| ☰
|
| ☰
|
||||||
a.card-copy-mobile-button.js-copy-link(
|
a.card-copy-mobile-button.js-copy-link(
|
||||||
id="cardURL_copy"
|
id="cardURL_copy"
|
||||||
class="fa-link"
|
|
||||||
title="{{_ 'copy-card-link-to-clipboard'}}"
|
title="{{_ 'copy-card-link-to-clipboard'}}"
|
||||||
href="{{ originRelativeUrl }}"
|
href="{{ originRelativeUrl }}"
|
||||||
)
|
)
|
||||||
|
| 🔗
|
||||||
span.copied-tooltip {{_ 'copied'}}
|
span.copied-tooltip {{_ 'copied'}}
|
||||||
h2.card-details-title.js-card-title(
|
h2.card-details-title.js-card-title(
|
||||||
class="{{#if canModifyCard}}js-open-inlined-form is-editable{{/if}}")
|
class="{{#if canModifyCard}}js-open-inlined-form is-editable{{/if}}")
|
||||||
|
|
@ -304,7 +304,7 @@ template(name="cardDetails")
|
||||||
hr
|
hr
|
||||||
.card-details-item.card-details-item-customfield
|
.card-details-item.card-details-item-customfield
|
||||||
h3.card-details-item-title
|
h3.card-details-item-title
|
||||||
| 📋-alt
|
| 📋
|
||||||
= definition.name
|
= definition.name
|
||||||
+cardCustomField
|
+cardCustomField
|
||||||
|
|
||||||
|
|
@ -678,7 +678,7 @@ template(name="cardDetailsActionsPopup")
|
||||||
| 👁️
|
| 👁️
|
||||||
| {{_ 'unwatch'}}
|
| {{_ 'unwatch'}}
|
||||||
else
|
else
|
||||||
| 👁️-slash
|
| 👁️
|
||||||
| {{_ 'watch'}}
|
| {{_ 'watch'}}
|
||||||
hr
|
hr
|
||||||
if canModifyCard
|
if canModifyCard
|
||||||
|
|
@ -698,7 +698,7 @@ template(name="cardDetailsActionsPopup")
|
||||||
if currentUser.isBoardAdmin
|
if currentUser.isBoardAdmin
|
||||||
li
|
li
|
||||||
a.js-custom-fields
|
a.js-custom-fields
|
||||||
| 📋-alt
|
| 📋
|
||||||
| {{_ 'card-edit-custom-fields'}}
|
| {{_ 'card-edit-custom-fields'}}
|
||||||
//li: a.js-received-date {{_ 'editCardReceivedDatePopup-title'}}
|
//li: a.js-received-date {{_ 'editCardReceivedDatePopup-title'}}
|
||||||
//li: a.js-start-date {{_ 'editCardStartDatePopup-title'}}
|
//li: a.js-start-date {{_ 'editCardStartDatePopup-title'}}
|
||||||
|
|
@ -718,7 +718,7 @@ template(name="cardDetailsActionsPopup")
|
||||||
| 👁️
|
| 👁️
|
||||||
| {{_ 'hide-list-on-minicard'}}
|
| {{_ 'hide-list-on-minicard'}}
|
||||||
else
|
else
|
||||||
| 👁️-slash
|
| 👁️
|
||||||
| {{_ 'show-list-on-minicard'}}
|
| {{_ 'show-list-on-minicard'}}
|
||||||
hr
|
hr
|
||||||
ul.pop-over-list
|
ul.pop-over-list
|
||||||
|
|
|
||||||
|
|
@ -67,14 +67,14 @@ textarea.js-edit-checklist-item {
|
||||||
.checklist-title .checklist-stat.is-finished {
|
.checklist-title .checklist-stat.is-finished {
|
||||||
color: #3cb500;
|
color: #3cb500;
|
||||||
}
|
}
|
||||||
.checklist-title span.fa.checklist-handle {
|
.checklist-title span.checklist-handle {
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
padding-top: 3px;
|
padding-top: 3px;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
display: inline-block;
|
||||||
.checklist-title span.fa.checklist-handle.fa-arrows::before {
|
width: 1.2em;
|
||||||
content: "↕️" !important;
|
text-align: center;
|
||||||
font-family: inherit !important;
|
color: #999;
|
||||||
}
|
}
|
||||||
#card-details-overlay {
|
#card-details-overlay {
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|
@ -148,13 +148,13 @@ textarea.js-edit-checklist-item {
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
max-width: 420px;
|
max-width: 420px;
|
||||||
}
|
}
|
||||||
.checklist-item span.fa.checklistitem-handle {
|
.checklist-item span.checklistitem-handle {
|
||||||
padding-top: 2px;
|
padding-top: 2px;
|
||||||
padding-right: 10px;
|
padding-right: 10px;
|
||||||
}
|
display: inline-block;
|
||||||
.checklist-item span.fa.checklistitem-handle.fa-arrows::before {
|
width: 1.2em;
|
||||||
content: "↕️" !important;
|
text-align: center;
|
||||||
font-family: inherit !important;
|
color: #999;
|
||||||
}
|
}
|
||||||
.js-delete-checklist-item,
|
.js-delete-checklist-item,
|
||||||
.js-convert-checklist-item-to-card {
|
.js-convert-checklist-item-to-card {
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ template(name="checklistDetail")
|
||||||
if canModifyCard
|
if canModifyCard
|
||||||
h4.title.js-open-inlined-form.is-editable
|
h4.title.js-open-inlined-form.is-editable
|
||||||
if isTouchScreenOrShowDesktopDragHandles
|
if isTouchScreenOrShowDesktopDragHandles
|
||||||
span.fa.checklist-handle(class="fa-arrows" title="{{_ 'dragChecklist'}}")
|
span.checklist-handle(title="{{_ 'dragChecklist'}}") ↕️
|
||||||
+viewer
|
+viewer
|
||||||
= checklist.title
|
= checklist.title
|
||||||
else
|
else
|
||||||
|
|
@ -127,7 +127,7 @@ template(name='checklistItemDetail')
|
||||||
if canModifyCard
|
if canModifyCard
|
||||||
.check-box-container
|
.check-box-container
|
||||||
.check-box.materialCheckBox(class="{{#if item.isFinished }}is-checked{{/if}}")
|
.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}}")
|
.item-title.js-open-inlined-form.is-editable(class="{{#if item.isFinished }}is-checked{{/if}}")
|
||||||
+viewer
|
+viewer
|
||||||
= item.title
|
= item.title
|
||||||
|
|
|
||||||
|
|
@ -223,9 +223,13 @@
|
||||||
.card-label-edit-button:hover {
|
.card-label-edit-button:hover {
|
||||||
background: #dbdbdb;
|
background: #dbdbdb;
|
||||||
}
|
}
|
||||||
ul.edit-labels-pop-over span.fa.label-handle {
|
ul.edit-labels-pop-over span.label-handle {
|
||||||
padding-right: 10px;
|
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;
|
max-width: 180px;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ template(name="cardLabelsPopup")
|
||||||
a.card-label-edit-button.js-edit-label
|
a.card-label-edit-button.js-edit-label
|
||||||
| ✏️
|
| ✏️
|
||||||
if isTouchScreenOrShowDesktopDragHandles
|
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}}"
|
span.card-label.card-label-selectable.js-select-label.card-label-wrapper(class="card-label-{{color}}"
|
||||||
class="{{# if isLabelSelected ../_id }}active{{/if}}")
|
class="{{# if isLabelSelected ../_id }}active{{/if}}")
|
||||||
+viewer
|
+viewer
|
||||||
|
|
|
||||||
|
|
@ -142,9 +142,12 @@
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.minicard .handle .fa-arrows {
|
.minicard .handle .drag-handle {
|
||||||
font-size: clamp(16px, 3vw, 20px);
|
font-size: clamp(16px, 3vw, 20px);
|
||||||
color: #ccc;
|
color: #ccc;
|
||||||
|
display: inline-block;
|
||||||
|
width: 1.4em;
|
||||||
|
text-align: center;
|
||||||
}
|
}
|
||||||
.minicard .minicard-title .card-number {
|
.minicard .minicard-title .card-number {
|
||||||
color: #b3b3b3;
|
color: #b3b3b3;
|
||||||
|
|
@ -297,19 +300,6 @@
|
||||||
background-color: #1976d2 !important;
|
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 {
|
.minicard .badges {
|
||||||
float: left;
|
float: left;
|
||||||
margin-top: 1vh;
|
margin-top: 1vh;
|
||||||
|
|
@ -740,8 +730,3 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 0.3vw;
|
gap: 0.3vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.minicard-list-name i.fa {
|
|
||||||
font-size: 0.8em;
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -251,6 +251,6 @@ template(name="minicardDetailsActionsPopup")
|
||||||
| 👁️
|
| 👁️
|
||||||
| {{_ 'unwatch'}}
|
| {{_ 'unwatch'}}
|
||||||
else
|
else
|
||||||
| 👁️-slash
|
| 👁️
|
||||||
| {{_ 'watch'}}
|
| {{_ 'watch'}}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,19 +2,17 @@
|
||||||
<div class="original-position-info">
|
<div class="original-position-info">
|
||||||
{{#if isLoading}}
|
{{#if isLoading}}
|
||||||
<div class="original-position-loading">
|
<div class="original-position-loading">
|
||||||
<i class="fa fa-spinner fa-spin"></i> Loading original position...
|
⏳ Loading original position...
|
||||||
</div>
|
</div>
|
||||||
{{else if showOriginalPosition}}
|
{{else if showOriginalPosition}}
|
||||||
<div class="original-position-details">
|
<div class="original-position-details">
|
||||||
{{#if hasMovedFromOriginal}}
|
{{#if hasMovedFromOriginal}}
|
||||||
<div class="original-position-moved">
|
<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>
|
</div>
|
||||||
{{else}}
|
{{else}}
|
||||||
<div class="original-position-unchanged">
|
<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>
|
</div>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
template(name="importHeaderBar")
|
template(name="importHeaderBar")
|
||||||
h1
|
h1
|
||||||
a.back-btn(href="{{pathFor 'home'}}")
|
a.back-btn(href="{{pathFor 'home'}}")
|
||||||
i.fa.fa-chevron-left
|
| ⬅️
|
||||||
| {{_ title}}
|
| {{_ title}}
|
||||||
|
|
||||||
template(name="import")
|
template(name="import")
|
||||||
|
|
@ -36,7 +36,7 @@ template(name="importMapMembers")
|
||||||
+userAvatar(userId=wekanId)
|
+userAvatar(userId=wekanId)
|
||||||
else
|
else
|
||||||
a.member.add-member
|
a.member.add-member
|
||||||
i.fa.fa-plus
|
| ➕
|
||||||
//-
|
//-
|
||||||
Due to the way the flewbox layout is working, we need to set some
|
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.
|
invisible items so that the last row items have a consistent width.
|
||||||
|
|
|
||||||
|
|
@ -368,6 +368,18 @@ body.list-resizing-active * {
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
word-wrap: break-word;
|
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 {
|
.list-rotated {
|
||||||
width: 1.3vw;
|
width: 1.3vw;
|
||||||
height: 35vh;
|
height: 35vh;
|
||||||
|
|
@ -750,6 +762,9 @@ body.list-resizing-active * {
|
||||||
grid-row: 2;
|
grid-row: 2;
|
||||||
grid-column: 2;
|
grid-column: 2;
|
||||||
align-self: start;
|
align-self: start;
|
||||||
|
text-align: left;
|
||||||
|
padding-left: 0;
|
||||||
|
margin-left: 0;
|
||||||
font-size: 16px !important;
|
font-size: 16px !important;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
}
|
}
|
||||||
|
|
@ -964,6 +979,9 @@ body.list-resizing-active * {
|
||||||
grid-row: 2 !important;
|
grid-row: 2 !important;
|
||||||
grid-column: 2 !important;
|
grid-column: 2 !important;
|
||||||
align-self: start !important;
|
align-self: start !important;
|
||||||
|
text-align: left !important;
|
||||||
|
padding-left: 0 !important;
|
||||||
|
margin-left: 0 !important;
|
||||||
font-size: 16px !important;
|
font-size: 16px !important;
|
||||||
line-height: 1.2 !important;
|
line-height: 1.2 !important;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,50 @@ BlazeComponent.extendComponent({
|
||||||
},
|
},
|
||||||
|
|
||||||
customFieldsSum() {
|
customFieldsSum() {
|
||||||
const ret = ReactiveCache.getCustomFields({
|
const list = Template.currentData();
|
||||||
boardIds: { $in: [Session.get('currentBoard')] },
|
if (!list) return [];
|
||||||
|
const boardId = Session.get('currentBoard');
|
||||||
|
const fields = ReactiveCache.getCustomFields({
|
||||||
|
boardIds: { $in: [boardId] },
|
||||||
showSumAtTopOfList: true,
|
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) {
|
openForm(options) {
|
||||||
|
|
@ -254,6 +293,22 @@ BlazeComponent.extendComponent({
|
||||||
},
|
},
|
||||||
}).register('listBody');
|
}).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) {
|
function toggleValueInReactiveArray(reactiveValue, value) {
|
||||||
const array = reactiveValue.get();
|
const array = reactiveValue.get();
|
||||||
const valueIndex = array.indexOf(value);
|
const valueIndex = array.indexOf(value);
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,9 @@ template(name="listHeader")
|
||||||
|/#{wipLimit.value})
|
|/#{wipLimit.value})
|
||||||
if showCardsCountForList cards.length
|
if showCardsCountForList cards.length
|
||||||
span.cardCount {{cardsCount}} {{cardsCountForListIsOne cards.length}}
|
span.cardCount {{cardsCount}} {{cardsCountForListIsOne cards.length}}
|
||||||
|
if hasNumberFieldsSum
|
||||||
|
|
|
||||||
|
span.list-sum-badge(title="{{_ 'sum-of-number-fields'}}") ∑ {{numberFieldsSum}}
|
||||||
else
|
else
|
||||||
if collapsed
|
if collapsed
|
||||||
a.js-collapse(title="{{_ 'uncollapse'}}")
|
a.js-collapse(title="{{_ 'uncollapse'}}")
|
||||||
|
|
@ -44,6 +47,9 @@ template(name="listHeader")
|
||||||
unless collapsed
|
unless collapsed
|
||||||
if showCardsCountForList cards.length
|
if showCardsCountForList cards.length
|
||||||
span.cardCount {{cardsCount}} {{cardsCountForListIsOne cards.length}}
|
span.cardCount {{cardsCount}} {{cardsCountForListIsOne cards.length}}
|
||||||
|
if hasNumberFieldsSum
|
||||||
|
|
|
||||||
|
span.list-sum-badge(title="{{_ 'sum-of-number-fields'}}") ∑ {{numberFieldsSum}}
|
||||||
if isMiniScreen
|
if isMiniScreen
|
||||||
if currentList
|
if currentList
|
||||||
if isWatching
|
if isWatching
|
||||||
|
|
|
||||||
|
|
@ -142,7 +142,48 @@ BlazeComponent.extendComponent({
|
||||||
Template.listHeader.helpers({
|
Template.listHeader.helpers({
|
||||||
isBoardAdmin() {
|
isBoardAdmin() {
|
||||||
return ReactiveCache.getCurrentUser().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({
|
Template.listActionPopup.helpers({
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,6 @@ template(name="minilist")
|
||||||
class="minicard-{{colorClass}}")
|
class="minicard-{{colorClass}}")
|
||||||
.minicard-title
|
.minicard-title
|
||||||
.handle
|
.handle
|
||||||
.fa.fa-arrows
|
span.drag-handle(title="{{_ 'dragList'}}") ↕️
|
||||||
+viewer
|
+viewer
|
||||||
= title
|
= title
|
||||||
|
|
|
||||||
|
|
@ -527,7 +527,7 @@ a:not(.disabled).is-active i.fa {
|
||||||
|
|
||||||
/* Board canvas */
|
/* Board canvas */
|
||||||
.board-canvas {
|
.board-canvas {
|
||||||
padding: 8px;
|
padding: 0 8px 8px 0;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
}
|
}
|
||||||
|
|
@ -675,7 +675,7 @@ a:not(.disabled).is-active i.fa {
|
||||||
}
|
}
|
||||||
|
|
||||||
.board-canvas {
|
.board-canvas {
|
||||||
padding: 12px;
|
padding: 0 12px 12px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#header {
|
#header {
|
||||||
|
|
@ -756,7 +756,7 @@ a:not(.disabled).is-active i.fa {
|
||||||
.inline-input {
|
.inline-input {
|
||||||
height: 37px;
|
height: 37px;
|
||||||
margin: 8px 10px 0 0;
|
margin: 8px 10px 0 0;
|
||||||
width: 50px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
.select-authentication {
|
.select-authentication {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
|
||||||
|
|
@ -20,10 +20,10 @@
|
||||||
height: 3vw;
|
height: 3vw;
|
||||||
}
|
}
|
||||||
#notifications-drawer .notification .read-status .activity-type {
|
#notifications-drawer .notification .read-status .activity-type {
|
||||||
margin: 2vh 0 0;
|
margin: 8px 0 0;
|
||||||
width: 2.2vw;
|
width: 1.2em;
|
||||||
height: 2.2vw;
|
height: 1.2em;
|
||||||
font-size: clamp(14px, 2.5vw, 17px);
|
font-size: clamp(14px, 2vw, 17px);
|
||||||
display: block;
|
display: block;
|
||||||
color: #bbb;
|
color: #bbb;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,4 +7,4 @@ template(name='notification')
|
||||||
+activity(activity=activityData mode='none')
|
+activity(activity=activityData mode='none')
|
||||||
if read
|
if read
|
||||||
.remove
|
.remove
|
||||||
a.fa.fa-trash
|
a(title="{{_ 'delete'}}") 🗑️
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
template(name='notificationIcon')
|
template(name='notificationIcon')
|
||||||
if($in activityType 'deleteAttachment' 'addAttachment')
|
if($in activityType 'deleteAttachment' 'addAttachment')
|
||||||
i.fa.fa-paperclip.activity-type(title="attachment")
|
span.activity-type(title="attachment") 📎
|
||||||
else if($in activityType 'createBoard' 'importBoard')
|
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')
|
else if($in activityType 'createCard' 'importCard' 'moveCard')
|
||||||
+cardNotificationIcon
|
+cardNotificationIcon
|
||||||
|
|
@ -19,17 +19,17 @@ template(name='notificationIcon')
|
||||||
//- DRY and consistant
|
//- DRY and consistant
|
||||||
|
|
||||||
else if($in activityType 'checkedItem' 'uncheckedItem' 'addChecklistItem' 'removedChecklistItem')
|
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')
|
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')
|
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')
|
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')
|
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')
|
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')
|
else if($in activityType 'createList' 'removeList' 'archivedList')
|
||||||
+listNotificationIcon
|
+listNotificationIcon
|
||||||
|
|
@ -41,17 +41,17 @@ template(name='notificationIcon')
|
||||||
//- elswhere in the app we use fa-trello to indicate lists...
|
//- elswhere in the app we use fa-trello to indicate lists...
|
||||||
//- i personally like fa-columns a bit better
|
//- i personally like fa-columns a bit better
|
||||||
else if($in activityType 'unjoinMember' 'addBoardMember' 'joinMember' 'removeBoardMember')
|
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')
|
else if($in activityType 'createSwimlane' 'archivedSwimlane')
|
||||||
i.fa.fa-th-large.activity-type(title="swimlane")
|
span.activity-type(title="swimlane") 🧭
|
||||||
else
|
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')
|
template(name='cardNotificationIcon')
|
||||||
i.fa.fa-clone.activity-type(title="card")
|
span.activity-type(title="card") 🗒️
|
||||||
|
|
||||||
template(name='checklistNotificationIcon')
|
template(name='checklistNotificationIcon')
|
||||||
i.fa.fa-list.activity-type(title="checklist")
|
span.activity-type(title="checklist") 📝
|
||||||
|
|
||||||
template(name='listNotificationIcon')
|
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 {
|
section#notifications-drawer .remove-read:hover {
|
||||||
color: #eb4646 !important;
|
color: #eb4646 !important;
|
||||||
}
|
}
|
||||||
section#notifications-drawer .remove-read:hover i.fa {
|
|
||||||
color: inherit;
|
|
||||||
}
|
|
||||||
section#notifications-drawer ul.notifications {
|
section#notifications-drawer ul.notifications {
|
||||||
display: block;
|
display: block;
|
||||||
padding: 0px 16px 0px 16px;
|
padding: 0px 16px 0px 16px;
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ template(name='notificationsDrawer')
|
||||||
h5 {{_ 'notifications'}}
|
h5 {{_ 'notifications'}}
|
||||||
if($gt unreadNotifications 0)
|
if($gt unreadNotifications 0)
|
||||||
|(#{unreadNotifications})
|
|(#{unreadNotifications})
|
||||||
a.fa.fa-times-thin.close
|
a.close ❌
|
||||||
ul.notifications
|
ul.notifications
|
||||||
each transformedProfile.notifications
|
each transformedProfile.notifications
|
||||||
+notification(activityData=activityObj index=dbIndex read=read)
|
+notification(activityData=activityObj index=dbIndex read=read)
|
||||||
|
|
@ -16,5 +16,5 @@ template(name='notificationsDrawer')
|
||||||
a.all-read {{_ 'mark-all-as-read'}}
|
a.all-read {{_ 'mark-all-as-read'}}
|
||||||
if ($and ($.Session.get 'showReadNotifications') ($gt readNotifications 0))
|
if ($and ($.Session.get 'showReadNotifications') ($gt readNotifications 0))
|
||||||
a.remove-read
|
a.remove-read
|
||||||
i.fa.fa-trash
|
| 🗑️
|
||||||
| {{_ 'remove-all-read'}}
|
| {{_ 'remove-all-read'}}
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@ template(name="filterSidebar")
|
||||||
else
|
else
|
||||||
span.quiet {{_ "label-default" (_ (concat "color-" color))}}
|
span.quiet {{_ "label-default" (_ (concat "color-" color))}}
|
||||||
if Filter.labelIds.isSelected _id
|
if Filter.labelIds.isSelected _id
|
||||||
i.fa.fa-check
|
| ✅
|
||||||
hr
|
hr
|
||||||
h3
|
h3
|
||||||
| 👥
|
| 👥
|
||||||
|
|
@ -68,7 +68,7 @@ template(name="filterSidebar")
|
||||||
span.sidebar-list-item-description
|
span.sidebar-list-item-description
|
||||||
| {{_ 'filter-no-assignee'}}
|
| {{_ 'filter-no-assignee'}}
|
||||||
if Filter.assignees.isSelected undefined
|
if Filter.assignees.isSelected undefined
|
||||||
i.fa.fa-check
|
| ✅
|
||||||
each currentBoard.activeMembers
|
each currentBoard.activeMembers
|
||||||
with getUser userId
|
with getUser userId
|
||||||
li(class="{{#if Filter.assignees.isSelected _id}}active{{/if}}")
|
li(class="{{#if Filter.assignees.isSelected _id}}active{{/if}}")
|
||||||
|
|
@ -90,37 +90,37 @@ template(name="filterSidebar")
|
||||||
span.sidebar-list-item-description
|
span.sidebar-list-item-description
|
||||||
| {{_ 'filter-no-due-date' }}
|
| {{_ 'filter-no-due-date' }}
|
||||||
if Filter.dueAt.isSelected 'noDate'
|
if Filter.dueAt.isSelected 'noDate'
|
||||||
i.fa.fa-check
|
| ✅
|
||||||
li(class="{{#if Filter.dueAt.isSelected 'past'}}active{{/if}}")
|
li(class="{{#if Filter.dueAt.isSelected 'past'}}active{{/if}}")
|
||||||
a.name.js-toggle-overdue-filter
|
a.name.js-toggle-overdue-filter
|
||||||
span.sidebar-list-item-description
|
span.sidebar-list-item-description
|
||||||
| {{_ 'filter-overdue' }}
|
| {{_ 'filter-overdue' }}
|
||||||
if Filter.dueAt.isSelected 'past'
|
if Filter.dueAt.isSelected 'past'
|
||||||
i.fa.fa-check
|
| ✅
|
||||||
li(class="{{#if Filter.dueAt.isSelected 'today'}}active{{/if}}")
|
li(class="{{#if Filter.dueAt.isSelected 'today'}}active{{/if}}")
|
||||||
a.name.js-toggle-due-today-filter
|
a.name.js-toggle-due-today-filter
|
||||||
span.sidebar-list-item-description
|
span.sidebar-list-item-description
|
||||||
| {{_ 'filter-due-today' }}
|
| {{_ 'filter-due-today' }}
|
||||||
if Filter.dueAt.isSelected 'today'
|
if Filter.dueAt.isSelected 'today'
|
||||||
i.fa.fa-check
|
| ✅
|
||||||
li(class="{{#if Filter.dueAt.isSelected 'tomorrow'}}active{{/if}}")
|
li(class="{{#if Filter.dueAt.isSelected 'tomorrow'}}active{{/if}}")
|
||||||
a.name.js-toggle-due-tomorrow-filter
|
a.name.js-toggle-due-tomorrow-filter
|
||||||
span.sidebar-list-item-description
|
span.sidebar-list-item-description
|
||||||
| {{_ 'filter-due-tomorrow' }}
|
| {{_ 'filter-due-tomorrow' }}
|
||||||
if Filter.dueAt.isSelected 'tomorrow'
|
if Filter.dueAt.isSelected 'tomorrow'
|
||||||
i.fa.fa-check
|
| ✅
|
||||||
li(class="{{#if Filter.dueAt.isSelected 'thisweek'}}active{{/if}}")
|
li(class="{{#if Filter.dueAt.isSelected 'thisweek'}}active{{/if}}")
|
||||||
a.name.js-toggle-due-this-week-filter
|
a.name.js-toggle-due-this-week-filter
|
||||||
span.sidebar-list-item-description
|
span.sidebar-list-item-description
|
||||||
| {{_ 'filter-due-this-week' }}
|
| {{_ 'filter-due-this-week' }}
|
||||||
if Filter.dueAt.isSelected 'thisweek'
|
if Filter.dueAt.isSelected 'thisweek'
|
||||||
i.fa.fa-check
|
| ✅
|
||||||
li(class="{{#if Filter.dueAt.isSelected 'nextweek'}}active{{/if}}")
|
li(class="{{#if Filter.dueAt.isSelected 'nextweek'}}active{{/if}}")
|
||||||
a.name.js-toggle-due-next-week-filter
|
a.name.js-toggle-due-next-week-filter
|
||||||
span.sidebar-list-item-description
|
span.sidebar-list-item-description
|
||||||
| {{_ 'filter-due-next-week' }}
|
| {{_ 'filter-due-next-week' }}
|
||||||
if Filter.dueAt.isSelected 'nextweek'
|
if Filter.dueAt.isSelected 'nextweek'
|
||||||
i.fa.fa-check
|
| ✅
|
||||||
hr
|
hr
|
||||||
h3
|
h3
|
||||||
| 📋
|
| 📋
|
||||||
|
|
@ -138,7 +138,7 @@ template(name="filterSidebar")
|
||||||
span.sidebar-list-item-description
|
span.sidebar-list-item-description
|
||||||
| {{ name }}
|
| {{ name }}
|
||||||
if Filter.customFields.isSelected _id
|
if Filter.customFields.isSelected _id
|
||||||
i.fa.fa-check
|
| ✅
|
||||||
hr
|
hr
|
||||||
h3
|
h3
|
||||||
| {{_ 'other-filters-label'}}
|
| {{_ 'other-filters-label'}}
|
||||||
|
|
@ -148,14 +148,14 @@ template(name="filterSidebar")
|
||||||
span.sidebar-list-item-description
|
span.sidebar-list-item-description
|
||||||
| {{_ 'filter-show-archive'}}
|
| {{_ 'filter-show-archive'}}
|
||||||
if Filter.archive.isSelected _id
|
if Filter.archive.isSelected _id
|
||||||
i.fa.fa-check
|
| ✅
|
||||||
ul.sidebar-list
|
ul.sidebar-list
|
||||||
li(class="{{#if Filter.hideEmpty.isSelected _id}}active{{/if}}")
|
li(class="{{#if Filter.hideEmpty.isSelected _id}}active{{/if}}")
|
||||||
a.name.js-toggle-hideEmpty-filter
|
a.name.js-toggle-hideEmpty-filter
|
||||||
span.sidebar-list-item-description
|
span.sidebar-list-item-description
|
||||||
| {{_ 'filter-hide-empty'}}
|
| {{_ 'filter-hide-empty'}}
|
||||||
if Filter.hideEmpty.isSelected _id
|
if Filter.hideEmpty.isSelected _id
|
||||||
i.fa.fa-check
|
| ✅
|
||||||
hr
|
hr
|
||||||
h3 {{_ 'advanced-filter-label'}}
|
h3 {{_ 'advanced-filter-label'}}
|
||||||
input.js-field-advanced-filter(type="text")
|
input.js-field-advanced-filter(type="text")
|
||||||
|
|
|
||||||
|
|
@ -28,23 +28,14 @@ template(name="swimlaneFixedHeader")
|
||||||
unless currentUser.isWorker
|
unless currentUser.isWorker
|
||||||
a.js-open-add-swimlane-menu.swimlane-header-plus-icon(title="{{_ 'add-swimlane'}}")
|
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
|
unless isTouchScreen
|
||||||
a.swimlane-header-handle.handle.js-swimlane-header-handle
|
a.swimlane-header-handle.handle.js-swimlane-header-handle
|
||||||
| ↕️
|
| ↕️
|
||||||
if isTouchScreen
|
if isTouchScreen
|
||||||
a.swimlane-header-miniscreen-handle.handle.js-swimlane-header-handle
|
a.swimlane-header-miniscreen-handle.handle.js-swimlane-header-handle
|
||||||
| ↕️
|
| ↕️
|
||||||
|
a.js-open-swimlane-menu(title="{{_ 'swimlaneActionPopup-title'}}")
|
||||||
|
| ☰
|
||||||
|
|
||||||
template(name="editSwimlaneTitleForm")
|
template(name="editSwimlaneTitleForm")
|
||||||
.list-composer
|
.list-composer
|
||||||
|
|
|
||||||
|
|
@ -54,12 +54,14 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
min-width: 100%;
|
min-width: 100%;
|
||||||
position: relative;
|
position: relative;
|
||||||
overflow: hidden;
|
overflow: visible;
|
||||||
min-height: 33px;
|
min-height: 33px;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
.swimlane .swimlane-header-wrap .swimlane-header {
|
.swimlane .swimlane-header-wrap .swimlane-header {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
padding: 5px 5px;
|
padding: 0;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
min-height: 33px;
|
min-height: 33px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|
@ -74,30 +76,39 @@
|
||||||
}
|
}
|
||||||
.swimlane .swimlane-header-wrap .swimlane-header-menu {
|
.swimlane .swimlane-header-wrap .swimlane-header-menu {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
padding: 5px 5px;
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
|
line-height: 1;
|
||||||
z-index: 20;
|
z-index: 20;
|
||||||
pointer-events: auto;
|
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 {
|
@media print {
|
||||||
.swimlane .swimlane-header-wrap .swimlane-header-menu {
|
.swimlane .swimlane-header-wrap .swimlane-header-menu {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.swimlane .swimlane-header-wrap .swimlane-header-plus-icon {
|
.swimlane .swimlane-header-wrap .swimlane-header-plus-icon {
|
||||||
margin-left: 5px;
|
top: calc(50% + 6px);
|
||||||
padding-right: 20px;
|
padding: 5px;
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
}
|
}
|
||||||
.swimlane .swimlane-header-wrap .swimlane-header-menu-icon {
|
.swimlane .swimlane-header-wrap .swimlane-header-menu-icon {
|
||||||
padding-right: 20px;
|
top: calc(50% + 6px);
|
||||||
|
padding: 5px;
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
}
|
}
|
||||||
.swimlane .swimlane-header-wrap .swimlane-header-handle {
|
.swimlane .swimlane-header-wrap .swimlane-header-handle {
|
||||||
position: absolute;
|
top: calc(50% + 2px);
|
||||||
padding: 7px;
|
padding: 2px;
|
||||||
top: 50%;
|
|
||||||
left: 230px;
|
|
||||||
font-size: clamp(16px, 3vw, 20px);
|
font-size: clamp(16px, 3vw, 20px);
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|
@ -109,22 +120,16 @@
|
||||||
}
|
}
|
||||||
.swimlane .swimlane-header-wrap .swimlane-header-miniscreen-handle {
|
.swimlane .swimlane-header-wrap .swimlane-header-miniscreen-handle {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
padding: 7px;
|
padding: 2px;
|
||||||
top: 50%;
|
top: calc(50% + 2px);
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
right: 10px;
|
right: 60px;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
cursor: move;
|
cursor: move;
|
||||||
z-index: 15;
|
z-index: 15;
|
||||||
pointer-events: auto;
|
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 {
|
#js-swimlane-height-edit .swimlane-height-error {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
display: block;
|
display: block;
|
||||||
position: relative;
|
position: relative;
|
||||||
float: left;
|
float: left;
|
||||||
height: 30px;
|
height: clamp(24px, 3.5vw, 36px);
|
||||||
width: 30px;
|
width: clamp(24px, 3.5vw, 36px);
|
||||||
margin: .3vh;
|
margin: .3vh;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
@ -111,7 +111,7 @@
|
||||||
padding-top: 0;
|
padding-top: 0;
|
||||||
}
|
}
|
||||||
.mini-profile-info .member {
|
.mini-profile-info .member {
|
||||||
width: 50px;
|
width: clamp(40px, 5vw, 60px);
|
||||||
height: 50px;
|
height: clamp(40px, 5vw, 60px);
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue