mirror of
https://github.com/wekan/wekan.git
synced 2026-01-26 03:06:09 +01:00
Merge branch 'master' of https://github.com/wekan/wekan
This commit is contained in:
commit
0ce2f9ea43
204 changed files with 13619 additions and 2379 deletions
|
|
@ -766,7 +766,15 @@ setBoardClear(color1,color2)
|
|||
.toggle-label:after, .board-color-modern .toggle-switch:checked~.toggle-label:after
|
||||
background-color: #819C5D !important
|
||||
|
||||
button, input:not([type=file]), select, textarea
|
||||
border-radius: 2px
|
||||
|
||||
/* Headers */
|
||||
&#header
|
||||
background-color: #262626
|
||||
border-bottom: 1px solid #555555;
|
||||
border-top: 1px solid #555555;
|
||||
|
||||
&#header-quick-access, .background-box, #header
|
||||
background-color: #333333
|
||||
|
||||
|
|
@ -774,14 +782,16 @@ setBoardClear(color1,color2)
|
|||
padding: 4px
|
||||
font-size: 14px
|
||||
|
||||
&#header-quick-access .allBoards
|
||||
padding: 5px 10px 0 10px;
|
||||
|
||||
&#header-quick-access ul.header-quick-access-list
|
||||
margin: -5px 0 -5px 0
|
||||
|
||||
&#header #header-main-bar
|
||||
height: 30px
|
||||
padding-top: 3px
|
||||
padding-bottom: 3px
|
||||
|
||||
&#header
|
||||
box-shadow: 0 6px 6px -6px rgba(0,0,0,0.8)
|
||||
|
||||
&#header-quick-access ul
|
||||
overflow: visible
|
||||
|
||||
|
|
@ -812,18 +822,23 @@ setBoardClear(color1,color2)
|
|||
/* Content */
|
||||
.board-canvas
|
||||
background: #2a2a2a
|
||||
padding: 10px 10px 0
|
||||
|
||||
/* Swimlanes */
|
||||
.swimlane .swimlane-header-wrap
|
||||
background-color: #666666
|
||||
background-color: #494949
|
||||
color: #cccccc
|
||||
padding: 4px 0
|
||||
margin-bottom: 10px
|
||||
|
||||
.swimlane .swimlane-header-wrap .swimlane-header
|
||||
font-family: Poppins
|
||||
|
||||
.swimlane .swimlane-header-wrap .swimlane-header-menu
|
||||
padding: 6px
|
||||
font-size: 16px
|
||||
|
||||
.swimlane .swimlane-header-wrap .swimlane-header-plus-icon
|
||||
font-size: 16px
|
||||
|
||||
.swimlane
|
||||
background: #2a2a2a
|
||||
line-height: 15px
|
||||
|
|
@ -836,13 +851,19 @@ setBoardClear(color1,color2)
|
|||
border: 0px solid #666666
|
||||
flex: 0 0 265px;
|
||||
|
||||
.swimlane .list:first-child
|
||||
margin-left: 0
|
||||
|
||||
.swimlane .list:nth-child(even)
|
||||
background: #5f5f5f
|
||||
|
||||
.swimlane .list:nth-child(odd) .list-header
|
||||
background: #3b3b3b
|
||||
|
||||
.list-header
|
||||
background: #333333
|
||||
padding-top: 10px
|
||||
border-bottom: 6px solid #333333
|
||||
padding: 10px
|
||||
border-bottom: 0
|
||||
|
||||
.list-header .viewer
|
||||
padding-left: 10px
|
||||
|
|
@ -852,7 +873,11 @@ setBoardClear(color1,color2)
|
|||
color: #eeeeee
|
||||
|
||||
.list-header .list-header-menu
|
||||
padding-top: 17px
|
||||
padding: 10px
|
||||
top: 0
|
||||
|
||||
.list-header .list-header-plus-icon
|
||||
color: #a6a6a6
|
||||
|
||||
.list-body
|
||||
scrollbar-width: thin
|
||||
|
|
@ -883,35 +908,43 @@ setBoardClear(color1,color2)
|
|||
color: #ffffff
|
||||
|
||||
/* Mini Card */
|
||||
.minicard-wrapper
|
||||
margin-bottom: 12px
|
||||
|
||||
.minicard
|
||||
background-color: #444444
|
||||
color: #cccccc
|
||||
border-radius: 2px
|
||||
font-size: 0.9em
|
||||
font-size: 0.95em
|
||||
padding: 10px
|
||||
box-shadow: 0 4px 3px -3px rgba(0,0,0,0.8)
|
||||
border-bottom: 1px solid #666666
|
||||
|
||||
.minicard:hover
|
||||
background-color: #555555 !important
|
||||
background-color: #494949 !important
|
||||
|
||||
.minicard .minicard-labels
|
||||
margin-bottom: 4px
|
||||
|
||||
.minicard .card-label
|
||||
font-size: 11px
|
||||
font-weight: 400
|
||||
padding: 2px 6px 0
|
||||
padding: 1px 6px 0
|
||||
border-radius: 2px
|
||||
|
||||
.minicard .badges
|
||||
color: #bbbbbb
|
||||
|
||||
.minicard .date
|
||||
margin-top: 7px
|
||||
margin-top: 10px
|
||||
font-size: 11px
|
||||
|
||||
.card-date
|
||||
color: #555555
|
||||
color: #444444
|
||||
border-radius: 2px
|
||||
|
||||
.card-date.almost-due
|
||||
color: #666666
|
||||
color: #444444
|
||||
|
||||
.minicard.minicard-composer textarea.minicard-composer-textarea:focus
|
||||
background-color: #eeeeee
|
||||
|
|
@ -970,11 +1003,17 @@ setBoardClear(color1,color2)
|
|||
|
||||
.card-details .checklist-item
|
||||
background-color: rgba(255,255,255,0.1)
|
||||
padding: 2px 8px
|
||||
border-radius: 3px
|
||||
padding: 4px 8px
|
||||
border-radius: 2px
|
||||
font-size: 13px
|
||||
margin-top: 5px
|
||||
|
||||
.card-details .checklist-item:hover
|
||||
background-color: rgba(255,255,255,0.2)
|
||||
|
||||
.card-details .checklist-item .item-title .viewer p
|
||||
max-width: auto
|
||||
|
||||
.card-details .check-box.materialCheckBox
|
||||
border-color: #ffffff
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
template(name="boardHeaderBar")
|
||||
h1.header-board-menu
|
||||
with currentBoard
|
||||
+viewer
|
||||
= title
|
||||
if $eq title 'Templates'
|
||||
| {{_ 'templates'}}
|
||||
else
|
||||
+viewer
|
||||
= title
|
||||
|
||||
.board-header-btns.left
|
||||
unless isMiniScreen
|
||||
|
|
@ -131,7 +134,7 @@ template(name="boardHeaderBar")
|
|||
i.fa.fa-times-thin
|
||||
|
||||
.separator
|
||||
a.board-header-btn.js-toggle-sidebar
|
||||
a.board-header-btn.js-toggle-sidebar(title="{{_ 'sidebar-open'}} {{_ 'or'}} {{_ 'sidebar-close'}}")
|
||||
i.fa.fa-navicon
|
||||
|
||||
template(name="boardVisibilityList")
|
||||
|
|
@ -225,6 +228,9 @@ template(name="createBoard")
|
|||
= " "
|
||||
| {{{_ 'board-private-info'}}}
|
||||
a.js-change-visibility {{_ 'change'}}.
|
||||
//a.flex.js-toggle-add-template-container
|
||||
// .materialCheckBox#add-template-container
|
||||
// span {{_ 'add-template-container'}}
|
||||
input.primary.wide(type="submit" value="{{_ 'create'}}")
|
||||
span.quiet
|
||||
| {{_ 'or'}}
|
||||
|
|
|
|||
|
|
@ -209,24 +209,79 @@ const CreateBoard = BlazeComponent.extendComponent({
|
|||
this.visibilityMenuIsOpen.set(!this.visibilityMenuIsOpen.get());
|
||||
},
|
||||
|
||||
toggleAddTemplateContainer() {
|
||||
$('#add-template-container').toggleClass('is-checked');
|
||||
},
|
||||
|
||||
onSubmit(event) {
|
||||
event.preventDefault();
|
||||
const title = this.find('.js-new-board-title').value;
|
||||
const visibility = this.visibility.get();
|
||||
|
||||
this.boardId.set(
|
||||
Boards.insert({
|
||||
title,
|
||||
permission: visibility,
|
||||
}),
|
||||
);
|
||||
const addTemplateContainer = $('#add-template-container.is-checked').length > 0;
|
||||
if (addTemplateContainer) {
|
||||
//const templateContainerId = Meteor.call('setCreateTemplateContainer');
|
||||
//Utils.goBoardId(templateContainerId);
|
||||
//alert('niinku template ' + Meteor.call('setCreateTemplateContainer'));
|
||||
|
||||
Swimlanes.insert({
|
||||
title: 'Default',
|
||||
boardId: this.boardId.get(),
|
||||
});
|
||||
this.boardId.set(
|
||||
Boards.insert({
|
||||
// title: TAPi18n.__('templates'),
|
||||
title: title,
|
||||
permission: 'private',
|
||||
type: 'template-container',
|
||||
}),
|
||||
);
|
||||
|
||||
Utils.goBoardId(this.boardId.get());
|
||||
// Insert the card templates swimlane
|
||||
Swimlanes.insert({
|
||||
// title: TAPi18n.__('card-templates-swimlane'),
|
||||
title: 'Card Templates',
|
||||
boardId: this.boardId.get(),
|
||||
sort: 1,
|
||||
type: 'template-container',
|
||||
}),
|
||||
|
||||
// Insert the list templates swimlane
|
||||
Swimlanes.insert(
|
||||
{
|
||||
// title: TAPi18n.__('list-templates-swimlane'),
|
||||
title: 'List Templates',
|
||||
boardId: this.boardId.get(),
|
||||
sort: 2,
|
||||
type: 'template-container',
|
||||
},
|
||||
);
|
||||
|
||||
// Insert the board templates swimlane
|
||||
Swimlanes.insert(
|
||||
{
|
||||
//title: TAPi18n.__('board-templates-swimlane'),
|
||||
title: 'Board Templates',
|
||||
boardId: this.boardId.get(),
|
||||
sort: 3,
|
||||
type: 'template-container',
|
||||
},
|
||||
);
|
||||
|
||||
Utils.goBoardId(this.boardId.get());
|
||||
|
||||
} else {
|
||||
const visibility = this.visibility.get();
|
||||
|
||||
this.boardId.set(
|
||||
Boards.insert({
|
||||
title,
|
||||
permission: visibility,
|
||||
}),
|
||||
);
|
||||
|
||||
Swimlanes.insert({
|
||||
title: 'Default',
|
||||
boardId: this.boardId.get(),
|
||||
});
|
||||
|
||||
Utils.goBoardId(this.boardId.get());
|
||||
}
|
||||
},
|
||||
|
||||
events() {
|
||||
|
|
@ -240,6 +295,7 @@ const CreateBoard = BlazeComponent.extendComponent({
|
|||
submit: this.onSubmit,
|
||||
'click .js-import-board': Popup.open('chooseBoardSource'),
|
||||
'click .js-board-template': Popup.open('searchElement'),
|
||||
'click .js-toggle-add-template-container': this.toggleAddTemplateContainer,
|
||||
},
|
||||
];
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ template(name="boardList")
|
|||
.wrapper
|
||||
ul.board-list.clearfix.js-boards
|
||||
li.js-add-board
|
||||
a.board-list-item.label {{_ 'add-board'}}
|
||||
a.board-list-item.label(title="{{_ 'add-board'}}")
|
||||
| {{_ 'add-board'}}
|
||||
each boards
|
||||
li(class="{{#if isStarred}}starred{{/if}}" class=colorClass).js-board
|
||||
if isInvited
|
||||
|
|
@ -16,47 +17,90 @@ template(name="boardList")
|
|||
button.js-accept-invite.primary {{_ 'accept'}}
|
||||
button.js-decline-invite {{_ 'decline'}}
|
||||
else
|
||||
a.js-open-board.board-list-item(href="{{pathFor 'board' id=_id slug=slug}}")
|
||||
span.details
|
||||
span.board-list-item-name
|
||||
+viewer
|
||||
= title
|
||||
i.fa.js-star-board(
|
||||
class="fa-star{{#if isStarred}} is-star-active{{else}}-o{{/if}}"
|
||||
title="{{_ 'star-board-title'}}")
|
||||
p.board-list-item-desc
|
||||
+viewer
|
||||
= description
|
||||
if hasSpentTimeCards
|
||||
i.fa.js-has-spenttime-cards(
|
||||
class="fa-circle{{#if hasOvertimeCards}} has-overtime-card-active{{else}} no-overtime-card-active{{/if}}"
|
||||
title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}")
|
||||
if isMiniScreen
|
||||
i.fa.board-handle(
|
||||
class="fa-arrows"
|
||||
title="{{_ 'Drag board'}}")
|
||||
unless isMiniScreen
|
||||
if isSandstorm
|
||||
i.fa.js-clone-board(
|
||||
class="fa-clone"
|
||||
title="{{_ 'duplicate-board'}}")
|
||||
i.fa.js-archive-board(
|
||||
class="fa-archive"
|
||||
title="{{_ 'archive-board'}}")
|
||||
else if isAdministrable
|
||||
i.fa.js-clone-board(
|
||||
class="fa-clone"
|
||||
title="{{_ 'duplicate-board'}}")
|
||||
i.fa.js-archive-board(
|
||||
class="fa-archive"
|
||||
title="{{_ 'archive-board'}}")
|
||||
else if currentUser.isAdmin
|
||||
i.fa.js-clone-board(
|
||||
class="fa-clone"
|
||||
title="{{_ 'duplicate-board'}}")
|
||||
i.fa.js-archive-board(
|
||||
class="fa-archive"
|
||||
title="{{_ 'archive-board'}}")
|
||||
if $eq type "template-container"
|
||||
a.js-open-board.template-container.board-list-item(href="{{pathFor 'board' id=_id slug=slug}}")
|
||||
span.details
|
||||
span.board-list-item-name(title="{{_ 'template-container'}}")
|
||||
+viewer
|
||||
= title
|
||||
i.fa.js-star-board(
|
||||
class="fa-star{{#if isStarred}} is-star-active{{else}}-o{{/if}}"
|
||||
title="{{_ 'star-board-title'}}")
|
||||
p.board-list-item-desc
|
||||
+viewer
|
||||
= description
|
||||
if hasSpentTimeCards
|
||||
i.fa.js-has-spenttime-cards(
|
||||
class="fa-circle{{#if hasOvertimeCards}} has-overtime-card-active{{else}} no-overtime-card-active{{/if}}"
|
||||
title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}")
|
||||
if isMiniScreen
|
||||
i.fa.board-handle(
|
||||
class="fa-arrows"
|
||||
title="{{_ 'Drag board'}}")
|
||||
unless isMiniScreen
|
||||
if isSandstorm
|
||||
i.fa.js-clone-board(
|
||||
class="fa-clone"
|
||||
title="{{_ 'duplicate-board'}}")
|
||||
i.fa.js-archive-board(
|
||||
class="fa-archive"
|
||||
title="{{_ 'archive-board'}}")
|
||||
else if isAdministrable
|
||||
i.fa.js-clone-board(
|
||||
class="fa-clone"
|
||||
title="{{_ 'duplicate-board'}}")
|
||||
i.fa.js-archive-board(
|
||||
class="fa-archive"
|
||||
title="{{_ 'archive-board'}}")
|
||||
else if currentUser.isAdmin
|
||||
i.fa.js-clone-board(
|
||||
class="fa-clone"
|
||||
title="{{_ 'duplicate-board'}}")
|
||||
i.fa.js-archive-board(
|
||||
class="fa-archive"
|
||||
title="{{_ 'archive-board'}}")
|
||||
else
|
||||
a.js-open-board.board-list-item(href="{{pathFor 'board' id=_id slug=slug}}")
|
||||
span.details
|
||||
span.board-list-item-name(title="{{_ 'board-drag-drop-reorder-or-click-open'}}")
|
||||
+viewer
|
||||
= title
|
||||
i.fa.js-star-board(
|
||||
class="fa-star{{#if isStarred}} is-star-active{{else}}-o{{/if}}"
|
||||
title="{{_ 'star-board-title'}}")
|
||||
p.board-list-item-desc
|
||||
+viewer
|
||||
= description
|
||||
if hasSpentTimeCards
|
||||
i.fa.js-has-spenttime-cards(
|
||||
class="fa-circle{{#if hasOvertimeCards}} has-overtime-card-active{{else}} no-overtime-card-active{{/if}}"
|
||||
title="{{#if hasOvertimeCards}}{{_ 'has-overtime-cards'}}{{else}}{{_ 'has-spenttime-cards'}}{{/if}}")
|
||||
if isMiniScreen
|
||||
i.fa.board-handle(
|
||||
class="fa-arrows"
|
||||
title="{{_ 'Drag board'}}")
|
||||
unless isMiniScreen
|
||||
if isSandstorm
|
||||
i.fa.js-clone-board(
|
||||
class="fa-clone"
|
||||
title="{{_ 'duplicate-board'}}")
|
||||
i.fa.js-archive-board(
|
||||
class="fa-archive"
|
||||
title="{{_ 'archive-board'}}")
|
||||
else if isAdministrable
|
||||
i.fa.js-clone-board(
|
||||
class="fa-clone"
|
||||
title="{{_ 'duplicate-board'}}")
|
||||
i.fa.js-archive-board(
|
||||
class="fa-archive"
|
||||
title="{{_ 'archive-board'}}")
|
||||
else if currentUser.isAdmin
|
||||
i.fa.js-clone-board(
|
||||
class="fa-clone"
|
||||
title="{{_ 'duplicate-board'}}")
|
||||
i.fa.js-archive-board(
|
||||
class="fa-archive"
|
||||
title="{{_ 'archive-board'}}")
|
||||
|
||||
template(name="boardListHeaderBar")
|
||||
h1 {{_ title }}
|
||||
|
|
|
|||
|
|
@ -22,6 +22,15 @@ Template.boardListHeaderBar.helpers({
|
|||
BlazeComponent.extendComponent({
|
||||
onCreated() {
|
||||
Meteor.subscribe('setting');
|
||||
let currUser = Meteor.user();
|
||||
let userLanguage;
|
||||
if(currUser && currUser.profile){
|
||||
userLanguage = currUser.profile.language
|
||||
}
|
||||
if (userLanguage) {
|
||||
TAPi18n.setLanguage(userLanguage);
|
||||
T9n.setLanguage(userLanguage);
|
||||
}
|
||||
},
|
||||
|
||||
onRendered() {
|
||||
|
|
@ -79,6 +88,7 @@ BlazeComponent.extendComponent({
|
|||
boards() {
|
||||
const query = {
|
||||
archived: false,
|
||||
//type: { $in: ['board','template-container'] },
|
||||
type: 'board',
|
||||
};
|
||||
if (FlowRouter.getRouteName() === 'home')
|
||||
|
|
|
|||
|
|
@ -45,6 +45,9 @@ $spaceBetweenTiles = 16px
|
|||
text-decoration: none
|
||||
word-wrap: break-word
|
||||
|
||||
&.template-container
|
||||
border: 4px solid #fff
|
||||
|
||||
&.tile
|
||||
background-size: auto
|
||||
background-repeat: repeat
|
||||
|
|
|
|||
|
|
@ -55,6 +55,5 @@ template(name="attachmentsGalery")
|
|||
unless currentUser.isCommentOnly
|
||||
unless currentUser.isWorker
|
||||
//li.attachment-item.add-attachment
|
||||
a.js-add-attachment
|
||||
a.js-add-attachment(title="{{_ 'add-attachment' }}")
|
||||
i.fa.fa-plus
|
||||
| {{_ 'add-attachment' }}
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ template(name="cardCustomField-stringtemplate")
|
|||
+inlinedForm(classNames="js-card-customfield-stringtemplate")
|
||||
each item in stringtemplateItems.get
|
||||
input.js-card-customfield-stringtemplate-item(type="text" value=item placeholder="")
|
||||
input.js-card-customfield-stringtemplate-item.last(type="text" value="" placeholder="{{_ 'custom-field-stringtemplate-item-placeholder'}}")
|
||||
input.js-card-customfield-stringtemplate-item.last(type="text" value="" placeholder="{{_ 'custom-field-stringtemplate-item-placeholder'}}" autofocus)
|
||||
.edit-controls.clearfix
|
||||
button.primary(type="submit") {{_ 'save'}}
|
||||
a.fa.fa-times-thin.js-close-inlined-form
|
||||
|
|
|
|||
|
|
@ -354,3 +354,30 @@ class VoteEndDate extends CardDate {
|
|||
}
|
||||
}
|
||||
VoteEndDate.register('voteEndDate');
|
||||
|
||||
class PokerEndDate extends CardDate {
|
||||
onCreated() {
|
||||
super.onCreated();
|
||||
const self = this;
|
||||
self.autorun(() => {
|
||||
self.date.set(moment(self.data().getPokerEnd()));
|
||||
});
|
||||
}
|
||||
classes() {
|
||||
const classes = 'end-date' + ' ';
|
||||
return classes;
|
||||
}
|
||||
showDate() {
|
||||
return this.date.get().format('l LT');
|
||||
}
|
||||
showTitle() {
|
||||
return `${TAPi18n.__('card-end-on')} ${this.date.get().format('LLLL')}`;
|
||||
}
|
||||
|
||||
events() {
|
||||
return super.events().concat({
|
||||
'click .js-edit-date': Popup.open('editPokerEndDate'),
|
||||
});
|
||||
}
|
||||
}
|
||||
PokerEndDate.register('pokerEndDate');
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
background-color: #fff
|
||||
border: 0
|
||||
box-shadow: 0 1px 2px rgba(0, 0, 0, .23)
|
||||
color: #8c8c8c
|
||||
height: 36px
|
||||
margin: 4px 4px 6px 0
|
||||
padding: 9px 11px
|
||||
|
|
|
|||
|
|
@ -1,22 +1,26 @@
|
|||
template(name="cardDetails")
|
||||
section.card-details.js-card-details: .card-details-canvas
|
||||
section.card-details.js-card-details(class='{{#if cardMaximized}}card-details-maximized{{/if}}'): .card-details-canvas
|
||||
.card-details-header(class='{{#if colorClass}}card-details-{{colorClass}}{{/if}}')
|
||||
+inlinedForm(classNames="js-card-details-title")
|
||||
+editCardTitleForm
|
||||
else
|
||||
unless isMiniScreen
|
||||
a.fa.fa-times-thin.close-card-details.js-close-card-details
|
||||
a.fa.fa-times-thin.close-card-details.js-close-card-details(title="{{_ 'close-card'}}")
|
||||
unless cardMaximized
|
||||
a.fa.fa-window-maximize.maximize-card-details.js-maximize-card-details(title="{{_ 'maximize-card'}}")
|
||||
if cardMaximized
|
||||
a.fa.fa-window-minimize.minimize-card-details.js-minimize-card-details(title="{{_ 'minimize-card'}}")
|
||||
if currentUser.isBoardMember
|
||||
a.fa.fa-navicon.card-details-menu.js-open-card-details-menu
|
||||
a.fa.fa-navicon.card-details-menu.js-open-card-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}")
|
||||
input.inline-input(type="text" id="cardURL_copy" value="{{ originRelativeUrl }}")
|
||||
a.fa.fa-link.card-copy-button.js-copy-link(
|
||||
class="fa-link"
|
||||
title="{{_ 'copy-card-link-to-clipboard'}}"
|
||||
)
|
||||
if isMiniScreen
|
||||
a.fa.fa-times-thin.close-card-details-mobile-web.js-close-card-details
|
||||
a.fa.fa-times-thin.close-card-details-mobile-web.js-close-card-details(title="{{_ 'close-card'}}")
|
||||
if currentUser.isBoardMember
|
||||
a.fa.fa-navicon.card-details-menu-mobile-web.js-open-card-details-menu
|
||||
a.fa.fa-navicon.card-details-menu-mobile-web.js-open-card-details-menu(title="{{_ 'cardDetailsActionsPopup-title'}}")
|
||||
a.fa.fa-link.card-copy-mobile-button
|
||||
h2.card-details-title.js-card-title(
|
||||
class="{{#if canModifyCard}}js-open-inlined-form is-editable{{/if}}")
|
||||
|
|
@ -41,286 +45,501 @@ template(name="cardDetails")
|
|||
else
|
||||
p.warning {{_ 'card-archived'}}
|
||||
|
||||
.card-details-items
|
||||
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
|
||||
span.card-label(class="card-label-{{color}}" title=name)
|
||||
+viewer
|
||||
= name
|
||||
if canModifyCard
|
||||
unless currentUser.isWorker
|
||||
a.card-label.add-label.js-add-labels(title="{{_ 'card-labels-title'}}")
|
||||
i.fa.fa-plus
|
||||
.card-details-left
|
||||
|
||||
.card-details-items
|
||||
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
|
||||
span.card-label(class="card-label-{{color}}" title=name)
|
||||
+viewer
|
||||
= name
|
||||
if canModifyCard
|
||||
unless currentUser.isWorker
|
||||
a.card-label.add-label.js-add-labels(title="{{_ 'card-labels-title'}}")
|
||||
i.fa.fa-plus
|
||||
|
||||
if currentBoard.allowsReceivedDate
|
||||
hr
|
||||
.card-details-item.card-details-item-received
|
||||
h3.card-details-item-title
|
||||
i.fa.fa-sign-out
|
||||
| {{_ 'card-received'}}
|
||||
if getReceived
|
||||
+cardReceivedDate
|
||||
else
|
||||
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
|
||||
else
|
||||
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-sign-in
|
||||
| {{_ 'card-due'}}
|
||||
if getDue
|
||||
+cardDueDate
|
||||
else
|
||||
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
|
||||
else
|
||||
if canModifyCard
|
||||
unless currentUser.isWorker
|
||||
a.card-label.add-label.js-end-date
|
||||
i.fa.fa-plus
|
||||
|
||||
if currentBoard.allowsReceivedDate
|
||||
hr
|
||||
.card-details-item.card-details-item-received
|
||||
h3.card-details-item-title
|
||||
i.fa.fa-sign-out
|
||||
| {{_ 'card-received'}}
|
||||
if getReceived
|
||||
+cardReceivedDate
|
||||
else
|
||||
if canModifyCard
|
||||
unless currentUser.isWorker
|
||||
a.card-label.add-label.js-received-date
|
||||
i.fa.fa-plus
|
||||
if currentBoard.allowsCreator
|
||||
.card-details-item.card-details-item-creator
|
||||
h3.card-details-item-title
|
||||
i.fa.fa-user
|
||||
| {{_ 'creator'}}
|
||||
|
||||
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
|
||||
else
|
||||
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-sign-in
|
||||
| {{_ 'card-due'}}
|
||||
if getDue
|
||||
+cardDueDate
|
||||
else
|
||||
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
|
||||
else
|
||||
if canModifyCard
|
||||
unless currentUser.isWorker
|
||||
a.card-label.add-label.js-end-date
|
||||
i.fa.fa-plus
|
||||
|
||||
hr
|
||||
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)
|
||||
| {{! XXX Hack to hide syntaxic coloration /// }}
|
||||
|
||||
//.card-details-items
|
||||
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)
|
||||
+userAvatar(userId=userId noRemove=true)
|
||||
| {{! XXX Hack to hide syntaxic coloration /// }}
|
||||
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
|
||||
//.card-details-items
|
||||
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)
|
||||
| {{! XXX Hack to hide syntaxic coloration /// }}
|
||||
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 getSpentTime
|
||||
.card-details-item.card-details-item-spent
|
||||
if getIsOvertime
|
||||
h3.card-details-item-title
|
||||
| {{_ 'overtime-hours'}}
|
||||
else
|
||||
h3.card-details-item-title
|
||||
| {{_ 'spent-time-hours'}}
|
||||
+cardSpentTime
|
||||
//.card-details-items
|
||||
if getSpentTime
|
||||
.card-details-item.card-details-item-spent
|
||||
if getIsOvertime
|
||||
h3.card-details-item-title
|
||||
| {{_ 'overtime-hours'}}
|
||||
else
|
||||
h3.card-details-item-title
|
||||
| {{_ 'spent-time-hours'}}
|
||||
+cardSpentTime
|
||||
|
||||
//.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
|
||||
+inlinedForm(classNames="js-card-details-requester")
|
||||
+editCardRequesterForm
|
||||
//.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
|
||||
+inlinedForm(classNames="js-card-details-requester")
|
||||
+editCardRequesterForm
|
||||
else
|
||||
a.js-open-inlined-form
|
||||
if getRequestedBy
|
||||
+viewer
|
||||
= getRequestedBy
|
||||
else
|
||||
| {{_ 'add'}}
|
||||
else if getRequestedBy
|
||||
+viewer
|
||||
= getRequestedBy
|
||||
|
||||
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
|
||||
+inlinedForm(classNames="js-card-details-assigner")
|
||||
+editCardAssignerForm
|
||||
else
|
||||
a.js-open-inlined-form
|
||||
if getAssignedBy
|
||||
+viewer
|
||||
= getAssignedBy
|
||||
else
|
||||
| {{_ 'add'}}
|
||||
else if getRequestedBy
|
||||
+viewer
|
||||
= getAssignedBy
|
||||
|
||||
if currentBoard.allowsCardSortingByNumber
|
||||
.card-details-item.card-details-sort-order
|
||||
h3.card-details-item-title
|
||||
i.fa.fa-sort
|
||||
| {{_ 'sort'}}
|
||||
if canModifyCard
|
||||
+inlinedForm(classNames="js-card-details-sort")
|
||||
+editCardSortOrderForm
|
||||
else
|
||||
a.js-open-inlined-form
|
||||
if getRequestedBy
|
||||
+viewer
|
||||
= getRequestedBy
|
||||
else
|
||||
| {{_ 'add'}}
|
||||
else if getRequestedBy
|
||||
+viewer
|
||||
= getRequestedBy
|
||||
+viewer
|
||||
= sort
|
||||
|
||||
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
|
||||
+inlinedForm(classNames="js-card-details-assigner")
|
||||
+editCardAssignerForm
|
||||
else
|
||||
a.js-open-inlined-form
|
||||
if getAssignedBy
|
||||
+viewer
|
||||
= getAssignedBy
|
||||
else
|
||||
| {{_ 'add'}}
|
||||
else if getRequestedBy
|
||||
+viewer
|
||||
= getAssignedBy
|
||||
//.card-details-items
|
||||
if customFieldsWD
|
||||
hr
|
||||
each customFieldsWD
|
||||
.card-details-item.card-details-item-customfield
|
||||
h3.card-details-item-title
|
||||
i.fa.fa-list-alt
|
||||
= definition.name
|
||||
+cardCustomField
|
||||
|
||||
//.card-details-items
|
||||
if customFieldsWD
|
||||
if getVoteQuestion
|
||||
hr
|
||||
each customFieldsWD
|
||||
.card-details-item.card-details-item-customfield
|
||||
.vote-title
|
||||
div.flex
|
||||
h3
|
||||
i.fa.fa-thumbs-up
|
||||
| {{_ 'vote-question'}}
|
||||
if getVoteEnd
|
||||
+voteEndDate
|
||||
.vote-result
|
||||
if votePublic
|
||||
a.card-label.card-label-green.js-show-positive-votes {{ voteCountPositive }}
|
||||
a.card-label.card-label-red.js-show-negative-votes {{ voteCountNegative }}
|
||||
else
|
||||
.card-label.card-label-green {{ voteCountPositive }}
|
||||
.card-label.card-label-red {{ voteCountNegative }}
|
||||
unless ($and currentBoard.isPublic voteAllowNonBoardMembers )
|
||||
.card-label.card-label-gray {{ voteCount }} {{_ 'r-of' }} {{ currentBoard.activeMembers.length }}
|
||||
+viewer
|
||||
= getVoteQuestion
|
||||
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
|
||||
i.fa.fa-thumbs-down
|
||||
| {{_ 'vote-against'}}
|
||||
|
||||
if getPokerQuestion
|
||||
hr
|
||||
.poker-title
|
||||
div.flex
|
||||
h3
|
||||
i.fa.fa-thumbs-up
|
||||
| {{_ 'poker-question'}}
|
||||
if getPokerEnd
|
||||
+pokerEndDate
|
||||
div.flex
|
||||
.poker-result
|
||||
if expiredPoker
|
||||
unless ($and currentBoard.isPublic pokerAllowNonBoardMembers )
|
||||
.card-label.card-label-gray {{ pokerCount }} {{_ 'r-of' }} {{ currentBoard.activeMembers.length }}
|
||||
if showPlanningPokerButtons
|
||||
.poker-result
|
||||
.poker-deck
|
||||
.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'}}
|
||||
|
||||
if expiredPoker
|
||||
.poker-table
|
||||
.poker-table-side-left
|
||||
.poker-table-heading-left
|
||||
.poker-table-row
|
||||
.poker-table-cell
|
||||
.poker-table-cell
|
||||
| {{_ 'poker-result-votes' }}
|
||||
.poker-table-cell.poker-table-cell-who
|
||||
| {{_ 'poker-result-who' }}
|
||||
.poker-table-body
|
||||
.poker-table-row
|
||||
.poker-table-cell
|
||||
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 1}}winner{{else}}loser{{/if}}") {{_ 'poker-one'}}
|
||||
.poker-table-cell {{ pokerCountOne }}
|
||||
.poker-table-cell.poker-table-cell-who
|
||||
.poker-result
|
||||
each m in pokerMemberOne
|
||||
a.name
|
||||
+userAvatar(userId=m._id noRemove=true)
|
||||
|
||||
.poker-table-row
|
||||
.poker-table-cell
|
||||
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 2}}winner{{else}}loser{{/if}}") {{_ 'poker-two'}}
|
||||
.poker-table-cell {{ pokerCountTwo }}
|
||||
.poker-table-cell.poker-table-cell-who
|
||||
.poker-result
|
||||
each m in pokerMemberTwo
|
||||
a.name
|
||||
+userAvatar(userId=m._id noRemove=true)
|
||||
|
||||
.poker-table-row
|
||||
.poker-table-cell
|
||||
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 3}}winner{{else}}loser{{/if}}") {{_ 'poker-three'}}
|
||||
.poker-table-cell {{ pokerCountThree }}
|
||||
.poker-table-cell.poker-table-cell-who
|
||||
.poker-result
|
||||
each m in pokerMemberThree
|
||||
a.name
|
||||
+userAvatar(userId=m._id noRemove=true)
|
||||
|
||||
.poker-table-row
|
||||
.poker-table-cell
|
||||
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 5}}winner{{else}}loser{{/if}}") {{_ 'poker-five'}}
|
||||
.poker-table-cell {{ pokerCountFive }}
|
||||
.poker-table-cell.poker-table-cell-who
|
||||
.poker-result
|
||||
each m in pokerMemberFive
|
||||
a.name
|
||||
+userAvatar(userId=m._id noRemove=true)
|
||||
|
||||
.poker-table-row
|
||||
.poker-table-cell
|
||||
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 8}}winner{{else}}loser{{/if}}") {{_ 'poker-eight'}}
|
||||
.poker-table-cell {{ pokerCountEight }}
|
||||
.poker-table-cell.poker-table-cell-who
|
||||
.poker-result
|
||||
each m in pokerMemberEight
|
||||
a.name
|
||||
+userAvatar(userId=m._id noRemove=true)
|
||||
|
||||
.poker-table-side-right
|
||||
.poker-table-heading-right
|
||||
.poker-table-row
|
||||
.poker-table-cell
|
||||
.poker-table-cell
|
||||
| {{_ 'poker-result-votes' }}
|
||||
.poker-table-cell.poker-table-cell-who
|
||||
| {{_ 'poker-result-who' }}
|
||||
.poker-table-body
|
||||
.poker-table-row
|
||||
.poker-table-cell
|
||||
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 13}}winner{{else}}loser{{/if}}") {{_ 'poker-thirteen'}}
|
||||
.poker-table-cell {{ pokerCountThirteen }}
|
||||
.poker-table-cell.poker-table-cell-who
|
||||
.poker-result
|
||||
each m in pokerMemberThirteen
|
||||
a.name
|
||||
+userAvatar(userId=m._id noRemove=true)
|
||||
|
||||
.poker-table-row
|
||||
.poker-table-cell
|
||||
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 20}}winner{{else}}loser{{/if}}") {{_ 'poker-twenty'}}
|
||||
.poker-table-cell {{ pokerCountTwenty }}
|
||||
.poker-table-cell.poker-table-cell-who
|
||||
.poker-result
|
||||
each m in pokerMemberTwenty
|
||||
a.name
|
||||
+userAvatar(userId=m._id noRemove=true)
|
||||
|
||||
.poker-table-row
|
||||
.poker-table-cell
|
||||
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 40}}winner{{else}}loser{{/if}}") {{_ 'poker-forty'}}
|
||||
.poker-table-cell {{ pokerCountForty }}
|
||||
.poker-table-cell.poker-table-cell-who
|
||||
.poker-result
|
||||
each m in pokerMemberForty
|
||||
a.name
|
||||
+userAvatar(userId=m._id noRemove=true)
|
||||
|
||||
.poker-table-row
|
||||
.poker-table-cell
|
||||
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 100}}winner{{else}}loser{{/if}}") {{_ 'poker-oneHundred'}}
|
||||
.poker-table-cell {{ pokerCountOneHundred }}
|
||||
.poker-table-cell.poker-table-cell-who
|
||||
.poker-result
|
||||
each m in pokerMemberOneHundred
|
||||
a.name
|
||||
+userAvatar(userId=m._id noRemove=true)
|
||||
|
||||
.poker-table-row
|
||||
.poker-table-cell
|
||||
button.card-details-gray.js-poker.poker-card-result(class="{{#if $eq pokerWinner 'unsure'}}winner{{else}}loser{{/if}}") {{_ 'poker-unsure'}}
|
||||
.poker-table-cell {{ pokerCountUnsure }}
|
||||
.poker-table-cell.poker-table-cell-who
|
||||
.poker-result
|
||||
each m in pokerMemberUnsure
|
||||
a.name
|
||||
+userAvatar(userId=m._id noRemove=true)
|
||||
|
||||
if currentUser.isBoardAdmin
|
||||
div.estimation-add
|
||||
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")
|
||||
|
||||
//- XXX We should use "editable" to avoid repetiting ourselves
|
||||
if canModifyCard
|
||||
unless currentUser.isWorker
|
||||
if currentBoard.allowsDescriptionTitle
|
||||
hr
|
||||
h3.card-details-item-title
|
||||
i.fa.fa-list-alt
|
||||
= definition.name
|
||||
+cardCustomField
|
||||
|
||||
if getVoteQuestion
|
||||
hr
|
||||
.vote-title
|
||||
div.flex
|
||||
h3
|
||||
i.fa.fa-thumbs-up
|
||||
| {{_ 'vote-question'}}
|
||||
if getVoteEnd
|
||||
+voteEndDate
|
||||
.vote-result
|
||||
if votePublic
|
||||
a.card-label.card-label-green.js-show-positive-votes {{ voteCountPositive }}
|
||||
a.card-label.card-label-red.js-show-negative-votes {{ voteCountNegative }}
|
||||
else
|
||||
.card-label.card-label-green {{ voteCountPositive }}
|
||||
.card-label.card-label-red {{ voteCountNegative }}
|
||||
unless ($and currentBoard.isPublic voteAllowNonBoardMembers )
|
||||
.card-label.card-label-gray {{ voteCount }} {{_ 'r-of' }} {{ currentBoard.activeMembers.length }}
|
||||
+viewer
|
||||
= getVoteQuestion
|
||||
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
|
||||
i.fa.fa-thumbs-down
|
||||
| {{_ 'vote-against'}}
|
||||
|
||||
//- XXX We should use "editable" to avoid repetiting ourselves
|
||||
if canModifyCard
|
||||
unless currentUser.isWorker
|
||||
i.fa.fa-align-left
|
||||
| {{_ 'description'}}
|
||||
if currentBoard.allowsDescriptionText
|
||||
+inlinedCardDescription(classNames="card-description js-card-description")
|
||||
+descriptionForm
|
||||
.edit-controls.clearfix
|
||||
button.primary(type="submit") {{_ 'save'}}
|
||||
a.fa.fa-times-thin.js-close-inlined-form
|
||||
else
|
||||
if currentBoard.allowsDescriptionText
|
||||
a.js-open-inlined-form
|
||||
if getDescription
|
||||
+viewer
|
||||
= getDescription
|
||||
else
|
||||
| {{_ 'edit'}}
|
||||
if (hasUnsavedValue 'cardDescription' _id)
|
||||
p.quiet
|
||||
| {{_ 'unsaved-description'}}
|
||||
a.js-open-inlined-form {{_ 'view-it'}}
|
||||
= ' - '
|
||||
a.js-close-inlined-form {{_ 'discard'}}
|
||||
else if getDescription
|
||||
if currentBoard.allowsDescriptionTitle
|
||||
hr
|
||||
h3.card-details-item-title
|
||||
i.fa.fa-align-left
|
||||
| {{_ 'description'}}
|
||||
h3.card-details-item-title {{_ 'description'}}
|
||||
if currentBoard.allowsDescriptionText
|
||||
+inlinedCardDescription(classNames="card-description js-card-description")
|
||||
+descriptionForm
|
||||
.edit-controls.clearfix
|
||||
button.primary(type="submit") {{_ 'save'}}
|
||||
a.fa.fa-times-thin.js-close-inlined-form
|
||||
else
|
||||
if currentBoard.allowsDescriptionText
|
||||
a.js-open-inlined-form
|
||||
if getDescription
|
||||
+viewer
|
||||
= getDescription
|
||||
else
|
||||
| {{_ 'edit'}}
|
||||
if (hasUnsavedValue 'cardDescription' _id)
|
||||
p.quiet
|
||||
| {{_ 'unsaved-description'}}
|
||||
a.js-open-inlined-form {{_ 'view-it'}}
|
||||
= ' - '
|
||||
a.js-close-inlined-form {{_ 'discard'}}
|
||||
else if getDescription
|
||||
if currentBoard.allowsDescriptionTitle
|
||||
hr
|
||||
h3.card-details-item-title {{_ 'description'}}
|
||||
if currentBoard.allowsDescriptionText
|
||||
+viewer
|
||||
= getDescription
|
||||
+viewer
|
||||
= getDescription
|
||||
|
||||
.card-checklist-attachmentGalerys
|
||||
.card-checklist-attachmentGalery.card-checklists
|
||||
if currentBoard.allowsChecklists
|
||||
.card-checklist-attachmentGalerys
|
||||
.card-checklist-attachmentGalery.card-checklists
|
||||
if currentBoard.allowsChecklists
|
||||
hr
|
||||
+checklists(cardId = _id)
|
||||
if currentBoard.allowsSubtasks
|
||||
hr
|
||||
+subtasks(cardId = _id)
|
||||
if currentBoard.allowsAttachments
|
||||
hr
|
||||
+checklists(cardId = _id)
|
||||
if currentBoard.allowsSubtasks
|
||||
hr
|
||||
+subtasks(cardId = _id)
|
||||
if currentBoard.allowsAttachments
|
||||
hr
|
||||
h3.card-details-item-title
|
||||
i.fa.fa-paperclip
|
||||
| {{_ 'attachments'}}
|
||||
.card-checklist-attachmentGalery.card-attachmentGalery
|
||||
+attachmentsGalery
|
||||
h3.card-details-item-title
|
||||
i.fa.fa-paperclip
|
||||
| {{_ 'attachments'}}
|
||||
.card-checklist-attachmentGalery.card-attachmentGalery
|
||||
+attachmentsGalery
|
||||
|
||||
hr
|
||||
unless currentUser.isNoComments
|
||||
.activity-title
|
||||
h3.card-details-item-title
|
||||
i.fa.fa-history
|
||||
| {{ _ 'activity'}}
|
||||
.card-details-right
|
||||
|
||||
unless currentUser.isNoComments
|
||||
.activity-title
|
||||
h3.card-details-item-title
|
||||
i.fa.fa-history
|
||||
| {{ _ 'activity'}}
|
||||
if currentUser.isBoardMember
|
||||
.material-toggle-switch(title="{{_ 'hide-system-messages'}}")
|
||||
//span.toggle-switch-title
|
||||
if hiddenSystemMessages
|
||||
input.toggle-switch(type="checkbox" id="toggleButton" checked="checked")
|
||||
else
|
||||
input.toggle-switch(type="checkbox" id="toggleButton")
|
||||
label.toggle-label(for="toggleButton")
|
||||
if currentBoard.allowsComments
|
||||
if currentUser.isBoardMember
|
||||
.material-toggle-switch
|
||||
span.toggle-switch-title {{_ 'hide-system-messages'}}
|
||||
if hiddenSystemMessages
|
||||
input.toggle-switch(type="checkbox" id="toggleButton" checked="checked")
|
||||
else
|
||||
input.toggle-switch(type="checkbox" id="toggleButton")
|
||||
label.toggle-label(for="toggleButton")
|
||||
if currentBoard.allowsComments
|
||||
if currentUser.isBoardMember
|
||||
unless currentUser.isNoComments
|
||||
+commentForm
|
||||
unless currentUser.isNoComments
|
||||
if isLoaded.get
|
||||
if isLinkedCard
|
||||
+activities(card=this mode="linkedcard")
|
||||
else if isLinkedBoard
|
||||
+activities(card=this mode="linkedboard")
|
||||
else
|
||||
+activities(card=this mode="card")
|
||||
unless currentUser.isNoComments
|
||||
+commentForm
|
||||
unless currentUser.isNoComments
|
||||
if isLoaded.get
|
||||
if isLinkedCard
|
||||
+activities(card=this mode="linkedcard")
|
||||
else if isLinkedBoard
|
||||
+activities(card=this mode="linkedboard")
|
||||
else
|
||||
+activities(card=this mode="card")
|
||||
|
||||
template(name="editCardTitleForm")
|
||||
textarea.js-edit-card-title(rows='1' autofocus dir="auto")
|
||||
|
|
@ -341,6 +560,12 @@ template(name="editCardAssignerForm")
|
|||
button.primary.confirm.js-submit-edit-card-assigner-form(type="submit") {{_ 'save'}}
|
||||
a.fa.fa-times-thin.js-close-inlined-form
|
||||
|
||||
template(name="editCardSortOrderForm")
|
||||
input.js-edit-card-sort(type='text' autofocus value=sort dir="auto")
|
||||
.edit-controls.clearfix
|
||||
button.primary.confirm.js-submit-edit-card-sort-form(type="submit") {{_ 'save'}}
|
||||
a.fa.fa-times-thin.js-close-inlined-form
|
||||
|
||||
template(name="cardDetailsActionsPopup")
|
||||
ul.pop-over-list
|
||||
li
|
||||
|
|
@ -351,9 +576,9 @@ template(name="cardDetailsActionsPopup")
|
|||
else
|
||||
i.fa.fa-eye-slash
|
||||
| {{_ 'watch'}}
|
||||
hr
|
||||
if canModifyCard
|
||||
unless currentUser.isWorker
|
||||
hr
|
||||
ul.pop-over-list
|
||||
//li: a.js-members {{_ 'card-edit-members'}}
|
||||
//li: a.js-labels {{_ 'card-edit-labels'}}
|
||||
|
|
@ -362,6 +587,10 @@ template(name="cardDetailsActionsPopup")
|
|||
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
|
||||
|
|
@ -379,50 +608,63 @@ template(name="cardDetailsActionsPopup")
|
|||
a.js-set-card-color
|
||||
i.fa.fa-paint-brush
|
||||
| {{_ 'setCardColorPopup-title'}}
|
||||
hr
|
||||
ul.pop-over-list
|
||||
hr
|
||||
ul.pop-over-list
|
||||
li
|
||||
a.js-export-card
|
||||
i.fa.fa-share-alt
|
||||
| {{_ 'export-card'}}
|
||||
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-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-copy
|
||||
| {{_ 'copyCardPopup-title'}}
|
||||
a.js-move-card
|
||||
i.fa.fa-arrow-right
|
||||
| {{_ 'moveCardPopup-title'}}
|
||||
unless currentUser.isWorker
|
||||
li
|
||||
a.js-copy-card
|
||||
i.fa.fa-copy
|
||||
| {{_ 'copyCardPopup-title'}}
|
||||
unless currentUser.isWorker
|
||||
hr
|
||||
ul.pop-over-list
|
||||
li
|
||||
a.js-copy-checklist-cards
|
||||
i.fa.fa-list
|
||||
i.fa.fa-copy
|
||||
| {{_ 'copyChecklistToManyCardsPopup-title'}}
|
||||
unless archived
|
||||
hr
|
||||
ul.pop-over-list
|
||||
li
|
||||
a.js-copy-checklist-cards
|
||||
i.fa.fa-list
|
||||
i.fa.fa-copy
|
||||
| {{_ 'copyChecklistToManyCardsPopup-title'}}
|
||||
unless archived
|
||||
hr
|
||||
ul.pop-over-list
|
||||
li
|
||||
a.js-archive
|
||||
i.fa.fa-arrow-right
|
||||
i.fa.fa-archive
|
||||
| {{_ 'archive-card'}}
|
||||
hr
|
||||
ul.pop-over-list
|
||||
li
|
||||
a.js-more
|
||||
i.fa.fa-link
|
||||
| {{_ 'cardMorePopup-title'}}
|
||||
a.js-archive
|
||||
i.fa.fa-arrow-right
|
||||
i.fa.fa-archive
|
||||
| {{_ 'archive-card'}}
|
||||
hr
|
||||
ul.pop-over-list
|
||||
li
|
||||
a.js-more
|
||||
i.fa.fa-link
|
||||
| {{_ 'cardMorePopup-title'}}
|
||||
|
||||
template(name="exportCardPopup")
|
||||
ul.pop-over-list
|
||||
li
|
||||
a(href="{{exportUrlCardPDF}}",, download="{{exportFilenameCardPDF}}")
|
||||
i.fa.fa-share-alt
|
||||
| {{_ 'export-card-pdf'}}
|
||||
|
||||
template(name="moveCardPopup")
|
||||
+boardsAndLists
|
||||
|
|
@ -621,3 +863,29 @@ template(name="negativeVoteMembersPopup")
|
|||
span.full-name
|
||||
= m.profile.fullname
|
||||
| (<span class="username">{{ m.username }}</span>)
|
||||
|
||||
template(name="deletePokerPopup")
|
||||
p {{_ "poker-delete-pop"}}
|
||||
button.js-confirm.negate.full(type="submit") {{_ 'delete'}}
|
||||
|
||||
template(name="cardStartPlanningPokerPopup")
|
||||
form.edit-poker-question
|
||||
.fields
|
||||
.check-div
|
||||
a.flex(class="{{#if getPokerQuestion}}is-disabled{{else}}js-toggle-poker-allow-non-members{{/if}}")
|
||||
.materialCheckBox#poker-allow-non-members(name="poker-allow-non-members" class="{{#if pokerAllowNonBoardMembers}}is-checked{{/if}}")
|
||||
span {{_ 'allowNonBoardMembers'}}
|
||||
.check-div.flex
|
||||
i.fa.fa-hourglass-end
|
||||
a.js-end-date
|
||||
span
|
||||
| {{_ 'card-end'}}
|
||||
unless getPokerEnd
|
||||
i.fa.fa-plus
|
||||
if getPokerEnd
|
||||
+pokerEndDate
|
||||
|
||||
button.primary.js-submit {{_ 'save'}}
|
||||
if getPokerQuestion
|
||||
if currentUser.isBoardAdmin
|
||||
button.js-remove-poker.negate.wide.right {{_ 'delete'}}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,10 @@ BlazeComponent.extendComponent({
|
|||
return Meteor.user().hasHiddenSystemMessages();
|
||||
},
|
||||
|
||||
cardMaximized() {
|
||||
return Meteor.user().hasCardMaximized();
|
||||
},
|
||||
|
||||
canModifyCard() {
|
||||
return (
|
||||
Meteor.user() &&
|
||||
|
|
@ -140,6 +144,15 @@ BlazeComponent.extendComponent({
|
|||
);
|
||||
},
|
||||
|
||||
showPlanningPokerButtons() {
|
||||
const card = this.currentData();
|
||||
return (
|
||||
(currentUser.isBoardMember() ||
|
||||
(currentUser && card.pokerAllowNonBoardMembers())) &&
|
||||
!card.expiredPoker()
|
||||
);
|
||||
},
|
||||
|
||||
onRendered() {
|
||||
if (Meteor.settings.public.CARD_OPENED_WEBHOOK_ENABLED) {
|
||||
// Send Webhook but not create Activities records ---
|
||||
|
|
@ -161,7 +174,7 @@ BlazeComponent.extendComponent({
|
|||
}).fetch();
|
||||
|
||||
if (integrations.length > 0) {
|
||||
integrations.forEach(integration => {
|
||||
integrations.forEach((integration) => {
|
||||
Meteor.call(
|
||||
'outgoingWebhooks',
|
||||
integration,
|
||||
|
|
@ -327,9 +340,7 @@ BlazeComponent.extendComponent({
|
|||
},
|
||||
'submit .js-card-details-title'(event) {
|
||||
event.preventDefault();
|
||||
const title = this.currentComponent()
|
||||
.getValue()
|
||||
.trim();
|
||||
const title = this.currentComponent().getValue().trim();
|
||||
if (title) {
|
||||
this.data().setTitle(title);
|
||||
} else {
|
||||
|
|
@ -338,9 +349,7 @@ BlazeComponent.extendComponent({
|
|||
},
|
||||
'submit .js-card-details-assigner'(event) {
|
||||
event.preventDefault();
|
||||
const assigner = this.currentComponent()
|
||||
.getValue()
|
||||
.trim();
|
||||
const assigner = this.currentComponent().getValue().trim();
|
||||
if (assigner) {
|
||||
this.data().setAssignedBy(assigner);
|
||||
} else {
|
||||
|
|
@ -349,15 +358,23 @@ BlazeComponent.extendComponent({
|
|||
},
|
||||
'submit .js-card-details-requester'(event) {
|
||||
event.preventDefault();
|
||||
const requester = this.currentComponent()
|
||||
.getValue()
|
||||
.trim();
|
||||
const requester = this.currentComponent().getValue().trim();
|
||||
if (requester) {
|
||||
this.data().setRequestedBy(requester);
|
||||
} else {
|
||||
this.data().setRequestedBy('');
|
||||
}
|
||||
},
|
||||
'submit .js-card-details-sort'(event) {
|
||||
event.preventDefault();
|
||||
const sort = parseFloat(this.currentComponent()
|
||||
.getValue()
|
||||
.trim());
|
||||
if (!Number.isNaN(sort)) {
|
||||
let card = this.data();
|
||||
card.move(card.boardId, card.swimlaneId, card.listId, sort);
|
||||
}
|
||||
},
|
||||
'click .js-go-to-linked-card'() {
|
||||
Utils.goCardId(this.data().linkedId);
|
||||
},
|
||||
|
|
@ -395,6 +412,14 @@ BlazeComponent.extendComponent({
|
|||
'click #toggleButton'() {
|
||||
Meteor.call('toggleSystemMessages');
|
||||
},
|
||||
'click .js-maximize-card-details'() {
|
||||
Meteor.call('toggleCardMaximized');
|
||||
autosize($('.card-details'));
|
||||
},
|
||||
'click .js-minimize-card-details'() {
|
||||
Meteor.call('toggleCardMaximized');
|
||||
autosize($('.card-details'));
|
||||
},
|
||||
'click .js-vote'(e) {
|
||||
const forIt = $(e.target).hasClass('js-vote-positive');
|
||||
let newState = null;
|
||||
|
|
@ -407,11 +432,126 @@ BlazeComponent.extendComponent({
|
|||
}
|
||||
this.data().setVote(Meteor.userId(), newState);
|
||||
},
|
||||
'click .js-poker'(e) {
|
||||
let newState = null;
|
||||
if ($(e.target).hasClass('js-poker-vote-one')) {
|
||||
newState = 'one';
|
||||
this.data().setPoker(Meteor.userId(), newState);
|
||||
}
|
||||
if ($(e.target).hasClass('js-poker-vote-two')) {
|
||||
newState = 'two';
|
||||
this.data().setPoker(Meteor.userId(), newState);
|
||||
}
|
||||
if ($(e.target).hasClass('js-poker-vote-three')) {
|
||||
newState = 'three';
|
||||
this.data().setPoker(Meteor.userId(), newState);
|
||||
}
|
||||
if ($(e.target).hasClass('js-poker-vote-five')) {
|
||||
newState = 'five';
|
||||
this.data().setPoker(Meteor.userId(), newState);
|
||||
}
|
||||
if ($(e.target).hasClass('js-poker-vote-eight')) {
|
||||
newState = 'eight';
|
||||
this.data().setPoker(Meteor.userId(), newState);
|
||||
}
|
||||
if ($(e.target).hasClass('js-poker-vote-thirteen')) {
|
||||
newState = 'thirteen';
|
||||
this.data().setPoker(Meteor.userId(), newState);
|
||||
}
|
||||
if ($(e.target).hasClass('js-poker-vote-twenty')) {
|
||||
newState = 'twenty';
|
||||
this.data().setPoker(Meteor.userId(), newState);
|
||||
}
|
||||
if ($(e.target).hasClass('js-poker-vote-forty')) {
|
||||
newState = 'forty';
|
||||
this.data().setPoker(Meteor.userId(), newState);
|
||||
}
|
||||
if ($(e.target).hasClass('js-poker-vote-one-hundred')) {
|
||||
newState = 'oneHundred';
|
||||
this.data().setPoker(Meteor.userId(), newState);
|
||||
}
|
||||
if ($(e.target).hasClass('js-poker-vote-unsure')) {
|
||||
newState = 'unsure';
|
||||
this.data().setPoker(Meteor.userId(), newState);
|
||||
}
|
||||
},
|
||||
'click .js-poker-finish'(e) {
|
||||
if ($(e.target).hasClass('js-poker-finish')) {
|
||||
e.preventDefault();
|
||||
const now = moment().format('YYYY-MM-DD HH:mm');
|
||||
this.data().setPokerEnd(now);
|
||||
}
|
||||
},
|
||||
|
||||
'click .js-poker-replay'(e) {
|
||||
if ($(e.target).hasClass('js-poker-replay')) {
|
||||
e.preventDefault();
|
||||
this.currentCard = this.currentData();
|
||||
this.currentCard.replayPoker();
|
||||
this.data().unsetPokerEnd();
|
||||
this.data().unsetPokerEstimation();
|
||||
}
|
||||
},
|
||||
'click .js-poker-estimation'(event) {
|
||||
event.preventDefault();
|
||||
|
||||
const ruleTitle = this.find('#pokerEstimation').value;
|
||||
if (ruleTitle !== undefined && ruleTitle !== '') {
|
||||
this.find('#pokerEstimation').value = '';
|
||||
|
||||
if (ruleTitle) {
|
||||
this.data().setPokerEstimation(parseInt(ruleTitle, 10));
|
||||
} else {
|
||||
this.data().setPokerEstimation('');
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('cardDetails');
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
template() {
|
||||
return 'exportCard';
|
||||
},
|
||||
withApi() {
|
||||
return Template.instance().apiEnabled.get();
|
||||
},
|
||||
exportUrlCardPDF() {
|
||||
const params = {
|
||||
boardId: Session.get('currentBoard'),
|
||||
listId: this.listId,
|
||||
cardId: this.cardId,
|
||||
};
|
||||
const queryParams = {
|
||||
authToken: Accounts._storedLoginToken(),
|
||||
};
|
||||
return FlowRouter.path(
|
||||
'/api/boards/:boardId/lists/:listId/cards/:cardId/exportPDF',
|
||||
params,
|
||||
queryParams,
|
||||
);
|
||||
},
|
||||
exportFilenameCardPDF() {
|
||||
//const boardId = Session.get('currentBoard');
|
||||
//return `export-card-pdf-${boardId}.xlsx`;
|
||||
return `export-card.pdf`;
|
||||
},
|
||||
}).register('exportCardPopup');
|
||||
|
||||
// only allow number input
|
||||
Template.editCardSortOrderForm.onRendered(function() {
|
||||
this.$('input').on("keypress paste", function(event) {
|
||||
let keyCode = event.keyCode;
|
||||
let charCode = String.fromCharCode(keyCode);
|
||||
let regex = new RegExp('[-0-9.]');
|
||||
let ret = regex.test(charCode);
|
||||
// only working here, defining in events() doesn't handle the return value correctly
|
||||
return ret;
|
||||
});
|
||||
});
|
||||
|
||||
// We extends the normal InlinedForm component to support UnsavedEdits draft
|
||||
// feature.
|
||||
(class extends InlinedForm {
|
||||
|
|
@ -472,11 +612,13 @@ Template.cardDetailsActionsPopup.helpers({
|
|||
});
|
||||
|
||||
Template.cardDetailsActionsPopup.events({
|
||||
'click .js-export-card': Popup.open('exportCard'),
|
||||
'click .js-members': Popup.open('cardMembers'),
|
||||
'click .js-assignees': Popup.open('cardAssignees'),
|
||||
'click .js-labels': Popup.open('cardLabels'),
|
||||
'click .js-attachments': Popup.open('cardAttachments'),
|
||||
'click .js-start-voting': Popup.open('cardStartVoting'),
|
||||
'click .js-start-planning-poker': Popup.open('cardStartPlanningPoker'),
|
||||
'click .js-custom-fields': Popup.open('cardCustomFields'),
|
||||
'click .js-received-date': Popup.open('editCardReceivedDate'),
|
||||
'click .js-start-date': Popup.open('editCardStartDate'),
|
||||
|
|
@ -492,7 +634,7 @@ Template.cardDetailsActionsPopup.events({
|
|||
const minOrder = _.min(
|
||||
this.list()
|
||||
.cards(this.swimlaneId)
|
||||
.map(c => c.sort),
|
||||
.map((c) => c.sort),
|
||||
);
|
||||
this.move(this.boardId, this.swimlaneId, this.listId, minOrder - 1);
|
||||
},
|
||||
|
|
@ -501,7 +643,7 @@ Template.cardDetailsActionsPopup.events({
|
|||
const maxOrder = _.max(
|
||||
this.list()
|
||||
.cards(this.swimlaneId)
|
||||
.map(c => c.sort),
|
||||
.map((c) => c.sort),
|
||||
);
|
||||
this.move(this.boardId, this.swimlaneId, this.listId, maxOrder + 1);
|
||||
},
|
||||
|
|
@ -520,7 +662,7 @@ Template.cardDetailsActionsPopup.events({
|
|||
},
|
||||
});
|
||||
|
||||
Template.editCardTitleForm.onRendered(function() {
|
||||
Template.editCardTitleForm.onRendered(function () {
|
||||
autosize(this.$('.js-edit-card-title'));
|
||||
});
|
||||
|
||||
|
|
@ -534,7 +676,7 @@ Template.editCardTitleForm.events({
|
|||
},
|
||||
});
|
||||
|
||||
Template.editCardRequesterForm.onRendered(function() {
|
||||
Template.editCardRequesterForm.onRendered(function () {
|
||||
autosize(this.$('.js-edit-card-requester'));
|
||||
});
|
||||
|
||||
|
|
@ -547,7 +689,7 @@ Template.editCardRequesterForm.events({
|
|||
},
|
||||
});
|
||||
|
||||
Template.editCardAssignerForm.onRendered(function() {
|
||||
Template.editCardAssignerForm.onRendered(function () {
|
||||
autosize(this.$('.js-edit-card-assigner'));
|
||||
});
|
||||
|
||||
|
|
@ -632,9 +774,7 @@ Template.copyCardPopup.events({
|
|||
const textarea = $('#copy-card-title');
|
||||
const title = textarea.val().trim();
|
||||
// insert new card to the bottom of new list
|
||||
card.sort = Lists.findOne(card.listId)
|
||||
.cards()
|
||||
.count();
|
||||
card.sort = Lists.findOne(card.listId).cards().count();
|
||||
|
||||
if (title) {
|
||||
card.title = title;
|
||||
|
|
@ -665,9 +805,7 @@ Template.copyChecklistToManyCardsPopup.events({
|
|||
const textarea = $('#copy-card-title');
|
||||
const titleEntry = textarea.val().trim();
|
||||
// insert new card to the bottom of new list
|
||||
card.sort = Lists.findOne(card.listId)
|
||||
.cards()
|
||||
.count();
|
||||
card.sort = Lists.findOne(card.listId).cards().count();
|
||||
|
||||
if (titleEntry) {
|
||||
const titleList = JSON.parse(titleEntry);
|
||||
|
|
@ -684,13 +822,13 @@ Template.copyChecklistToManyCardsPopup.events({
|
|||
Filter.addException(_id);
|
||||
|
||||
// copy checklists
|
||||
Checklists.find({ cardId: oldId }).forEach(ch => {
|
||||
Checklists.find({ cardId: oldId }).forEach((ch) => {
|
||||
ch.copy(_id);
|
||||
});
|
||||
|
||||
// copy subtasks
|
||||
const cursor = Cards.find({ parentId: oldId });
|
||||
cursor.forEach(function() {
|
||||
cursor.forEach(function () {
|
||||
'use strict';
|
||||
const subtask = arguments[0];
|
||||
subtask.parentId = _id;
|
||||
|
|
@ -699,7 +837,7 @@ Template.copyChecklistToManyCardsPopup.events({
|
|||
});
|
||||
|
||||
// copy card comments
|
||||
CardComments.find({ cardId: oldId }).forEach(cmt => {
|
||||
CardComments.find({ cardId: oldId }).forEach((cmt) => {
|
||||
cmt.copy(_id);
|
||||
});
|
||||
}
|
||||
|
|
@ -715,7 +853,7 @@ BlazeComponent.extendComponent({
|
|||
},
|
||||
|
||||
colors() {
|
||||
return ALLOWED_COLORS.map(color => ({ color, name: '' }));
|
||||
return ALLOWED_COLORS.map((color) => ({ color, name: '' }));
|
||||
},
|
||||
|
||||
isSelected(color) {
|
||||
|
|
@ -838,7 +976,7 @@ BlazeComponent.extendComponent({
|
|||
}
|
||||
}
|
||||
},
|
||||
'click .js-delete': Popup.afterConfirm('cardDelete', function() {
|
||||
'click .js-delete': Popup.afterConfirm('cardDelete', function () {
|
||||
Popup.close();
|
||||
// verify that there are no linked cards
|
||||
if (Cards.find({ linkedId: this._id }).count() === 0) {
|
||||
|
|
@ -945,6 +1083,8 @@ BlazeComponent.extendComponent({
|
|||
moment(new Date().setHours(12, 0, 0)).format('LT');
|
||||
|
||||
const dateString = `${evt.target.date.value} ${time}`;
|
||||
|
||||
/*
|
||||
const newDate = moment(dateString, 'L LT', true);
|
||||
if (newDate.isValid()) {
|
||||
// if active vote - store it
|
||||
|
|
@ -955,6 +1095,159 @@ BlazeComponent.extendComponent({
|
|||
this.currentData().vote = { end: newDate.toDate() }; // set vote end temp
|
||||
Popup.back();
|
||||
}
|
||||
|
||||
|
||||
*/
|
||||
|
||||
// Try to parse different date formats of all languages.
|
||||
// This code is same for vote and planning poker.
|
||||
const usaDate = moment(dateString, 'L LT', true);
|
||||
const euroAmDate = moment(dateString, 'DD.MM.YYYY LT', true);
|
||||
const euro24hDate = moment(dateString, 'DD.MM.YYYY HH.mm', true);
|
||||
const eurodotDate = moment(dateString, 'DD.MM.YYYY HH:mm', true);
|
||||
const minusDate = moment(dateString, 'YYYY-MM-DD HH:mm', true);
|
||||
const slashDate = moment(dateString, 'DD/MM/YYYY HH.mm', true);
|
||||
const dotDate = moment(dateString, 'DD/MM/YYYY HH:mm', true);
|
||||
const brezhonegDate = moment(dateString, 'DD/MM/YYYY h[e]mm A', true);
|
||||
const hrvatskiDate = moment(dateString, 'DD. MM. YYYY H:mm', true);
|
||||
const latviaDate = moment(dateString, 'YYYY.MM.DD. H:mm', true);
|
||||
const nederlandsDate = moment(dateString, 'DD-MM-YYYY HH:mm', true);
|
||||
// greekDate does not work: el Greek Ελληνικά ,
|
||||
// it has date format DD/MM/YYYY h:mm MM like 20/06/2021 11:15 MM
|
||||
// where MM is maybe some text like AM/PM ?
|
||||
// Also some other languages that have non-ascii characters in dates
|
||||
// do not work.
|
||||
const greekDate = moment(dateString, 'DD/MM/YYYY h:mm A', true);
|
||||
const macedonianDate = moment(dateString, 'D.MM.YYYY H:mm', true);
|
||||
|
||||
if (usaDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(usaDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: usaDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (euroAmDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(euroAmDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: euroAmDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (euro24hDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(euro24hDate.toDate());
|
||||
this.card.setPokerEnd(euro24hDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: euro24hDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (eurodotDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(eurodotDate.toDate());
|
||||
this.card.setPokerEnd(eurodotDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: eurodotDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (minusDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(minusDate.toDate());
|
||||
this.card.setPokerEnd(minusDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: minusDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (slashDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(slashDate.toDate());
|
||||
this.card.setPokerEnd(slashDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: slashDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (dotDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(dotDate.toDate());
|
||||
this.card.setPokerEnd(dotDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: dotDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (brezhonegDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(brezhonegDate.toDate());
|
||||
this.card.setPokerEnd(brezhonegDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: brezhonegDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (hrvatskiDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(hrvatskiDate.toDate());
|
||||
this.card.setPokerEnd(hrvatskiDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: hrvatskiDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (latviaDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(latviaDate.toDate());
|
||||
this.card.setPokerEnd(latviaDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: latviaDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (nederlandsDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(nederlandsDate.toDate());
|
||||
this.card.setPokerEnd(nederlandsDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: nederlandsDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (greekDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(greekDate.toDate());
|
||||
this.card.setPokerEnd(greekDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: greekDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (macedonianDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(macedonianDate.toDate());
|
||||
this.card.setPokerEnd(macedonianDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: macedonianDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else {
|
||||
this.error.set('invalid-date');
|
||||
evt.target.date.focus();
|
||||
|
|
@ -976,6 +1269,277 @@ BlazeComponent.extendComponent({
|
|||
}
|
||||
}.register('editVoteEndDatePopup'));
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
onCreated() {
|
||||
this.currentCard = this.currentData();
|
||||
this.pokerQuestion = new ReactiveVar(this.currentCard.pokerQuestion);
|
||||
},
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'click .js-end-date': Popup.open('editPokerEndDate'),
|
||||
'submit .edit-poker-question'(evt) {
|
||||
evt.preventDefault();
|
||||
const pokerQuestion = true;
|
||||
const allowNonBoardMembers = $('#poker-allow-non-members').hasClass(
|
||||
'is-checked',
|
||||
);
|
||||
const endString = this.currentCard.getPokerEnd();
|
||||
|
||||
this.currentCard.setPokerQuestion(
|
||||
pokerQuestion,
|
||||
allowNonBoardMembers,
|
||||
);
|
||||
if (endString) {
|
||||
this.currentCard.setPokerEnd(endString);
|
||||
}
|
||||
Popup.close();
|
||||
},
|
||||
'click .js-remove-poker': Popup.afterConfirm('deletePoker', (event) => {
|
||||
event.preventDefault();
|
||||
this.currentCard.unsetPoker();
|
||||
Popup.close();
|
||||
}),
|
||||
'click a.js-toggle-poker-allow-non-members'(event) {
|
||||
event.preventDefault();
|
||||
$('#poker-allow-non-members').toggleClass('is-checked');
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('cardStartPlanningPokerPopup');
|
||||
|
||||
// editPokerEndDatePopup
|
||||
(class extends DatePicker {
|
||||
onCreated() {
|
||||
super.onCreated(moment().format('YYYY-MM-DD HH:mm'));
|
||||
this.data().getPokerEnd() &&
|
||||
this.date.set(moment(this.data().getPokerEnd()));
|
||||
}
|
||||
|
||||
/*
|
||||
Tried to use dateFormat and timeFormat from client/components/lib/datepicker.js
|
||||
to make detecting all date formats not necessary,
|
||||
but got error "language mk does not exist".
|
||||
Maybe client/components/lib/datepicker.jade could have hidden input field for
|
||||
datepicker format that could be used to detect date format?
|
||||
|
||||
dateFormat() {
|
||||
return moment.localeData().longDateFormat('L');
|
||||
}
|
||||
|
||||
timeFormat() {
|
||||
return moment.localeData().longDateFormat('LT');
|
||||
}
|
||||
|
||||
const newDate = moment(dateString, dateformat() + ' ' + timeformat(), true);
|
||||
*/
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'submit .edit-date'(evt) {
|
||||
evt.preventDefault();
|
||||
|
||||
// if no time was given, init with 12:00
|
||||
const time =
|
||||
evt.target.time.value ||
|
||||
moment(new Date().setHours(12, 0, 0)).format('LT');
|
||||
|
||||
const dateString = `${evt.target.date.value} ${time}`;
|
||||
|
||||
/*
|
||||
Tried to use dateFormat and timeFormat from client/components/lib/datepicker.js
|
||||
to make detecting all date formats not necessary,
|
||||
but got error "language mk does not exist".
|
||||
Maybe client/components/lib/datepicker.jade could have hidden input field for
|
||||
datepicker format that could be used to detect date format?
|
||||
|
||||
const newDate = moment(dateString, dateformat() + ' ' + timeformat(), true);
|
||||
|
||||
if (newDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(newDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: newDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
*/
|
||||
|
||||
// Try to parse different date formats of all languages.
|
||||
// This code is same for vote and planning poker.
|
||||
const usaDate = moment(dateString, 'L LT', true);
|
||||
const euroAmDate = moment(dateString, 'DD.MM.YYYY LT', true);
|
||||
const euro24hDate = moment(dateString, 'DD.MM.YYYY HH.mm', true);
|
||||
const eurodotDate = moment(dateString, 'DD.MM.YYYY HH:mm', true);
|
||||
const minusDate = moment(dateString, 'YYYY-MM-DD HH:mm', true);
|
||||
const slashDate = moment(dateString, 'DD/MM/YYYY HH.mm', true);
|
||||
const dotDate = moment(dateString, 'DD/MM/YYYY HH:mm', true);
|
||||
const brezhonegDate = moment(dateString, 'DD/MM/YYYY h[e]mm A', true);
|
||||
const hrvatskiDate = moment(dateString, 'DD. MM. YYYY H:mm', true);
|
||||
const latviaDate = moment(dateString, 'YYYY.MM.DD. H:mm', true);
|
||||
const nederlandsDate = moment(dateString, 'DD-MM-YYYY HH:mm', true);
|
||||
// greekDate does not work: el Greek Ελληνικά ,
|
||||
// it has date format DD/MM/YYYY h:mm MM like 20/06/2021 11:15 MM
|
||||
// where MM is maybe some text like AM/PM ?
|
||||
// Also some other languages that have non-ascii characters in dates
|
||||
// do not work.
|
||||
const greekDate = moment(dateString, 'DD/MM/YYYY h:mm A', true);
|
||||
const macedonianDate = moment(dateString, 'D.MM.YYYY H:mm', true);
|
||||
|
||||
if (usaDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(usaDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: usaDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (euroAmDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(euroAmDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: euroAmDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (euro24hDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(euro24hDate.toDate());
|
||||
this.card.setPokerEnd(euro24hDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: euro24hDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (eurodotDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(eurodotDate.toDate());
|
||||
this.card.setPokerEnd(eurodotDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: eurodotDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (minusDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(minusDate.toDate());
|
||||
this.card.setPokerEnd(minusDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: minusDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (slashDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(slashDate.toDate());
|
||||
this.card.setPokerEnd(slashDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: slashDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (dotDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(dotDate.toDate());
|
||||
this.card.setPokerEnd(dotDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: dotDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (brezhonegDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(brezhonegDate.toDate());
|
||||
this.card.setPokerEnd(brezhonegDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: brezhonegDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (hrvatskiDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(hrvatskiDate.toDate());
|
||||
this.card.setPokerEnd(hrvatskiDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: hrvatskiDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (latviaDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(latviaDate.toDate());
|
||||
this.card.setPokerEnd(latviaDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: latviaDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (nederlandsDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(nederlandsDate.toDate());
|
||||
this.card.setPokerEnd(nederlandsDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: nederlandsDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (greekDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(greekDate.toDate());
|
||||
this.card.setPokerEnd(greekDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: greekDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else if (macedonianDate.isValid()) {
|
||||
// if active poker - store it
|
||||
if (this.currentData().getPokerQuestion()) {
|
||||
this._storeDate(macedonianDate.toDate());
|
||||
this.card.setPokerEnd(macedonianDate.toDate());
|
||||
Popup.close();
|
||||
} else {
|
||||
this.currentData().poker = { end: macedonianDate.toDate() }; // set poker end temp
|
||||
Popup.back();
|
||||
}
|
||||
} else {
|
||||
// this.error.set('invalid-date);
|
||||
this.error.set('invalid-date' + ' ' + dateString);
|
||||
evt.target.date.focus();
|
||||
}
|
||||
},
|
||||
'click .js-delete-date'(evt) {
|
||||
evt.preventDefault();
|
||||
this._deleteDate();
|
||||
Popup.close();
|
||||
},
|
||||
},
|
||||
];
|
||||
}
|
||||
_storeDate(newDate) {
|
||||
this.card.setPokerEnd(newDate);
|
||||
}
|
||||
_deleteDate() {
|
||||
this.card.unsetPokerEnd();
|
||||
}
|
||||
}.register('editPokerEndDatePopup'));
|
||||
|
||||
// Close the card details pane by pressing escape
|
||||
EscapeActions.register(
|
||||
'detailsPane',
|
||||
|
|
|
|||
|
|
@ -110,11 +110,13 @@ avatar-radius = 50%
|
|||
|
||||
.card-details-header
|
||||
margin: 0 -20px 5px
|
||||
padding 7px 20px
|
||||
padding: 7px 20px
|
||||
background: darken(white, 7%)
|
||||
border-bottom: 1px solid darken(white, 14%)
|
||||
|
||||
.close-card-details,
|
||||
.maximize-card-details,
|
||||
.minimize-card-details,
|
||||
.card-details-menu,
|
||||
.card-copy-button,
|
||||
.card-copy-mobile-button,
|
||||
|
|
@ -122,9 +124,11 @@ avatar-radius = 50%
|
|||
.card-details-menu-mobile-web
|
||||
float: right
|
||||
|
||||
.close-card-details
|
||||
.close-card-details,
|
||||
.maximize-card-details,
|
||||
.minimize-card-details
|
||||
font-size: 24px
|
||||
padding: 5px
|
||||
padding: 5px 10px 5px 10px
|
||||
margin-right: -8px
|
||||
|
||||
.close-card-details-mobile-web
|
||||
|
|
@ -233,6 +237,43 @@ avatar-radius = 50%
|
|||
.activities
|
||||
padding-top: 10px
|
||||
|
||||
.card-details-maximized
|
||||
padding: 0
|
||||
flex-shrink: 0
|
||||
flex-basis: calc(100% - 20px)
|
||||
will-change: flex-basis
|
||||
overflow-y: scroll
|
||||
overflow-x: scroll
|
||||
background: darken(white, 3%)
|
||||
border-radius: bottom 3px
|
||||
z-index: 1000 !important
|
||||
animation: flexGrowIn 0.1s
|
||||
box-shadow: 0 0 7px 0 darken(white, 30%)
|
||||
transition: flex-basis 0.1s
|
||||
box-sizing: border-box
|
||||
position: absolute
|
||||
top: 0
|
||||
left: 0
|
||||
height: calc(100% - 20px)
|
||||
width: calc(100% - 20px)
|
||||
float: left
|
||||
|
||||
.card-details-left
|
||||
position: absolute
|
||||
float: left
|
||||
top: 60px
|
||||
left: 20px
|
||||
width: 47%
|
||||
|
||||
.card-details-right
|
||||
position: absolute
|
||||
float: right
|
||||
top: 20px
|
||||
left: 50%
|
||||
|
||||
.card-details-header
|
||||
width: 47%
|
||||
|
||||
input[type="text"].attachment-add-link-input
|
||||
float: left
|
||||
margin: 0 0 8px
|
||||
|
|
@ -260,7 +301,13 @@ input[type="submit"].attachment-add-link-submit
|
|||
margin-right: 0px
|
||||
|
||||
.card-details-menu
|
||||
margin-right: 10px
|
||||
margin-right: 40px
|
||||
|
||||
.maximize-card-details
|
||||
margin-right: 40px
|
||||
|
||||
.minimize-card-details
|
||||
margin-right: 40px
|
||||
|
||||
card-details-color(background, color...)
|
||||
background: background !important
|
||||
|
|
@ -357,3 +404,131 @@ card-details-color(background, color...)
|
|||
display: flex
|
||||
.js-show-positive-votes
|
||||
cursor: pointer
|
||||
|
||||
.poker-voted
|
||||
opacity: .7
|
||||
|
||||
.poker-title
|
||||
display: flex
|
||||
justify-content: space-between
|
||||
|
||||
.js-edit-date
|
||||
align-self: baseline
|
||||
margin-left: 5px
|
||||
|
||||
.poker-result
|
||||
display: flex
|
||||
flex-flow: row wrap
|
||||
.js-show-positive-poker-votes
|
||||
cursor: pointer
|
||||
|
||||
.poker-deck
|
||||
display: grid
|
||||
flex-direction: column
|
||||
text-align: center
|
||||
|
||||
.poker-card-result
|
||||
width: 32px
|
||||
font-size: 1em
|
||||
font-weight: bold
|
||||
padding: 4px 2px 4px 2px
|
||||
cursor: default
|
||||
|
||||
.winner
|
||||
font-weight: bold
|
||||
outline: #2d2d2d solid 2px
|
||||
|
||||
.loser
|
||||
opacity: .5
|
||||
|
||||
.responsive-table
|
||||
overflow-x: auto
|
||||
|
||||
.poker-table
|
||||
display: table
|
||||
width: 100%
|
||||
padding-top: 10px
|
||||
|
||||
.poker-table-row
|
||||
display: table-row
|
||||
|
||||
.poker-table-heading
|
||||
background-color: #EEE
|
||||
display: table-header-group
|
||||
|
||||
.poker-table-cell
|
||||
display: table-cell
|
||||
padding: 0 0 5px 2px
|
||||
border-bottom: 1px solid #d2d0d0
|
||||
text-align: center
|
||||
min-width: 45px
|
||||
|
||||
.poker-table-cell-who
|
||||
width: 150px
|
||||
vertical-align: middle
|
||||
|
||||
.poker-table-heading-left,
|
||||
.poker-table-heading-right
|
||||
display: table-header-group
|
||||
font-weight: bold
|
||||
border-top: 1px solid #808080
|
||||
|
||||
@media (max-width: 400px)
|
||||
.poker-table-heading-right
|
||||
display: none
|
||||
|
||||
.poker-table-body
|
||||
display: table-row-group
|
||||
|
||||
.poker-table-side-left,
|
||||
.poker-table-side-right
|
||||
display: inline-block
|
||||
|
||||
.poker-table-side-right
|
||||
padding-left: 10px
|
||||
|
||||
@media (max-width: 400px)
|
||||
.poker-table-side-right
|
||||
padding-left: 0px
|
||||
|
||||
.estimation-add
|
||||
display: block
|
||||
overflow: auto
|
||||
margin-top: 15px
|
||||
margin-bottom: 5px
|
||||
input
|
||||
display: inline-block
|
||||
float: right
|
||||
margin: auto
|
||||
margin-right: 10px
|
||||
width: 100px
|
||||
button
|
||||
display: inline-block
|
||||
float: right
|
||||
margin: auto
|
||||
|
||||
.poker-card
|
||||
width:48px
|
||||
height:72px
|
||||
float:left
|
||||
background:#fff
|
||||
border-radius:5px
|
||||
display:table
|
||||
box-sizing:border-box
|
||||
padding:5px
|
||||
margin:3px
|
||||
font-size:20px
|
||||
font-weight: bold
|
||||
text-shadow: #2d2d2d 1px 1px 0
|
||||
box-shadow:0 0 5px #aaaaaa
|
||||
text-align:center
|
||||
position:relative
|
||||
cursor: pointer
|
||||
|
||||
.inner
|
||||
display:table-cell
|
||||
vertical-align:middle
|
||||
border-radius:5px
|
||||
overflow:hidden
|
||||
background-color: #cecece
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,8 @@ template(name="checklists")
|
|||
i.fa.fa-check
|
||||
| {{_ 'checklists'}}
|
||||
if currentUser.isBoardMember
|
||||
.material-toggle-switch
|
||||
span.toggle-switch-title {{_ 'hide-checked-items'}}
|
||||
.material-toggle-switch(title="{{_ 'hide-checked-items'}}")
|
||||
//span.toggle-switch-title
|
||||
if hideCheckedItems
|
||||
input.toggle-switch(type="checkbox" id="toggleHideCheckedItemsButton" checked="checked")
|
||||
else
|
||||
|
|
@ -25,9 +25,8 @@ template(name="checklists")
|
|||
+inlinedForm(autoclose=false classNames="js-add-checklist" cardId = cardId)
|
||||
+addChecklistItemForm
|
||||
else
|
||||
a.js-open-inlined-form
|
||||
a.js-open-inlined-form(title="{{_ 'add-checklist'}}")
|
||||
i.fa.fa-plus
|
||||
| {{_ 'add-checklist'}}...
|
||||
|
||||
template(name="checklistDetail")
|
||||
.js-checklist.checklist
|
||||
|
|
@ -93,9 +92,8 @@ template(name="checklistItems")
|
|||
+inlinedForm(autoclose=false classNames="js-add-checklist-item" checklist = checklist)
|
||||
+addChecklistItemForm
|
||||
else
|
||||
a.add-checklist-item.js-open-inlined-form
|
||||
a.add-checklist-item.js-open-inlined-form(title="{{_ 'add-checklist-item'}}")
|
||||
i.fa.fa-plus
|
||||
| {{_ 'add-checklist-item'}}...
|
||||
|
||||
template(name='checklistItemDetail')
|
||||
.js-checklist-item.checklist-item(class="{{#if item.isFinished }}is-checked{{#if hideCheckedItems}} invisible{{/if}}{{/if}}")
|
||||
|
|
|
|||
|
|
@ -44,9 +44,20 @@
|
|||
align-items: center
|
||||
justify-content: center
|
||||
|
||||
.card-label-white
|
||||
background-color: #ffffff
|
||||
color: #000000 //Black text for better visibility
|
||||
border: 1px solid #c0c0c0
|
||||
|
||||
.card-label-white:hover
|
||||
color: #aaaaaa //grey text for better visibility
|
||||
|
||||
.card-label-green
|
||||
background-color: #3cb500
|
||||
|
||||
.card-label-green:hover
|
||||
color: #000000 //Black hover text for better visibility
|
||||
|
||||
.card-label-yellow
|
||||
background-color: #fad900
|
||||
color: #000000 //Black text for better visibility
|
||||
|
|
|
|||
|
|
@ -121,6 +121,11 @@ template(name="minicard")
|
|||
span.badge-text {{ voteCountPositive }}
|
||||
span.badge-icon.fa.fa-thumbs-down(class="{{#if $eq voteState false}}text-red{{/if}}")
|
||||
span.badge-text {{ voteCountNegative }}
|
||||
if getPokerQuestion
|
||||
.badge.badge-state-image-only(title=getPokerQuestion)
|
||||
span.badge-icon.fa.fa-check(class="{{#if pokerState}}text-green{{/if}}")
|
||||
if expiredPoker
|
||||
span.badge-text {{ getPokerEstimation }}
|
||||
if attachments.count
|
||||
.badge
|
||||
span.badge-icon.fa.fa-paperclip
|
||||
|
|
@ -134,3 +139,7 @@ template(name="minicard")
|
|||
span.badge-icon.fa.fa-sitemap
|
||||
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
|
||||
.badge
|
||||
span.badge-icon.fa.fa-sort
|
||||
span.badge-text {{ sort }}
|
||||
|
|
|
|||
|
|
@ -15,9 +15,8 @@ template(name="subtasks")
|
|||
+inlinedForm(autoclose=false classNames="js-add-subtask" cardId = cardId)
|
||||
+addSubtaskItemForm
|
||||
else
|
||||
a.js-open-inlined-form
|
||||
a.js-open-inlined-form(title="{{_ 'add-subtask'}}")
|
||||
i.fa.fa-plus
|
||||
| {{_ 'add-subtask'}}...
|
||||
|
||||
template(name="subtaskDetail")
|
||||
.js-subtasks.subtask
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ select
|
|||
margin-bottom: 8px
|
||||
|
||||
&.inline
|
||||
width: 100%
|
||||
width: 100%
|
||||
|
||||
option[disabled]
|
||||
color: #8c8c8c
|
||||
|
|
|
|||
|
|
@ -19,19 +19,14 @@ template(name="listBody")
|
|||
+inlinedForm(autoclose=false position="bottom")
|
||||
+addCardForm(listId=_id position="bottom")
|
||||
else
|
||||
a.open-minicard-composer.js-card-composer.js-open-inlined-form
|
||||
a.open-minicard-composer.js-card-composer.js-open-inlined-form(title="{{_ 'add-card-to-bottom-of-list'}}")
|
||||
i.fa.fa-plus
|
||||
| {{_ 'add-card'}}
|
||||
|
||||
template(name="spinnerList")
|
||||
.sk-spinner.sk-spinner-wave.sk-spinner-list(
|
||||
class=currentBoard.colorClass
|
||||
.sk-spinner.sk-spinner-list(
|
||||
class="{{currentBoard.colorClass}} {{getSkSpinnerName}}"
|
||||
id="showMoreResults")
|
||||
.sk-rect1
|
||||
.sk-rect2
|
||||
.sk-rect3
|
||||
.sk-rect4
|
||||
.sk-rect5
|
||||
+spinnerRaw
|
||||
|
||||
template(name="addCardForm")
|
||||
.minicard.minicard-composer.js-composer
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { Spinner } from '/client/lib/spinner';
|
||||
|
||||
const subManager = new SubsManager();
|
||||
const InfiniteScrollIter = 10;
|
||||
|
||||
|
|
@ -116,8 +118,6 @@ BlazeComponent.extendComponent({
|
|||
if (position === 'bottom') {
|
||||
this.scrollToBottom();
|
||||
}
|
||||
|
||||
formComponent.reset();
|
||||
}
|
||||
},
|
||||
|
||||
|
|
@ -552,7 +552,7 @@ BlazeComponent.extendComponent({
|
|||
board = Boards.findOne((Meteor.user().profile || {}).templatesBoardId);
|
||||
} else {
|
||||
// Prefetch first non-current board id
|
||||
board = Boards.findOne({
|
||||
board = Boards.find({
|
||||
archived: false,
|
||||
'members.userId': Meteor.userId(),
|
||||
_id: {
|
||||
|
|
@ -698,7 +698,7 @@ BlazeComponent.extendComponent({
|
|||
},
|
||||
}).register('searchElementPopup');
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
(class extends Spinner {
|
||||
onCreated() {
|
||||
this.cardlimit = this.parentComponent().cardlimit;
|
||||
|
||||
|
|
@ -726,7 +726,7 @@ BlazeComponent.extendComponent({
|
|||
.parentComponent()
|
||||
.data()._id;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
onRendered() {
|
||||
this.spinner = this.find('.sk-spinner-list');
|
||||
|
|
@ -741,47 +741,58 @@ BlazeComponent.extendComponent({
|
|||
);
|
||||
|
||||
this.updateList();
|
||||
},
|
||||
}
|
||||
|
||||
onDestroyed() {
|
||||
$(this.container).off(`scroll.spinner_${this.swimlaneId}_${this.listId}`);
|
||||
$(window).off(`resize.spinner_${this.swimlaneId}_${this.listId}`);
|
||||
},
|
||||
}
|
||||
|
||||
checkIdleTime() {
|
||||
return window.requestIdleCallback ||
|
||||
function(handler) {
|
||||
const startTime = Date.now();
|
||||
return setTimeout(function() {
|
||||
handler({
|
||||
didTimeout: false,
|
||||
timeRemaining() {
|
||||
return Math.max(0, 50.0 - (Date.now() - startTime));
|
||||
},
|
||||
});
|
||||
}, 1);
|
||||
};
|
||||
}
|
||||
|
||||
updateList() {
|
||||
// Use fallback when requestIdleCallback is not available on iOS and Safari
|
||||
// https://www.afasterweb.com/2017/11/20/utilizing-idle-moments/
|
||||
checkIdleTime =
|
||||
window.requestIdleCallback ||
|
||||
function(handler) {
|
||||
const startTime = Date.now();
|
||||
return setTimeout(function() {
|
||||
handler({
|
||||
didTimeout: false,
|
||||
timeRemaining() {
|
||||
return Math.max(0, 50.0 - (Date.now() - startTime));
|
||||
},
|
||||
});
|
||||
}, 1);
|
||||
};
|
||||
|
||||
if (this.spinnerInView()) {
|
||||
this.cardlimit.set(this.cardlimit.get() + InfiniteScrollIter);
|
||||
checkIdleTime(() => this.updateList());
|
||||
this.checkIdleTime(() => this.updateList());
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
spinnerInView() {
|
||||
const parentViewHeight = this.container.clientHeight;
|
||||
const bottomViewPosition = this.container.scrollTop + parentViewHeight;
|
||||
|
||||
const threshold = this.spinner.offsetTop;
|
||||
|
||||
// spinner deleted
|
||||
if (!this.spinner.offsetTop) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return bottomViewPosition > threshold;
|
||||
},
|
||||
}).register('spinnerList');
|
||||
const parentViewHeight = this.container.clientHeight;
|
||||
const bottomViewPosition = this.container.scrollTop + parentViewHeight;
|
||||
|
||||
let spinnerOffsetTop = this.spinner.offsetTop;
|
||||
|
||||
const addCard = $(this.container).find("a.open-minicard-composer").first()[0];
|
||||
if (addCard !== undefined) {
|
||||
spinnerOffsetTop -= addCard.clientHeight;
|
||||
}
|
||||
|
||||
return bottomViewPosition > spinnerOffsetTop;
|
||||
}
|
||||
|
||||
getSkSpinnerName() {
|
||||
return "sk-spinner-" + super.getSpinnerName().toLowerCase();
|
||||
}
|
||||
}.register('spinnerList'));
|
||||
|
|
|
|||
|
|
@ -28,8 +28,8 @@ template(name="listHeader")
|
|||
div.list-header-menu
|
||||
unless currentUser.isCommentOnly
|
||||
if canSeeAddCard
|
||||
a.js-add-card.fa.fa-plus.list-header-plus-icon
|
||||
a.fa.fa-navicon.js-open-list-menu
|
||||
a.js-add-card.fa.fa-plus.list-header-plus-icon(title="{{_ 'add-card-to-top-of-list'}}")
|
||||
a.fa.fa-navicon.js-open-list-menu(title="{{_ 'listActionPopup-title'}}")
|
||||
else
|
||||
a.list-header-menu-icon.fa.fa-angle-right.js-select-list
|
||||
a.list-header-handle.handle.fa.fa-arrows.js-list-handle
|
||||
|
|
@ -41,8 +41,8 @@ template(name="listHeader")
|
|||
//if isBoardAdmin
|
||||
// a.fa.js-list-star.list-header-plus-icon(class="fa-star{{#unless starred}}-o{{/unless}}")
|
||||
if canSeeAddCard
|
||||
a.js-add-card.fa.fa-plus.list-header-plus-icon
|
||||
a.fa.fa-navicon.js-open-list-menu
|
||||
a.js-add-card.fa.fa-plus.list-header-plus-icon(title="{{_ 'add-card-to-top-of-list'}}")
|
||||
a.fa.fa-navicon.js-open-list-menu(title="{{_ 'listActionPopup-title'}}")
|
||||
if currentUser.isBoardAdmin
|
||||
if showDesktopDragHandles
|
||||
a.list-header-handle.handle.fa.fa-arrows.js-list-handle
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ Template.editor.onRendered(() => {
|
|||
['table', ['table']],
|
||||
//['insert', ['link', 'picture', 'video']], // iframe tag will be sanitized TODO if iframe[class=note-video-clip] can be added into safe list, insert video can be enabled
|
||||
['insert', ['link']], //, 'picture']], // modal popup has issue somehow :(
|
||||
['view', ['fullscreen', 'help']],
|
||||
['view', ['fullscreen', 'codeview', 'help']],
|
||||
];
|
||||
const cleanPastedHTML = function(input) {
|
||||
const badTags = [
|
||||
|
|
@ -229,7 +229,7 @@ Template.editor.onRendered(() => {
|
|||
// (and multiplies by pasting more) by changing paste "p" to "br".
|
||||
// Fixes https://github.com/wekan/wekan/2890 .
|
||||
// == Fix Start ==
|
||||
//someNote.execCommand('defaultParagraphSeparator', false, 'br');
|
||||
someNote.execCommand('defaultParagraphSeparator', false, 'br');
|
||||
// == Fix End ==
|
||||
const original = someNote.summernote('code');
|
||||
const cleaned = cleanPastedHTML(original); //this is where to call whatever clean function you want. I have mine in a different file, called CleanPastedHTML.
|
||||
|
|
|
|||
|
|
@ -158,40 +158,42 @@ class GlobalSearchComponent extends CardSearchPagedComponent {
|
|||
['# ', 'globalSearch-instructions-heading'],
|
||||
['\n', 'globalSearch-instructions-description'],
|
||||
['\n\n', 'globalSearch-instructions-operators'],
|
||||
['\n* ', 'globalSearch-instructions-operator-board'],
|
||||
['\n* ', 'globalSearch-instructions-operator-list'],
|
||||
['\n* ', 'globalSearch-instructions-operator-swimlane'],
|
||||
['\n* ', 'globalSearch-instructions-operator-comment'],
|
||||
['\n* ', 'globalSearch-instructions-operator-label'],
|
||||
['\n* ', 'globalSearch-instructions-operator-hash'],
|
||||
['\n* ', 'globalSearch-instructions-operator-user'],
|
||||
['\n* ', 'globalSearch-instructions-operator-at'],
|
||||
['\n* ', 'globalSearch-instructions-operator-member'],
|
||||
['\n* ', 'globalSearch-instructions-operator-assignee'],
|
||||
['\n* ', 'globalSearch-instructions-operator-creator'],
|
||||
['\n* ', 'globalSearch-instructions-operator-due'],
|
||||
['\n* ', 'globalSearch-instructions-operator-created'],
|
||||
['\n* ', 'globalSearch-instructions-operator-modified'],
|
||||
['\n* ', 'globalSearch-instructions-operator-status'],
|
||||
['\n * ', 'globalSearch-instructions-status-archived'],
|
||||
['\n * ', 'globalSearch-instructions-status-public'],
|
||||
['\n * ', 'globalSearch-instructions-status-private'],
|
||||
['\n * ', 'globalSearch-instructions-status-all'],
|
||||
['\n * ', 'globalSearch-instructions-status-ended'],
|
||||
['\n* ', 'globalSearch-instructions-operator-has'],
|
||||
['\n* ', 'globalSearch-instructions-operator-sort'],
|
||||
['\n* ', 'globalSearch-instructions-operator-limit'],
|
||||
['\n- ', 'globalSearch-instructions-operator-board'],
|
||||
['\n- ', 'globalSearch-instructions-operator-list'],
|
||||
['\n- ', 'globalSearch-instructions-operator-swimlane'],
|
||||
['\n- ', 'globalSearch-instructions-operator-comment'],
|
||||
['\n- ', 'globalSearch-instructions-operator-label'],
|
||||
['\n- ', 'globalSearch-instructions-operator-hash'],
|
||||
['\n- ', 'globalSearch-instructions-operator-user'],
|
||||
['\n- ', 'globalSearch-instructions-operator-at'],
|
||||
['\n- ', 'globalSearch-instructions-operator-member'],
|
||||
['\n- ', 'globalSearch-instructions-operator-assignee'],
|
||||
['\n- ', 'globalSearch-instructions-operator-creator'],
|
||||
['\n- ', 'globalSearch-instructions-operator-due'],
|
||||
['\n- ', 'globalSearch-instructions-operator-created'],
|
||||
['\n- ', 'globalSearch-instructions-operator-modified'],
|
||||
['\n- ', 'globalSearch-instructions-operator-status'],
|
||||
['\n - ', 'globalSearch-instructions-status-archived'],
|
||||
['\n - ', 'globalSearch-instructions-status-public'],
|
||||
['\n - ', 'globalSearch-instructions-status-private'],
|
||||
['\n - ', 'globalSearch-instructions-status-all'],
|
||||
['\n - ', 'globalSearch-instructions-status-ended'],
|
||||
['\n- ', 'globalSearch-instructions-operator-has'],
|
||||
['\n- ', 'globalSearch-instructions-operator-sort'],
|
||||
['\n- ', 'globalSearch-instructions-operator-limit'],
|
||||
['\n## ', 'heading-notes'],
|
||||
['\n* ', 'globalSearch-instructions-notes-1'],
|
||||
['\n* ', 'globalSearch-instructions-notes-2'],
|
||||
['\n* ', 'globalSearch-instructions-notes-3'],
|
||||
['\n* ', 'globalSearch-instructions-notes-3-2'],
|
||||
['\n* ', 'globalSearch-instructions-notes-4'],
|
||||
['\n* ', 'globalSearch-instructions-notes-5'],
|
||||
['\n- ', 'globalSearch-instructions-notes-1'],
|
||||
['\n- ', 'globalSearch-instructions-notes-2'],
|
||||
['\n- ', 'globalSearch-instructions-notes-3'],
|
||||
['\n- ', 'globalSearch-instructions-notes-3-2'],
|
||||
['\n- ', 'globalSearch-instructions-notes-4'],
|
||||
['\n- ', 'globalSearch-instructions-notes-5'],
|
||||
].forEach(([prefix, instruction]) => {
|
||||
text += `${prefix}${TAPi18n.__(instruction, tags)}`;
|
||||
text += `${prefix}${TAPi18n.__(instruction, tags)}`
|
||||
// Replace *<text>* with `<text>` so markdown shows correctly
|
||||
.replace(/\*\</, '`<')
|
||||
.replace(/\>\*/, '\>\`')
|
||||
});
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -31,12 +31,12 @@ template(name="header")
|
|||
unless currentSetting.hideLogo
|
||||
if currentSetting.customTopLeftCornerLogoImageUrl
|
||||
if currentSetting.customTopLeftCornerLogoLinkUrl
|
||||
a(href="{{currentSetting.customTopLeftCornerLogoLinkUrl}}")
|
||||
a(href="{{currentSetting.customTopLeftCornerLogoLinkUrl}}" alt="{{currentSetting.productName}}" title="{{currentSetting.productName}}")
|
||||
img(src="{{currentSetting.customTopLeftCornerLogoImageUrl}}" height="{{#if currentSetting.customTopLeftCornerLogoHeight}}#{currentSetting.customTopLeftCornerLogoHeight}{{else}}27{{/if}}" width="auto" margin="0" padding="0")
|
||||
unless currentSetting.customTopLeftCornerLogoLinkUrl
|
||||
img(src="{{currentSetting.customTopLeftCornerLogoImageUrl}}" height="{{#if currentSetting.customTopLeftCornerLogoHeight}}#{currentSetting.customTopLeftCornerLogoHeight}{{else}}27{{/if}}" width="auto" margin="0" padding="0")
|
||||
img(src="{{currentSetting.customTopLeftCornerLogoImageUrl}}" height="{{#if currentSetting.customTopLeftCornerLogoHeight}}#{currentSetting.customTopLeftCornerLogoHeight}{{else}}27{{/if}}" width="auto" margin="0" padding="0" alt="{{currentSetting.productName}}" title="{{currentSetting.productName}}")
|
||||
unless currentSetting.customTopLeftCornerLogoImageUrl
|
||||
img(src="{{pathFor '/logo-header.png'}}" alt="")
|
||||
img(src="{{pathFor '/logo-header.png'}}" alt="{{currentSetting.productName}}" title="{{currentSetting.productName}}")
|
||||
span.allBoards
|
||||
a(href="{{pathFor 'home'}}")
|
||||
span.fa.fa-home
|
||||
|
|
|
|||
5
client/components/main/spinner.jade
Normal file
5
client/components/main/spinner.jade
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
template(name="spinner")
|
||||
+Template.dynamic(template=getSpinnerTemplate)
|
||||
|
||||
template(name="spinnerRaw")
|
||||
+Template.dynamic(template=getSpinnerTemplateRaw)
|
||||
11
client/components/main/spinner.js
Normal file
11
client/components/main/spinner.js
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
import { Spinner } from '/client/lib/spinner';
|
||||
|
||||
(class extends Spinner {
|
||||
}.register('spinner'));
|
||||
|
||||
(class extends Spinner {
|
||||
getSpinnerTemplateRaw() {
|
||||
let ret = super.getSpinnerTemplate() + 'Raw';
|
||||
return ret;
|
||||
}
|
||||
}.register('spinnerRaw'));
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
.sk-spinner.sk-spinner-wave(class=currentBoard.colorClass)
|
||||
.sk-rect1
|
||||
.sk-rect2
|
||||
.sk-rect3
|
||||
.sk-rect4
|
||||
.sk-rect5
|
||||
11
client/components/main/spinner_bounce.jade
Normal file
11
client/components/main/spinner_bounce.jade
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
template(name="spinnerBounce")
|
||||
.sk-spinner.sk-spinner-bounce(class=currentBoard.colorClass)
|
||||
+spinnerBounceRaw
|
||||
|
||||
template(name="spinnerBounceRaw")
|
||||
.sk-bounce1
|
||||
|
|
||||
.sk-bounce2
|
||||
|
|
||||
.sk-bounce3
|
||||
|
|
||||
44
client/components/main/spinner_bounce.styl
Normal file
44
client/components/main/spinner_bounce.styl
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
@import 'nib'
|
||||
|
||||
// From https://github.com/tobiasahlin/SpinKit
|
||||
.sk-spinner-bounce {
|
||||
margin: 100px auto 0;
|
||||
width: 70px;
|
||||
text-align: center;
|
||||
|
||||
div {
|
||||
width: 18px;
|
||||
height: 18px;
|
||||
background-color: #333;
|
||||
|
||||
border-radius: 100%;
|
||||
display: inline-block;
|
||||
-webkit-animation: sk-bouncedelay 1.4s infinite ease-in-out both;
|
||||
animation: sk-bouncedelay 1.4s infinite ease-in-out both;
|
||||
}
|
||||
|
||||
.sk-bounce1 {
|
||||
-webkit-animation-delay: -0.32s;
|
||||
animation-delay: -0.32s;
|
||||
}
|
||||
|
||||
.sk-bounce2 {
|
||||
-webkit-animation-delay: -0.16s;
|
||||
animation-delay: -0.16s;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes sk-bouncedelay {
|
||||
0%, 80%, 100% { -webkit-transform: scale(0) }
|
||||
40% { -webkit-transform: scale(1.0) }
|
||||
}
|
||||
|
||||
@keyframes sk-bouncedelay {
|
||||
0%, 80%, 100% {
|
||||
-webkit-transform: scale(0);
|
||||
transform: scale(0);
|
||||
} 40% {
|
||||
-webkit-transform: scale(1.0);
|
||||
transform: scale(1.0);
|
||||
}
|
||||
}
|
||||
8
client/components/main/spinner_cube.jade
Normal file
8
client/components/main/spinner_cube.jade
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
template(name="spinnerCube")
|
||||
.sk-spinner.sk-spinner-cube(class=currentBoard.colorClass)
|
||||
+spinnerCubeRaw
|
||||
|
||||
template(name="spinnerCubeRaw")
|
||||
.sk-cube1
|
||||
.sk-cube2
|
||||
.sk-cube3
|
||||
52
client/components/main/spinner_cube.styl
Normal file
52
client/components/main/spinner_cube.styl
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
@import 'nib'
|
||||
|
||||
// From https://github.com/tobiasahlin/SpinKit
|
||||
.sk-spinner-cube {
|
||||
margin: 100px auto;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.sk-cube1, .sk-cube2 {
|
||||
background-color: #333;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
-webkit-animation: sk-cubemove 1.8s infinite ease-in-out;
|
||||
animation: sk-cubemove 1.8s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.sk-cube2 {
|
||||
-webkit-animation-delay: -0.9s;
|
||||
animation-delay: -0.9s;
|
||||
}
|
||||
|
||||
@-webkit-keyframes sk-cubemove {
|
||||
25% { -webkit-transform: translateX(35px) rotate(-90deg) scale(0.5) }
|
||||
50% { -webkit-transform: translateX(35px) translateY(35px) rotate(-180deg) }
|
||||
75% { -webkit-transform: translateX(0px) translateY(35px) rotate(-270deg) scale(0.5) }
|
||||
100% { -webkit-transform: rotate(-360deg) }
|
||||
}
|
||||
|
||||
@keyframes sk-cubemove {
|
||||
25% {
|
||||
transform: translateX(35px) rotate(-90deg) scale(0.5);
|
||||
-webkit-transform: translateX(35px) rotate(-90deg) scale(0.5);
|
||||
} 50% {
|
||||
transform: translateX(35px) translateY(35px) rotate(-179deg);
|
||||
-webkit-transform: translateX(35px) translateY(35px) rotate(-179deg);
|
||||
} 50.1% {
|
||||
transform: translateX(35px) translateY(35px) rotate(-180deg);
|
||||
-webkit-transform: translateX(35px) translateY(35px) rotate(-180deg);
|
||||
} 75% {
|
||||
transform: translateX(0px) translateY(35px) rotate(-270deg) scale(0.5);
|
||||
-webkit-transform: translateX(0px) translateY(35px) rotate(-270deg) scale(0.5);
|
||||
} 100% {
|
||||
transform: rotate(-360deg);
|
||||
-webkit-transform: rotate(-360deg);
|
||||
}
|
||||
}
|
||||
14
client/components/main/spinner_cube_grid.jade
Normal file
14
client/components/main/spinner_cube_grid.jade
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
template(name="spinnerCubeGrid")
|
||||
.sk-spinner.sk-spinner-cube-grid(class=currentBoard.colorClass)
|
||||
+spinnerCubeGridRaw
|
||||
|
||||
template(name="spinnerCubeGridRaw")
|
||||
.sk-cube-grid.sk-cube-grid1
|
||||
.sk-cube-grid.sk-cube-grid2
|
||||
.sk-cube-grid.sk-cube-grid3
|
||||
.sk-cube-grid.sk-cube-grid4
|
||||
.sk-cube-grid.sk-cube-grid5
|
||||
.sk-cube-grid.sk-cube-grid6
|
||||
.sk-cube-grid.sk-cube-grid7
|
||||
.sk-cube-grid.sk-cube-grid8
|
||||
.sk-cube-grid.sk-cube-grid9
|
||||
64
client/components/main/spinner_cube_grid.styl
Normal file
64
client/components/main/spinner_cube_grid.styl
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
@import 'nib'
|
||||
|
||||
// From https://github.com/tobiasahlin/SpinKit
|
||||
.sk-spinner-cube-grid {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
margin: 100px auto;
|
||||
}
|
||||
|
||||
.sk-spinner-cube-grid .sk-cube-grid {
|
||||
width: 33%;
|
||||
height: 33%;
|
||||
background-color: #333;
|
||||
float: left;
|
||||
-webkit-animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out;
|
||||
animation: sk-cubeGridScaleDelay 1.3s infinite ease-in-out;
|
||||
}
|
||||
.sk-spinner-cube-grid .sk-cube-grid1 {
|
||||
-webkit-animation-delay: 0.2s;
|
||||
animation-delay: 0.2s; }
|
||||
.sk-spinner-cube-grid .sk-cube-grid2 {
|
||||
-webkit-animation-delay: 0.3s;
|
||||
animation-delay: 0.3s; }
|
||||
.sk-spinner-cube-grid .sk-cube-grid3 {
|
||||
-webkit-animation-delay: 0.4s;
|
||||
animation-delay: 0.4s; }
|
||||
.sk-spinner-cube-grid .sk-cube-grid4 {
|
||||
-webkit-animation-delay: 0.1s;
|
||||
animation-delay: 0.1s; }
|
||||
.sk-spinner-cube-grid .sk-cube-grid5 {
|
||||
-webkit-animation-delay: 0.2s;
|
||||
animation-delay: 0.2s; }
|
||||
.sk-spinner-cube-grid .sk-cube-grid6 {
|
||||
-webkit-animation-delay: 0.3s;
|
||||
animation-delay: 0.3s; }
|
||||
.sk-spinner-cube-grid .sk-cube-grid7 {
|
||||
-webkit-animation-delay: 0s;
|
||||
animation-delay: 0s; }
|
||||
.sk-spinner-cube-grid .sk-cube-grid8 {
|
||||
-webkit-animation-delay: 0.1s;
|
||||
animation-delay: 0.1s; }
|
||||
.sk-spinner-cube-grid .sk-cube-grid9 {
|
||||
-webkit-animation-delay: 0.2s;
|
||||
animation-delay: 0.2s; }
|
||||
|
||||
@-webkit-keyframes sk-cubeGridScaleDelay {
|
||||
0%, 70%, 100% {
|
||||
-webkit-transform: scale3D(1, 1, 1);
|
||||
transform: scale3D(1, 1, 1);
|
||||
} 35% {
|
||||
-webkit-transform: scale3D(0, 0, 1);
|
||||
transform: scale3D(0, 0, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sk-cubeGridScaleDelay {
|
||||
0%, 70%, 100% {
|
||||
-webkit-transform: scale3D(1, 1, 1);
|
||||
transform: scale3D(1, 1, 1);
|
||||
} 35% {
|
||||
-webkit-transform: scale3D(0, 0, 1);
|
||||
transform: scale3D(0, 0, 1);
|
||||
}
|
||||
}
|
||||
7
client/components/main/spinner_dot.jade
Normal file
7
client/components/main/spinner_dot.jade
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
template(name="spinnerDot")
|
||||
.sk-spinner.sk-spinner-dot(class=currentBoard.colorClass)
|
||||
+spinnerDotRaw
|
||||
|
||||
template(name="spinnerDotRaw")
|
||||
.sk-dot1
|
||||
.sk-dot2
|
||||
51
client/components/main/spinner_dot.styl
Normal file
51
client/components/main/spinner_dot.styl
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
@import 'nib'
|
||||
|
||||
// From https://github.com/tobiasahlin/SpinKit
|
||||
.sk-spinner-dot {
|
||||
margin: 100px auto;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
position: relative;
|
||||
text-align: center;
|
||||
|
||||
-webkit-animation: sk-rotate 2.0s infinite linear;
|
||||
animation: sk-rotate 2.0s infinite linear;
|
||||
}
|
||||
|
||||
.sk-dot1, .sk-dot2 {
|
||||
width: 40%;
|
||||
height: 40%;
|
||||
display: inline-block;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
background-color: #333;
|
||||
border-radius: 100%;
|
||||
|
||||
-webkit-animation: sk-bounce 2.0s infinite ease-in-out;
|
||||
animation: sk-bounce 2.0s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.sk-dot2 {
|
||||
top: auto;
|
||||
bottom: 0;
|
||||
-webkit-animation-delay: -1.0s;
|
||||
animation-delay: -1.0s;
|
||||
}
|
||||
|
||||
@-webkit-keyframes sk-rotate { 100% { -webkit-transform: rotate(360deg) }}
|
||||
@keyframes sk-rotate { 100% { transform: rotate(360deg); -webkit-transform: rotate(360deg) }}
|
||||
|
||||
@-webkit-keyframes sk-bounce {
|
||||
0%, 100% { -webkit-transform: scale(0.0) }
|
||||
50% { -webkit-transform: scale(1.0) }
|
||||
}
|
||||
|
||||
@keyframes sk-bounce {
|
||||
0%, 100% {
|
||||
transform: scale(0.0);
|
||||
-webkit-transform: scale(0.0);
|
||||
} 50% {
|
||||
transform: scale(1.0);
|
||||
-webkit-transform: scale(1.0);
|
||||
}
|
||||
}
|
||||
7
client/components/main/spinner_double_bounce.jade
Normal file
7
client/components/main/spinner_double_bounce.jade
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
template(name="spinnerDoubleBounce")
|
||||
.sk-spinner.sk-spinner-double-bounce(class=currentBoard.colorClass)
|
||||
+spinnerDoubleBounceRaw
|
||||
|
||||
template(name="spinnerDoubleBounceRaw")
|
||||
.sk-double-bounce1
|
||||
.sk-double-bounce2
|
||||
44
client/components/main/spinner_double_bounce.styl
Normal file
44
client/components/main/spinner_double_bounce.styl
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
@import 'nib'
|
||||
|
||||
// From https://github.com/tobiasahlin/SpinKit
|
||||
.sk-spinner-double-bounce {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
|
||||
position: relative;
|
||||
margin: 100px auto;
|
||||
}
|
||||
|
||||
.sk-double-bounce1, .sk-double-bounce2 {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: 50%;
|
||||
background-color: #333;
|
||||
opacity: 0.6;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
|
||||
-webkit-animation: sk-bounce 2.0s infinite ease-in-out;
|
||||
animation: sk-bounce 2.0s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.sk-double-bounce2 {
|
||||
-webkit-animation-delay: -1.0s;
|
||||
animation-delay: -1.0s;
|
||||
}
|
||||
|
||||
@-webkit-keyframes sk-bounce {
|
||||
0%, 100% { -webkit-transform: scale(0.0) }
|
||||
50% { -webkit-transform: scale(1.0) }
|
||||
}
|
||||
|
||||
@keyframes sk-bounce {
|
||||
0%, 100% {
|
||||
transform: scale(0.0);
|
||||
-webkit-transform: scale(0.0);
|
||||
} 50% {
|
||||
transform: scale(1.0);
|
||||
-webkit-transform: scale(1.0);
|
||||
}
|
||||
}
|
||||
6
client/components/main/spinner_rotateplane.jade
Normal file
6
client/components/main/spinner_rotateplane.jade
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
template(name="spinnerRotateplane")
|
||||
.sk-spinner.sk-spinner-rotateplane(class=currentBoard.colorClass)
|
||||
+spinnerRotateplaneRaw
|
||||
|
||||
template(name="spinnerRotateplaneRaw")
|
||||
.sk-rotateplane1
|
||||
38
client/components/main/spinner_rotateplane.styl
Normal file
38
client/components/main/spinner_rotateplane.styl
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
@import 'nib'
|
||||
|
||||
// From https://github.com/tobiasahlin/SpinKit
|
||||
.sk-spinner-rotateplane {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
text-align: center;
|
||||
|
||||
margin: 100px auto;
|
||||
-webkit-animation: sk-rotateplane 1.2s infinite ease-in-out;
|
||||
animation: sk-rotateplane 1.2s infinite ease-in-out;
|
||||
|
||||
div {
|
||||
background-color: #333;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes sk-rotateplane {
|
||||
0% { -webkit-transform: perspective(120px) }
|
||||
50% { -webkit-transform: perspective(120px) rotateY(180deg) }
|
||||
100% { -webkit-transform: perspective(120px) rotateY(180deg) rotateX(180deg) }
|
||||
}
|
||||
|
||||
@keyframes sk-rotateplane {
|
||||
0% {
|
||||
transform: perspective(120px) rotateX(0deg) rotateY(0deg);
|
||||
-webkit-transform: perspective(120px) rotateX(0deg) rotateY(0deg)
|
||||
} 50% {
|
||||
transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg);
|
||||
-webkit-transform: perspective(120px) rotateX(-180.1deg) rotateY(0deg)
|
||||
} 100% {
|
||||
transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
|
||||
-webkit-transform: perspective(120px) rotateX(-180deg) rotateY(-179.9deg);
|
||||
}
|
||||
}
|
||||
6
client/components/main/spinner_scaleout.jade
Normal file
6
client/components/main/spinner_scaleout.jade
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
template(name="spinnerScaleout")
|
||||
.sk-spinner.sk-spinner-scaleout(class=currentBoard.colorClass)
|
||||
+spinnerScaleoutRaw
|
||||
|
||||
template(name="spinnerScaleoutRaw")
|
||||
.sk-scaleout1
|
||||
40
client/components/main/spinner_scaleout.styl
Normal file
40
client/components/main/spinner_scaleout.styl
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
@import 'nib'
|
||||
|
||||
// From https://github.com/tobiasahlin/SpinKit
|
||||
.sk-spinner-scaleout {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
text-align: center;
|
||||
|
||||
margin: 100px auto;
|
||||
|
||||
border-radius: 100%;
|
||||
-webkit-animation: sk-scaleout 1.0s infinite ease-in-out;
|
||||
animation: sk-scaleout 1.0s infinite ease-in-out;
|
||||
|
||||
div {
|
||||
background-color: #333;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: inline-block;
|
||||
}
|
||||
}
|
||||
|
||||
@-webkit-keyframes sk-scaleout {
|
||||
0% { -webkit-transform: scale(0) }
|
||||
100% {
|
||||
-webkit-transform: scale(1.0);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes sk-scaleout {
|
||||
0% {
|
||||
-webkit-transform: scale(0);
|
||||
transform: scale(0);
|
||||
} 100% {
|
||||
-webkit-transform: scale(1.0);
|
||||
transform: scale(1.0);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
15
client/components/main/spinner_wave.jade
Normal file
15
client/components/main/spinner_wave.jade
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
template(name="spinnerWave")
|
||||
.sk-spinner.sk-spinner-wave(class=currentBoard.colorClass)
|
||||
+spinnerWaveRaw
|
||||
|
||||
template(name="spinnerWaveRaw")
|
||||
.sk-rect1
|
||||
|
|
||||
.sk-rect2
|
||||
|
|
||||
.sk-rect3
|
||||
|
|
||||
.sk-rect4
|
||||
|
|
||||
.sk-rect5
|
||||
|
|
||||
|
|
@ -1,21 +1,7 @@
|
|||
@import 'nib'
|
||||
|
||||
/*
|
||||
* From https://github.com/tobiasahlin/SpinKit
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* <div class="sk-spinner sk-spinner-wave">
|
||||
* <div class="sk-rect1"></div>
|
||||
* <div class="sk-rect2"></div>
|
||||
* <div class="sk-rect3"></div>
|
||||
* <div class="sk-rect4"></div>
|
||||
* <div class="sk-rect5"></div>
|
||||
* </div>
|
||||
*
|
||||
*/
|
||||
|
||||
.sk-spinner {
|
||||
// From https://github.com/tobiasahlin/SpinKit
|
||||
.sk-spinner-wave {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin: auto;
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
template(name='notifications')
|
||||
#notifications.board-header-btns.right
|
||||
a.notifications-drawer-toggle.fa.fa-bell(class="{{#if $gt unreadNotifications 0}}alert{{/if}}")
|
||||
a.notifications-drawer-toggle.fa.fa-bell(class="{{#if $gt unreadNotifications 0}}alert{{/if}}" title="{{_ 'notifications'}}")
|
||||
if $.Session.get 'showNotificationsDrawer'
|
||||
+notificationsDrawer(unreadNotifications=unreadNotifications)
|
||||
|
|
|
|||
|
|
@ -110,6 +110,8 @@ template(name="peopleGeneral")
|
|||
th {{_ 'active'}}
|
||||
th {{_ 'authentication-method'}}
|
||||
th {{_ 'import-usernames'}}
|
||||
th {{_ 'organizations'}}
|
||||
th {{_ 'teams'}}
|
||||
th
|
||||
+newUserRow
|
||||
each user in peopleList
|
||||
|
|
@ -132,28 +134,28 @@ template(name="newUserRow")
|
|||
|
||||
template(name="orgRow")
|
||||
tr
|
||||
if orgData.loginDisabled
|
||||
if orgData.orgIsActive
|
||||
td <s>{{ orgData.orgDisplayName }}</s>
|
||||
else
|
||||
td {{ orgData.orgDisplayName }}
|
||||
if orgData.loginDisabled
|
||||
if orgData.orgIsActive
|
||||
td <s>{{ orgData.orgDesc }}</s>
|
||||
else
|
||||
td {{ orgData.orgDesc }}
|
||||
if orgData.loginDisabled
|
||||
td <s>{{ orgData.orgName }}</s>
|
||||
if orgData.orgIsActive
|
||||
td <s>{{ orgData.orgShortName }}</s>
|
||||
else
|
||||
td {{ orgData.orgName }}
|
||||
if orgData.loginDisabled
|
||||
td {{ orgData.orgShortName }}
|
||||
if orgData.orgIsActive
|
||||
td <s>{{ orgData.orgWebsite }}</s>
|
||||
else
|
||||
td {{ orgData.orgWebsite }}
|
||||
if orgData.loginDisabled
|
||||
if orgData.orgIsActive
|
||||
td <s>{{ moment orgData.createdAt 'LLL' }}</s>
|
||||
else
|
||||
td {{ moment orgData.createdAt 'LLL' }}
|
||||
td
|
||||
if orgData.loginDisabled
|
||||
if orgData.orgIsActive
|
||||
| {{_ 'no'}}
|
||||
else
|
||||
| {{_ 'yes'}}
|
||||
|
|
@ -166,28 +168,28 @@ template(name="orgRow")
|
|||
|
||||
template(name="teamRow")
|
||||
tr
|
||||
if teamData.loginDisabled
|
||||
if teamData.teamIsActive
|
||||
td <s>{{ teamData.teamDisplayName }}</s>
|
||||
else
|
||||
td {{ teamData.teamDisplayName }}
|
||||
if teamData.loginDisabled
|
||||
if teamData.teamIsActive
|
||||
td <s>{{ teamData.teamDesc }}</s>
|
||||
else
|
||||
td {{ teamData.teamDesc }}
|
||||
if teamData.loginDisabled
|
||||
td <s>{{ teamData.teamName }}</s>
|
||||
if teamData.teamIsActive
|
||||
td <s>{{ teamData.teamShortName }}</s>
|
||||
else
|
||||
td {{ teamData.teamName }}
|
||||
if teamData.loginDisabled
|
||||
td {{ teamData.teamShortName }}
|
||||
if teamData.teamIsActive
|
||||
td <s>{{ teamData.teamWebsite }}</s>
|
||||
else
|
||||
td {{ teamData.teamWebsite }}
|
||||
if orgData.loginDisabled
|
||||
if teamData.teamIsActive
|
||||
td <s>{{ moment teamData.createdAt 'LLL' }}</s>
|
||||
else
|
||||
td {{ moment teamData.createdAt 'LLL' }}
|
||||
td
|
||||
if teamData.loginDisabled
|
||||
if teamData.teamIsActive
|
||||
| {{_ 'no'}}
|
||||
else
|
||||
| {{_ 'yes'}}
|
||||
|
|
@ -257,6 +259,14 @@ template(name="peopleRow")
|
|||
td <s>{{ userData.importUsernamesString }}</s>
|
||||
else
|
||||
td {{ userData.importUsernamesString }}
|
||||
if userData.loginDisabled
|
||||
td <s>{{ userData.orgsUserBelongs }}</s>
|
||||
else
|
||||
td {{ userData.orgsUserBelongs }}
|
||||
if userData.loginDisabled
|
||||
td <s>{{ userData.teamsUserBelongs }}</s>
|
||||
else
|
||||
td {{ userData.teamsUserBelongs }}
|
||||
td
|
||||
a.edit-user
|
||||
i.fa.fa-edit
|
||||
|
|
@ -269,7 +279,7 @@ template(name="editOrgPopup")
|
|||
label.hide.orgId(type="text" value=org._id)
|
||||
label
|
||||
| {{_ 'displayName'}}
|
||||
input.js-orgDisplayName(type="text" value=org.displayName required)
|
||||
input.js-orgDisplayName(type="text" value=org.orgDisplayName required)
|
||||
span.error.hide.orgname-taken
|
||||
| {{_ 'error-orgname-taken'}}
|
||||
label
|
||||
|
|
@ -285,7 +295,7 @@ template(name="editOrgPopup")
|
|||
| {{_ 'active'}}
|
||||
select.select-active.js-org-isactive
|
||||
option(value="false") {{_ 'yes'}}
|
||||
option(value="true" selected="{{org.loginDisabled}}") {{_ 'no'}}
|
||||
option(value="true" selected="{{org.orgIsActive}}") {{_ 'no'}}
|
||||
hr
|
||||
div.buttonsContainer
|
||||
input.primary.wide(type="submit" value="{{_ 'save'}}")
|
||||
|
|
@ -311,7 +321,7 @@ template(name="editTeamPopup")
|
|||
| {{_ 'active'}}
|
||||
select.select-active.js-team-isactive
|
||||
option(value="false") {{_ 'yes'}}
|
||||
option(value="true" selected="{{team.loginDisabled}}") {{_ 'no'}}
|
||||
option(value="true" selected="{{team.teamIsActive}}") {{_ 'no'}}
|
||||
hr
|
||||
div.buttonsContainer
|
||||
input.primary.wide(type="submit" value="{{_ 'save'}}")
|
||||
|
|
@ -367,6 +377,27 @@ template(name="editUserPopup")
|
|||
option(value="{{value}}" selected) {{_ value}}
|
||||
else
|
||||
option(value="{{value}}") {{_ value}}
|
||||
label
|
||||
| {{_ 'organizations'}}
|
||||
i.fa.fa-plus-square#addUserOrg
|
||||
i.fa.fa-minus-square#removeUserOrg
|
||||
select.js-orgs#jsOrgs
|
||||
option(value="-1") {{_ 'organizations'}} :
|
||||
each value in orgsDatas
|
||||
option(value="{{value._id}}") {{_ value.orgDisplayName}}
|
||||
input#jsUserOrgsInPut.js-userOrgs(type="text" value=user.orgsUserBelongs, disabled)
|
||||
input#jsUserOrgIdsInPut.js-userOrgIds.hide(type="text" value=user.orgIdsUserBelongs)
|
||||
label
|
||||
| {{_ 'teams'}}
|
||||
i.fa.fa-plus-square#addUserTeam
|
||||
i.fa.fa-minus-square#removeUserTeam
|
||||
select.js-teams#jsTeams
|
||||
option(value="-1") {{_ 'teams'}} :
|
||||
each value in teamsDatas
|
||||
option(value="{{value._id}}") {{_ value.teamDisplayName}}
|
||||
input#jsUserTeamsInPut.js-userteams(type="text" value=user.teamsUserBelongs, disabled)
|
||||
input#jsUserTeamIdsInPut.js-userteamIds.hide(type="text" value=user.teamIdsUserBelongs)
|
||||
|
||||
hr
|
||||
label
|
||||
| {{_ 'password'}}
|
||||
|
|
@ -385,7 +416,7 @@ template(name="newOrgPopup")
|
|||
input.js-orgDesc(type="text" value="" required)
|
||||
label
|
||||
| {{_ 'shortName'}}
|
||||
input.js-orgName(type="text" value="" required)
|
||||
input.js-orgShortName(type="text" value="" required)
|
||||
label
|
||||
| {{_ 'website'}}
|
||||
input.js-orgWebsite(type="text" value="" required)
|
||||
|
|
@ -409,7 +440,7 @@ template(name="newTeamPopup")
|
|||
input.js-teamDesc(type="text" value="" required)
|
||||
label
|
||||
| {{_ 'shortName'}}
|
||||
input.js-teamName(type="text" value="" required)
|
||||
input.js-teamShortName(type="text" value="" required)
|
||||
label
|
||||
| {{_ 'website'}}
|
||||
input.js-teamWebsite(type="text" value="" required)
|
||||
|
|
@ -468,6 +499,27 @@ template(name="newUserPopup")
|
|||
option(value="{{value}}" selected) {{_ value}}
|
||||
else
|
||||
option(value="{{value}}") {{_ value}}
|
||||
label
|
||||
| {{_ 'organizations'}}
|
||||
i.fa.fa-plus-square#addUserOrgNewUser
|
||||
i.fa.fa-minus-square#removeUserOrgNewUser
|
||||
select.js-orgsNewUser#jsOrgsNewUser
|
||||
option(value="-1") {{_ 'organizations'}} :
|
||||
each value in orgsDatas
|
||||
option(value="{{value._id}}") {{_ value.orgDisplayName}}
|
||||
input#jsUserOrgsInPutNewUser.js-userOrgsNewUser(type="text" value=user.orgsUserBelongs, disabled)
|
||||
input#jsUserOrgIdsInPutNewUser.js-userOrgIdsNewUser.hide(type="text" value=user.orgIdsUserBelongs)
|
||||
label
|
||||
| {{_ 'teams'}}
|
||||
i.fa.fa-plus-square#addUserTeamNewUser
|
||||
i.fa.fa-minus-square#removeUserTeamNewUser
|
||||
select.js-teamsNewUser#jsTeamsNewUser
|
||||
option(value="-1") {{_ 'teams'}} :
|
||||
each value in teamsDatas
|
||||
option(value="{{value._id}}") {{_ value.teamDisplayName}}
|
||||
input#jsUserTeamsInPutNewUser.js-userteamsNewUser(type="text" value=user.teamsUserBelongs, disabled)
|
||||
input#jsUserTeamIdsInPutNewUser.js-userteamIdsNewUser.hide(type="text" value=user.teamIdsUserBelongs)
|
||||
|
||||
hr
|
||||
label
|
||||
| {{_ 'password'}}
|
||||
|
|
@ -478,27 +530,40 @@ template(name="newUserPopup")
|
|||
template(name="settingsOrgPopup")
|
||||
ul.pop-over-list
|
||||
li
|
||||
a.impersonate-org
|
||||
i.fa.fa-user
|
||||
| {{_ 'impersonate-org'}}
|
||||
// Delete is not enabled yet, because it does leave empty user avatars
|
||||
// to boards: boards members, card members and assignees have
|
||||
// empty users. See:
|
||||
// - wekan/client/components/settings/peopleBody.jade deleteButton
|
||||
// - wekan/client/components/settings/peopleBody.js deleteButton
|
||||
// - wekan/client/components/sidebar/sidebar.js Popup.afterConfirm('removeMember'
|
||||
// that does now remove member from board, card members and assignees correctly,
|
||||
// but that should be used to remove user from all boards similarly
|
||||
// - wekan/models/users.js Delete is not enabled
|
||||
//li
|
||||
// br
|
||||
// br
|
||||
// hr
|
||||
//li
|
||||
// form
|
||||
// label.hide.userId(type="text" value=user._id)
|
||||
// div.buttonsContainer
|
||||
// input#deleteButton.card-details-red.right.wide(type="button" value="{{_ 'delete'}}")
|
||||
form
|
||||
label#deleteOrgWarningMessage.hide
|
||||
| {{_ 'delete-org-warning-message'}}
|
||||
br
|
||||
label
|
||||
| {{_ 'delete-org-confirm-popup'}}
|
||||
br
|
||||
label.hide.orgId(type="text" value=org._id)
|
||||
labeldelete-org-confirm-popup
|
||||
div.buttonsContainer
|
||||
input#deleteButton.card-details-red.right.wide(type="button" value="{{_ 'delete'}}")
|
||||
// It's not yet possible to impersonate organization. Only impersonate user,
|
||||
// because that changes current user ID. What would it mean in practice
|
||||
// to impersonate organization?
|
||||
// li
|
||||
// a.impersonate-org
|
||||
// i.fa.fa-user
|
||||
// | {{_ 'impersonate-org'}}
|
||||
//
|
||||
//
|
||||
|
||||
template(name="settingsTeamPopup")
|
||||
ul.pop-over-list
|
||||
li
|
||||
form
|
||||
label#deleteTeamWarningMessage.hide
|
||||
| {{_ 'delete-team-warning-message'}}
|
||||
br
|
||||
label
|
||||
| {{_ 'delete-team-confirm-popup'}}
|
||||
br
|
||||
label.hide.teamId(type="text" value=team._id)
|
||||
div.buttonsContainer
|
||||
input#deleteButton.card-details-red.right.wide(type="button" value="{{_ 'delete'}}")
|
||||
|
||||
template(name="settingsUserPopup")
|
||||
ul.pop-over-list
|
||||
|
|
@ -506,21 +571,19 @@ template(name="settingsUserPopup")
|
|||
a.impersonate-user
|
||||
i.fa.fa-user
|
||||
| {{_ 'impersonate-user'}}
|
||||
// Delete is not enabled yet, because it does leave empty user avatars
|
||||
hr
|
||||
li
|
||||
form
|
||||
label.hide.userId(type="text" value=user._id)
|
||||
div.buttonsContainer
|
||||
input#deleteButton.card-details-red.right.wide(type="button" value="{{_ 'delete'}}")
|
||||
// Delete is enabled, but there is still bug of leaving empty user avatars
|
||||
// to boards: boards members, card members and assignees have
|
||||
// empty users. See:
|
||||
// empty users. So it is better to remove user from all boards before removing user.
|
||||
// See:
|
||||
// - wekan/client/components/settings/peopleBody.jade deleteButton
|
||||
// - wekan/client/components/settings/peopleBody.js deleteButton
|
||||
// - wekan/client/components/sidebar/sidebar.js Popup.afterConfirm('removeMember'
|
||||
// that does now remove member from board, card members and assignees correctly,
|
||||
// but that should be used to remove user from all boards similarly
|
||||
// - wekan/models/users.js Delete is not enabled
|
||||
//li
|
||||
// br
|
||||
// br
|
||||
// hr
|
||||
//li
|
||||
// form
|
||||
// label.hide.userId(type="text" value=user._id)
|
||||
// div.buttonsContainer
|
||||
// input#deleteButton.card-details-red.right.wide(type="button" value="{{_ 'delete'}}")
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
const orgsPerPage = 25;
|
||||
const teamsPerPage = 25;
|
||||
const usersPerPage = 25;
|
||||
let userOrgsTeamsAction = ""; //poosible actions 'addOrg', 'addTeam', 'removeOrg' or 'removeTeam' when adding or modifying a user
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
mixins() {
|
||||
|
|
@ -101,9 +102,7 @@ BlazeComponent.extendComponent({
|
|||
];
|
||||
},
|
||||
filterPeople() {
|
||||
const value = $('#searchInput')
|
||||
.first()
|
||||
.val();
|
||||
const value = $('#searchInput').first().val();
|
||||
if (value === '') {
|
||||
this.findUsersOptions.set({});
|
||||
} else {
|
||||
|
|
@ -150,7 +149,7 @@ BlazeComponent.extendComponent({
|
|||
const teams = Team.find(this.findTeamsOptions.get(), {
|
||||
fields: { _id: true },
|
||||
});
|
||||
this.numberTeams.set(team.count(false));
|
||||
this.numberTeams.set(teams.count(false));
|
||||
return teams;
|
||||
},
|
||||
peopleList() {
|
||||
|
|
@ -203,7 +202,7 @@ Template.peopleRow.helpers({
|
|||
},
|
||||
});
|
||||
|
||||
Template.editUserPopup.onCreated(function() {
|
||||
Template.editUserPopup.onCreated(function () {
|
||||
this.authenticationMethods = new ReactiveVar([]);
|
||||
this.errorMessage = new ReactiveVar('');
|
||||
|
||||
|
|
@ -215,8 +214,8 @@ Template.editUserPopup.onCreated(function() {
|
|||
{ value: 'password' },
|
||||
// Gets only the authentication methods availables
|
||||
...Object.entries(result)
|
||||
.filter(e => e[1])
|
||||
.map(e => ({ value: e[0] })),
|
||||
.filter((e) => e[1])
|
||||
.map((e) => ({ value: e[0] })),
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
|
@ -247,6 +246,12 @@ Template.editUserPopup.helpers({
|
|||
authentications() {
|
||||
return Template.instance().authenticationMethods.get();
|
||||
},
|
||||
orgsDatas() {
|
||||
return Org.find({}, {sort: { createdAt: -1 }});
|
||||
},
|
||||
teamsDatas() {
|
||||
return Team.find({}, {sort: { createdAt: -1 }});
|
||||
},
|
||||
isSelected(match) {
|
||||
const userId = Template.instance().data.userId;
|
||||
const selected = Users.findOne(userId).authenticationMethod;
|
||||
|
|
@ -262,15 +267,15 @@ Template.editUserPopup.helpers({
|
|||
},
|
||||
});
|
||||
|
||||
Template.newOrgPopup.onCreated(function() {
|
||||
Template.newOrgPopup.onCreated(function () {
|
||||
this.errorMessage = new ReactiveVar('');
|
||||
});
|
||||
|
||||
Template.newTeamPopup.onCreated(function() {
|
||||
Template.newTeamPopup.onCreated(function () {
|
||||
this.errorMessage = new ReactiveVar('');
|
||||
});
|
||||
|
||||
Template.newUserPopup.onCreated(function() {
|
||||
Template.newUserPopup.onCreated(function () {
|
||||
this.authenticationMethods = new ReactiveVar([]);
|
||||
this.errorMessage = new ReactiveVar('');
|
||||
|
||||
|
|
@ -282,8 +287,8 @@ Template.newUserPopup.onCreated(function() {
|
|||
{ value: 'password' },
|
||||
// Gets only the authentication methods availables
|
||||
...Object.entries(result)
|
||||
.filter(e => e[1])
|
||||
.map(e => ({ value: e[0] })),
|
||||
.filter((e) => e[1])
|
||||
.map((e) => ({ value: e[0] })),
|
||||
]);
|
||||
}
|
||||
});
|
||||
|
|
@ -314,10 +319,21 @@ Template.newUserPopup.helpers({
|
|||
authentications() {
|
||||
return Template.instance().authenticationMethods.get();
|
||||
},
|
||||
orgsDatas() {
|
||||
return Org.find({}, {sort: { createdAt: -1 }});
|
||||
},
|
||||
teamsDatas() {
|
||||
return Team.find({}, {sort: { createdAt: -1 }});
|
||||
},
|
||||
isSelected(match) {
|
||||
const userId = Template.instance().data.userId;
|
||||
const selected = Users.findOne(userId).authenticationMethod;
|
||||
return selected === match;
|
||||
if(userId){
|
||||
const selected = Users.findOne(userId).authenticationMethod;
|
||||
return selected === match;
|
||||
}
|
||||
else{
|
||||
false;
|
||||
}
|
||||
},
|
||||
isLdap() {
|
||||
const userId = Template.instance().data.userId;
|
||||
|
|
@ -407,7 +423,7 @@ BlazeComponent.extendComponent({
|
|||
Template.editOrgPopup.events({
|
||||
submit(event, templateInstance) {
|
||||
event.preventDefault();
|
||||
const org = Orgs.findOne(this.orgId);
|
||||
const org = Org.findOne(this.orgId);
|
||||
|
||||
const orgDisplayName = templateInstance
|
||||
.find('.js-orgDisplayName')
|
||||
|
|
@ -415,7 +431,8 @@ Template.editOrgPopup.events({
|
|||
const orgDesc = templateInstance.find('.js-orgDesc').value.trim();
|
||||
const orgShortName = templateInstance.find('.js-orgShortName').value.trim();
|
||||
const orgWebsite = templateInstance.find('.js-orgWebsite').value.trim();
|
||||
const orgIsActive = templateInstance.find('.js-org-isactive').value.trim();
|
||||
const orgIsActive =
|
||||
templateInstance.find('.js-org-isactive').value.trim() == 'true';
|
||||
|
||||
const isChangeOrgDisplayName = orgDisplayName !== org.orgDisplayName;
|
||||
const isChangeOrgDesc = orgDesc !== org.orgDesc;
|
||||
|
|
@ -423,20 +440,22 @@ Template.editOrgPopup.events({
|
|||
const isChangeOrgWebsite = orgWebsite !== org.orgWebsite;
|
||||
const isChangeOrgIsActive = orgIsActive !== org.orgIsActive;
|
||||
|
||||
if (isChangeOrgDisplayName) {
|
||||
Meteor.call('setOrgDisplayName', org, orgDisplayName);
|
||||
}
|
||||
|
||||
if (isChangeOrgDesc) {
|
||||
Meteor.call('setOrgDesc', org, orgDesc);
|
||||
}
|
||||
|
||||
if (isChangeOrgShortName) {
|
||||
Meteor.call('setOrgShortName', org, orgShortName);
|
||||
}
|
||||
|
||||
if (isChangeOrgIsActive) {
|
||||
Meteor.call('setOrgIsActive', org, orgIsActive);
|
||||
if (
|
||||
isChangeOrgDisplayName ||
|
||||
isChangeOrgDesc ||
|
||||
isChangeOrgShortName ||
|
||||
isChangeOrgWebsite ||
|
||||
isChangeOrgIsActive
|
||||
) {
|
||||
Meteor.call(
|
||||
'setOrgAllFields',
|
||||
org,
|
||||
orgDisplayName,
|
||||
orgDesc,
|
||||
orgShortName,
|
||||
orgWebsite,
|
||||
orgIsActive,
|
||||
);
|
||||
}
|
||||
|
||||
Popup.close();
|
||||
|
|
@ -446,7 +465,7 @@ Template.editOrgPopup.events({
|
|||
Template.editTeamPopup.events({
|
||||
submit(event, templateInstance) {
|
||||
event.preventDefault();
|
||||
const team = Teams.findOne(this.teamId);
|
||||
const team = Team.findOne(this.teamId);
|
||||
|
||||
const teamDisplayName = templateInstance
|
||||
.find('.js-teamDisplayName')
|
||||
|
|
@ -456,9 +475,8 @@ Template.editTeamPopup.events({
|
|||
.find('.js-teamShortName')
|
||||
.value.trim();
|
||||
const teamWebsite = templateInstance.find('.js-teamWebsite').value.trim();
|
||||
const teamIsActive = templateInstance
|
||||
.find('.js-team-isactive')
|
||||
.value.trim();
|
||||
const teamIsActive =
|
||||
templateInstance.find('.js-team-isactive').value.trim() == 'true';
|
||||
|
||||
const isChangeTeamDisplayName = teamDisplayName !== team.teamDisplayName;
|
||||
const isChangeTeamDesc = teamDesc !== team.teamDesc;
|
||||
|
|
@ -466,20 +484,22 @@ Template.editTeamPopup.events({
|
|||
const isChangeTeamWebsite = teamWebsite !== team.teamWebsite;
|
||||
const isChangeTeamIsActive = teamIsActive !== team.teamIsActive;
|
||||
|
||||
if (isChangeTeamDisplayName) {
|
||||
Meteor.call('setTeamDisplayName', team, teamDisplayName);
|
||||
}
|
||||
|
||||
if (isChangeTeamDesc) {
|
||||
Meteor.call('setTeamDesc', team, teamDesc);
|
||||
}
|
||||
|
||||
if (isChangeTeamShortName) {
|
||||
Meteor.call('setTeamShortName', team, teamShortName);
|
||||
}
|
||||
|
||||
if (isChangeTeamIsActive) {
|
||||
Meteor.call('setTeamIsActive', team, teamIsActive);
|
||||
if (
|
||||
isChangeTeamDisplayName ||
|
||||
isChangeTeamDesc ||
|
||||
isChangeTeamShortName ||
|
||||
isChangeTeamWebsite ||
|
||||
isChangeTeamIsActive
|
||||
) {
|
||||
Meteor.call(
|
||||
'setTeamAllFields',
|
||||
team,
|
||||
teamDisplayName,
|
||||
teamDesc,
|
||||
teamShortName,
|
||||
teamWebsite,
|
||||
teamIsActive,
|
||||
);
|
||||
}
|
||||
|
||||
Popup.close();
|
||||
|
|
@ -497,15 +517,13 @@ Template.editUserPopup.events({
|
|||
const isAdmin = templateInstance.find('.js-profile-isadmin').value.trim();
|
||||
const isActive = templateInstance.find('.js-profile-isactive').value.trim();
|
||||
const email = templateInstance.find('.js-profile-email').value.trim();
|
||||
const verified = templateInstance
|
||||
.find('.js-profile-email-verified')
|
||||
.value.trim();
|
||||
const authentication = templateInstance
|
||||
.find('.js-authenticationMethod')
|
||||
.value.trim();
|
||||
const importUsernames = templateInstance
|
||||
.find('.js-import-usernames')
|
||||
.value.trim();
|
||||
const verified = templateInstance.find('.js-profile-email-verified').value.trim();
|
||||
const authentication = templateInstance.find('.js-authenticationMethod').value.trim();
|
||||
const importUsernames = templateInstance.find('.js-import-usernames').value.trim();
|
||||
const userOrgs = templateInstance.find('.js-userOrgs').value.trim();
|
||||
const userOrgsIds = templateInstance.find('.js-userOrgIds').value.trim();
|
||||
const userTeams = templateInstance.find('.js-userteams').value.trim();
|
||||
const userTeamsIds = templateInstance.find('.js-userteamIds').value.trim();
|
||||
|
||||
const isChangePassword = password.length > 0;
|
||||
const isChangeUserName = username !== user.username;
|
||||
|
|
@ -530,6 +548,42 @@ Template.editUserPopup.events({
|
|||
},
|
||||
});
|
||||
|
||||
let userTeamsList = userTeams.split(",");
|
||||
let userTeamsIdsList = userTeamsIds.split(",");
|
||||
let userTms = [];
|
||||
if(userTeams != ''){
|
||||
for(let i = 0; i < userTeamsList.length; i++){
|
||||
userTms.push({
|
||||
"teamId": userTeamsIdsList[i],
|
||||
"teamDisplayName": userTeamsList[i],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Users.update(this.userId, {
|
||||
$set:{
|
||||
teams: userTms
|
||||
}
|
||||
});
|
||||
|
||||
let userOrgsList = userOrgs.split(",");
|
||||
let userOrgsIdsList = userOrgsIds.split(",");
|
||||
let userOrganizations = [];
|
||||
if(userOrgs != ''){
|
||||
for(let i = 0; i < userOrgsList.length; i++){
|
||||
userOrganizations.push({
|
||||
"orgId": userOrgsIdsList[i],
|
||||
"orgDisplayName": userOrgsList[i],
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Users.update(this.userId, {
|
||||
$set:{
|
||||
orgs: userOrganizations
|
||||
}
|
||||
});
|
||||
|
||||
if (isChangePassword) {
|
||||
Meteor.call('setPassword', password, this.userId);
|
||||
}
|
||||
|
|
@ -548,7 +602,7 @@ Template.editUserPopup.events({
|
|||
username,
|
||||
email.toLowerCase(),
|
||||
this.userId,
|
||||
function(error) {
|
||||
function (error) {
|
||||
const usernameMessageElement = templateInstance.$('.username-taken');
|
||||
const emailMessageElement = templateInstance.$('.email-taken');
|
||||
if (error) {
|
||||
|
|
@ -568,7 +622,7 @@ Template.editUserPopup.events({
|
|||
},
|
||||
);
|
||||
} else if (isChangeUserName) {
|
||||
Meteor.call('setUsername', username, this.userId, function(error) {
|
||||
Meteor.call('setUsername', username, this.userId, function (error) {
|
||||
const usernameMessageElement = templateInstance.$('.username-taken');
|
||||
if (error) {
|
||||
const errorElement = error.error;
|
||||
|
|
@ -581,24 +635,138 @@ Template.editUserPopup.events({
|
|||
}
|
||||
});
|
||||
} else if (isChangeEmail) {
|
||||
Meteor.call('setEmail', email.toLowerCase(), this.userId, function(
|
||||
error,
|
||||
) {
|
||||
const emailMessageElement = templateInstance.$('.email-taken');
|
||||
if (error) {
|
||||
const errorElement = error.error;
|
||||
if (errorElement === 'email-already-taken') {
|
||||
emailMessageElement.show();
|
||||
Meteor.call(
|
||||
'setEmail',
|
||||
email.toLowerCase(),
|
||||
this.userId,
|
||||
function (error) {
|
||||
const emailMessageElement = templateInstance.$('.email-taken');
|
||||
if (error) {
|
||||
const errorElement = error.error;
|
||||
if (errorElement === 'email-already-taken') {
|
||||
emailMessageElement.show();
|
||||
}
|
||||
} else {
|
||||
emailMessageElement.hide();
|
||||
Popup.close();
|
||||
}
|
||||
} else {
|
||||
emailMessageElement.hide();
|
||||
Popup.close();
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
} else Popup.close();
|
||||
},
|
||||
'click #addUserOrg'(event) {
|
||||
event.preventDefault();
|
||||
|
||||
userOrgsTeamsAction = "addOrg";
|
||||
document.getElementById("jsOrgs").style.display = 'block';
|
||||
document.getElementById("jsTeams").style.display = 'none';
|
||||
},
|
||||
'click #removeUserOrg'(event) {
|
||||
event.preventDefault();
|
||||
|
||||
userOrgsTeamsAction = "removeOrg";
|
||||
document.getElementById("jsOrgs").style.display = 'block';
|
||||
document.getElementById("jsTeams").style.display = 'none';
|
||||
},
|
||||
'click #addUserTeam'(event) {
|
||||
event.preventDefault();
|
||||
|
||||
userOrgsTeamsAction = "addTeam";
|
||||
document.getElementById("jsTeams").style.display = 'block';
|
||||
document.getElementById("jsOrgs").style.display = 'none';
|
||||
},
|
||||
'click #removeUserTeam'(event) {
|
||||
event.preventDefault();
|
||||
|
||||
userOrgsTeamsAction = "removeTeam";
|
||||
document.getElementById("jsTeams").style.display = 'block';
|
||||
document.getElementById("jsOrgs").style.display = 'none';
|
||||
},
|
||||
'change #jsOrgs'(event) {
|
||||
event.preventDefault();
|
||||
UpdateUserOrgsOrTeamsElement();
|
||||
},
|
||||
'change #jsTeams'(event) {
|
||||
event.preventDefault();
|
||||
UpdateUserOrgsOrTeamsElement();
|
||||
},
|
||||
});
|
||||
|
||||
UpdateUserOrgsOrTeamsElement = function(isNewUser = false){
|
||||
let selectedElt;
|
||||
let selectedEltValue;
|
||||
let selectedEltValueId;
|
||||
let inputElt;
|
||||
let inputEltId;
|
||||
let lstInputValues = [];
|
||||
let lstInputValuesIds = [];
|
||||
let index;
|
||||
let indexId;
|
||||
switch(userOrgsTeamsAction)
|
||||
{
|
||||
case "addOrg":
|
||||
case "removeOrg":
|
||||
inputElt = !isNewUser ? document.getElementById("jsUserOrgsInPut") : document.getElementById("jsUserOrgsInPutNewUser");
|
||||
inputEltId = !isNewUser ? document.getElementById("jsUserOrgIdsInPut") : document.getElementById("jsUserOrgIdsInPutNewUser");
|
||||
selectedElt = !isNewUser ? document.getElementById("jsOrgs") : document.getElementById("jsOrgsNewUser");
|
||||
break;
|
||||
case "addTeam":
|
||||
case "removeTeam":
|
||||
inputElt = !isNewUser ? document.getElementById("jsUserTeamsInPut") : document.getElementById("jsUserTeamsInPutNewUser");
|
||||
inputEltId = !isNewUser ? document.getElementById("jsUserTeamIdsInPut") : document.getElementById("jsUserTeamIdsInPutNewUser");
|
||||
selectedElt = !isNewUser ? document.getElementById("jsTeams") : document.getElementById("jsTeamsNewUser");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
selectedEltValue = selectedElt.options[selectedElt.selectedIndex].text;
|
||||
selectedEltValueId = selectedElt.options[selectedElt.selectedIndex].value;
|
||||
lstInputValues = inputElt.value.trim().split(",");
|
||||
if(lstInputValues.length == 1 && lstInputValues[0] == ''){
|
||||
lstInputValues = [];
|
||||
}
|
||||
lstInputValuesIds = inputEltId.value.trim().split(",");
|
||||
if(lstInputValuesIds.length == 1 && lstInputValuesIds[0] == ''){
|
||||
lstInputValuesIds = [];
|
||||
}
|
||||
index = lstInputValues.indexOf(selectedEltValue);
|
||||
indexId = lstInputValuesIds.indexOf(selectedEltValueId);
|
||||
if(userOrgsTeamsAction == "addOrg" || userOrgsTeamsAction == "addTeam"){
|
||||
if(index <= -1 && selectedEltValueId != "-1"){
|
||||
lstInputValues.push(selectedEltValue);
|
||||
}
|
||||
|
||||
if(indexId <= -1 && selectedEltValueId != "-1"){
|
||||
lstInputValuesIds.push(selectedEltValueId);
|
||||
}
|
||||
}
|
||||
else{
|
||||
if(index > -1 && selectedEltValueId != "-1"){
|
||||
lstInputValues.splice(index, 1);
|
||||
}
|
||||
|
||||
if(indexId > -1 && selectedEltValueId != "-1"){
|
||||
lstInputValuesIds.splice(indexId, 1);
|
||||
}
|
||||
}
|
||||
|
||||
if(lstInputValues.length > 0){
|
||||
inputElt.value = lstInputValues.join(",");
|
||||
}
|
||||
else{
|
||||
inputElt.value = "";
|
||||
}
|
||||
|
||||
if(lstInputValuesIds.length > 0){
|
||||
inputEltId.value = lstInputValuesIds.join(",");
|
||||
}
|
||||
else{
|
||||
inputEltId.value = "";
|
||||
}
|
||||
selectedElt.value = "-1";
|
||||
selectedElt.style.display = "none";
|
||||
}
|
||||
|
||||
Template.newOrgPopup.events({
|
||||
submit(event, templateInstance) {
|
||||
event.preventDefault();
|
||||
|
|
@ -608,7 +776,8 @@ Template.newOrgPopup.events({
|
|||
const orgDesc = templateInstance.find('.js-orgDesc').value.trim();
|
||||
const orgShortName = templateInstance.find('.js-orgShortName').value.trim();
|
||||
const orgWebsite = templateInstance.find('.js-orgWebsite').value.trim();
|
||||
const orgIsActive = templateInstance.find('.js-org-isactive').value.trim();
|
||||
const orgIsActive =
|
||||
templateInstance.find('.js-org-isactive').value.trim() == 'true';
|
||||
|
||||
Meteor.call(
|
||||
'setCreateOrg',
|
||||
|
|
@ -633,9 +802,8 @@ Template.newTeamPopup.events({
|
|||
.find('.js-teamShortName')
|
||||
.value.trim();
|
||||
const teamWebsite = templateInstance.find('.js-teamWebsite').value.trim();
|
||||
const teamIsActive = templateInstance
|
||||
.find('.js-team-isactive')
|
||||
.value.trim();
|
||||
const teamIsActive =
|
||||
templateInstance.find('.js-team-isactive').value.trim() == 'true';
|
||||
|
||||
Meteor.call(
|
||||
'setCreateTeam',
|
||||
|
|
@ -662,6 +830,30 @@ Template.newUserPopup.events({
|
|||
const importUsernames = Users.parseImportUsernames(
|
||||
templateInstance.find('.js-import-usernames').value,
|
||||
);
|
||||
const userOrgs = templateInstance.find('.js-userOrgsNewUser').value.trim();
|
||||
const userOrgsIds = templateInstance.find('.js-userOrgIdsNewUser').value.trim();
|
||||
const userTeams = templateInstance.find('.js-userteamsNewUser').value.trim();
|
||||
const userTeamsIds = templateInstance.find('.js-userteamIdsNewUser').value.trim();
|
||||
|
||||
let userTeamsList = userTeams.split(",");
|
||||
let userTeamsIdsList = userTeamsIds.split(",");
|
||||
let userTms = [];
|
||||
for(let i = 0; i < userTeamsList.length; i++){
|
||||
userTms.push({
|
||||
"teamId": userTeamsIdsList[i],
|
||||
"teamDisplayName": userTeamsList[i],
|
||||
})
|
||||
}
|
||||
|
||||
let userOrgsList = userOrgs.split(",");
|
||||
let userOrgsIdsList = userOrgsIds.split(",");
|
||||
let userOrganizations = [];
|
||||
for(let i = 0; i < userOrgsList.length; i++){
|
||||
userOrganizations.push({
|
||||
"orgId": userOrgsIdsList[i],
|
||||
"orgDisplayName": userOrgsList[i],
|
||||
})
|
||||
}
|
||||
|
||||
Meteor.call(
|
||||
'setCreateUser',
|
||||
|
|
@ -673,6 +865,8 @@ Template.newUserPopup.events({
|
|||
isActive,
|
||||
email.toLowerCase(),
|
||||
importUsernames,
|
||||
userOrganizations,
|
||||
userTms,
|
||||
function(error) {
|
||||
const usernameMessageElement = templateInstance.$('.username-taken');
|
||||
const emailMessageElement = templateInstance.$('.email-taken');
|
||||
|
|
@ -694,13 +888,85 @@ Template.newUserPopup.events({
|
|||
);
|
||||
Popup.close();
|
||||
},
|
||||
'click #addUserOrgNewUser'(event) {
|
||||
event.preventDefault();
|
||||
|
||||
userOrgsTeamsAction = "addOrg";
|
||||
document.getElementById("jsOrgsNewUser").style.display = 'block';
|
||||
document.getElementById("jsTeamsNewUser").style.display = 'none';
|
||||
},
|
||||
'click #removeUserOrgNewUser'(event) {
|
||||
event.preventDefault();
|
||||
|
||||
userOrgsTeamsAction = "removeOrg";
|
||||
document.getElementById("jsOrgsNewUser").style.display = 'block';
|
||||
document.getElementById("jsTeamsNewUser").style.display = 'none';
|
||||
},
|
||||
'click #addUserTeamNewUser'(event) {
|
||||
event.preventDefault();
|
||||
|
||||
userOrgsTeamsAction = "addTeam";
|
||||
document.getElementById("jsTeamsNewUser").style.display = 'block';
|
||||
document.getElementById("jsOrgsNewUser").style.display = 'none';
|
||||
},
|
||||
'click #removeUserTeamNewUser'(event) {
|
||||
event.preventDefault();
|
||||
|
||||
userOrgsTeamsAction = "removeTeam";
|
||||
document.getElementById("jsTeamsNewUser").style.display = 'block';
|
||||
document.getElementById("jsOrgsNewUser").style.display = 'none';
|
||||
},
|
||||
'change #jsOrgsNewUser'(event) {
|
||||
event.preventDefault();
|
||||
UpdateUserOrgsOrTeamsElement(true);
|
||||
},
|
||||
'change #jsTeamsNewUser'(event) {
|
||||
event.preventDefault();
|
||||
UpdateUserOrgsOrTeamsElement(true);
|
||||
},
|
||||
});
|
||||
|
||||
Template.settingsOrgPopup.events({
|
||||
'click #deleteButton'(event) {
|
||||
event.preventDefault();
|
||||
if(Users.find({"orgs.orgId": this.orgId}).count() > 0)
|
||||
{
|
||||
let orgClassList = document.getElementById("deleteOrgWarningMessage").classList;
|
||||
if(orgClassList.contains('hide'))
|
||||
{
|
||||
orgClassList.remove('hide');
|
||||
document.getElementById("deleteOrgWarningMessage").style.color = "red";
|
||||
}
|
||||
return;
|
||||
}
|
||||
Org.remove(this.orgId);
|
||||
Popup.close();
|
||||
}
|
||||
});
|
||||
|
||||
Template.settingsTeamPopup.events({
|
||||
'click #deleteButton'(event) {
|
||||
event.preventDefault();
|
||||
if(Users.find({"teams.teamId": this.teamId}).count() > 0)
|
||||
{
|
||||
let teamClassList = document.getElementById("deleteTeamWarningMessage").classList;
|
||||
if(teamClassList.contains('hide'))
|
||||
{
|
||||
teamClassList.remove('hide');
|
||||
document.getElementById("deleteTeamWarningMessage").style.color = "red";
|
||||
}
|
||||
return;
|
||||
}
|
||||
Team.remove(this.teamId);
|
||||
Popup.close();
|
||||
}
|
||||
});
|
||||
|
||||
Template.settingsUserPopup.events({
|
||||
'click .impersonate-user'(event) {
|
||||
event.preventDefault();
|
||||
|
||||
Meteor.call('impersonate', this.userId, err => {
|
||||
Meteor.call('impersonate', this.userId, (err) => {
|
||||
if (!err) {
|
||||
FlowRouter.go('/');
|
||||
Meteor.connection.setUserId(this.userId);
|
||||
|
|
@ -720,21 +986,6 @@ Template.settingsUserPopup.events({
|
|||
// but that should be used to remove user from all boards similarly
|
||||
// - wekan/models/users.js Delete is not enabled
|
||||
//
|
||||
//console.log('user id: ' + this.userId);
|
||||
//Popup.afterConfirm('userDelete', function(event) {
|
||||
//Boards.find({ members: this.userId }).forEach(board => {
|
||||
// console.log('board id: ' + board._id);
|
||||
//Cards.find({ boardId: board._id, members: this.userId }).forEach(card => {
|
||||
// card.unassignMember(this.userId);
|
||||
//});
|
||||
//Cards.find({ boardId: board._id, members: this.userId }).forEach(card => {
|
||||
// card.unassignMember(this.userId);
|
||||
//});
|
||||
//Cards.find({ boardId: board._id, assignees: this.userId }).forEach(card => {
|
||||
// card.unassignAssignee(this.userId);
|
||||
//});
|
||||
//Boards.findOne({ boardId: board._id }).removeMember(this.userId);
|
||||
//});
|
||||
//Users.remove(this.userId);
|
||||
*/
|
||||
Popup.close();
|
||||
|
|
|
|||
|
|
@ -49,3 +49,9 @@ table
|
|||
|
||||
.more-settings-user,.more-settings-team,.more-settings-org
|
||||
margin-left: 10px;
|
||||
|
||||
.js-orgs,.js-orgsNewUser
|
||||
display: none;
|
||||
|
||||
.js-teams,.js-teamsNewUser
|
||||
display: none;
|
||||
|
|
|
|||
|
|
@ -173,6 +173,9 @@ template(name='layoutSettings')
|
|||
li.layout-form
|
||||
.title {{_ 'default-authentication-method'}}
|
||||
+selectAuthenticationMethod(authenticationMethod=currentSetting.defaultAuthenticationMethod)
|
||||
li.layout-form
|
||||
.title {{_ 'wait-spinner'}}
|
||||
+selectSpinnerName(spinnerName=currentSetting.spinnerName)
|
||||
li.layout-form
|
||||
.title {{_ 'custom-product-name'}}
|
||||
.form-group
|
||||
|
|
@ -222,3 +225,11 @@ template(name='selectAuthenticationMethod')
|
|||
option(value="{{value}}" selected) {{_ value}}
|
||||
else
|
||||
option(value="{{value}}") {{_ value}}
|
||||
|
||||
template(name='selectSpinnerName')
|
||||
select#spinnerName
|
||||
each spinner in spinners
|
||||
if isSelected spinner
|
||||
option(value="{{spinner}}" selected) {{_ spinner}}
|
||||
else
|
||||
option(value="{{spinner}}") {{_ spinner}}
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
import { ALLOWED_WAIT_SPINNERS } from '/config/const';
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
onCreated() {
|
||||
this.error = new ReactiveVar('');
|
||||
|
|
@ -199,6 +201,8 @@ BlazeComponent.extendComponent({
|
|||
$('input[name=displayAuthenticationMethod]:checked').val() === 'true';
|
||||
const defaultAuthenticationMethod = $('#defaultAuthenticationMethod').val();
|
||||
|
||||
const spinnerName = $('#spinnerName').val();
|
||||
|
||||
try {
|
||||
Settings.update(Settings.findOne()._id, {
|
||||
$set: {
|
||||
|
|
@ -213,6 +217,7 @@ BlazeComponent.extendComponent({
|
|||
displayAuthenticationMethod,
|
||||
defaultAuthenticationMethod,
|
||||
automaticLinkedUrlSchemes,
|
||||
spinnerName,
|
||||
},
|
||||
});
|
||||
} catch (e) {
|
||||
|
|
@ -384,3 +389,12 @@ Template.selectAuthenticationMethod.helpers({
|
|||
return Template.instance().data.authenticationMethod === match;
|
||||
},
|
||||
});
|
||||
|
||||
Template.selectSpinnerName.helpers({
|
||||
spinners() {
|
||||
return ALLOWED_WAIT_SPINNERS;
|
||||
},
|
||||
isSelected(match) {
|
||||
return Template.instance().data.spinnerName === match;
|
||||
},
|
||||
});
|
||||
|
|
|
|||
|
|
@ -5,10 +5,6 @@ template(name="sidebar")
|
|||
// title="{{showTongueTitle}}")
|
||||
// i.fa.fa-navicon
|
||||
.sidebar-shadow
|
||||
.sidebar-content.sidebar-shortcuts
|
||||
a.board-header-btn.js-shortcuts
|
||||
i.fa.fa-keyboard-o
|
||||
span {{_ 'keyboard-shortcuts' }}
|
||||
.sidebar-content.js-board-sidebar-content
|
||||
//a.hide-btn.js-hide-sidebar
|
||||
// i.fa.fa-navicon
|
||||
|
|
@ -23,7 +19,7 @@ template(name='homeSidebar')
|
|||
hr
|
||||
+labelsWidget
|
||||
ul#cards.label-text-hidden
|
||||
a.flex.js-toggle-minicard-label-text
|
||||
a.flex.js-toggle-minicard-label-text(title="{{_ 'hide-minicard-label-text'}}")
|
||||
span {{_ 'hide-minicard-label-text'}}
|
||||
b
|
||||
.materialCheckBox(class="{{#if hiddenMinicardLabelText}}is-checked{{/if}}")
|
||||
|
|
@ -35,10 +31,36 @@ template(name='homeSidebar')
|
|||
+activities(mode="board")
|
||||
|
||||
template(name="membersWidget")
|
||||
.board-widget.board-widget-members
|
||||
h3
|
||||
i.fa.fa-users
|
||||
| {{_ 'organizations'}}
|
||||
|
||||
.board-widget-content
|
||||
+boardOrgGeneral
|
||||
.clearfix
|
||||
br
|
||||
hr
|
||||
.board-widget.board-widget-members
|
||||
h3
|
||||
i.fa.fa-users
|
||||
| {{_ 'teams'}}
|
||||
|
||||
.board-widget-content
|
||||
+boardTeamGeneral
|
||||
.clearfix
|
||||
br
|
||||
hr
|
||||
.board-widget.board-widget-members
|
||||
h3
|
||||
i.fa.fa-users
|
||||
| {{_ 'members'}}
|
||||
|
||||
.sidebar-shortcuts
|
||||
a.board-header-btn.js-shortcuts(title="{{_ 'keyboard-shortcuts' }}")
|
||||
i.fa.fa-keyboard-o
|
||||
span {{_ 'keyboard-shortcuts' }}
|
||||
|
||||
unless currentUser.isCommentOnly
|
||||
unless currentUser.isWorker
|
||||
a.board-header-btn.js-open-board-menu(title="{{_ 'boardMenuPopup-title'}}").right
|
||||
|
|
@ -49,10 +71,10 @@ template(name="membersWidget")
|
|||
+userAvatar(userId=this.userId showStatus=true)
|
||||
if isSandstorm
|
||||
if currentUser.isBoardMember
|
||||
a.member.add-member.sandstorm-powerbox-request-identity
|
||||
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
|
||||
a.member.add-member.js-manage-board-members(title="{{_ 'add-members'}}")
|
||||
i.fa.fa-plus
|
||||
.clearfix
|
||||
if isInvited
|
||||
|
|
@ -63,6 +85,30 @@ template(name="membersWidget")
|
|||
button.js-member-invite-accept.primary {{_ 'accept'}}
|
||||
button.js-member-invite-decline {{_ 'decline'}}
|
||||
|
||||
template(name="boardOrgGeneral")
|
||||
table
|
||||
tbody
|
||||
tr
|
||||
th {{_ 'displayName'}}
|
||||
th
|
||||
if currentUser.isBoardAdmin
|
||||
a.member.orgOrTeamMember.add-member.js-manage-board-addOrg(title="{{_ 'add-members'}}")
|
||||
i.fa.fa-plus
|
||||
each org in currentBoard.activeOrgs
|
||||
+boardOrgRow(orgId=org.orgId)
|
||||
|
||||
template(name="boardTeamGeneral")
|
||||
table
|
||||
tbody
|
||||
tr
|
||||
th {{_ 'displayName'}}
|
||||
th
|
||||
if currentUser.isBoardAdmin
|
||||
a.member.orgOrTeamMember.add-member.js-manage-board-addTeam(title="{{_ 'add-members'}}")
|
||||
i.fa.fa-plus
|
||||
each currentBoard.activeTeams
|
||||
+boardTeamRow(teamId=this.teamId)
|
||||
|
||||
template(name="boardChangeColorPopup")
|
||||
.board-backgrounds-list.clearfix
|
||||
each backgroundColors
|
||||
|
|
@ -131,6 +177,12 @@ template(name="boardCardSettingsPopup")
|
|||
span
|
||||
i.fa.fa-user-plus
|
||||
| {{_ 'requested-by'}}
|
||||
div.check-div
|
||||
a.flex.js-field-has-card-sorting-by-number(class="{{#if allowsCardSortingByNumber}}is-checked{{/if}}")
|
||||
.materialCheckBox(class="{{#if allowsCardSortingByNumber}}is-checked{{/if}}")
|
||||
span
|
||||
i.fa.fa-sort
|
||||
| {{_ 'card-sorting-by-number'}}
|
||||
div.check-div
|
||||
a.flex.js-field-has-labels(class="{{#if allowsLabels}}is-checked{{/if}}")
|
||||
.materialCheckBox(class="{{#if allowsLabels}}is-checked{{/if}}")
|
||||
|
|
@ -362,7 +414,7 @@ template(name="labelsWidget")
|
|||
+viewer
|
||||
= name
|
||||
if currentUser.isBoardAdmin
|
||||
a.card-label.add-label.js-add-label
|
||||
a.card-label.add-label.js-add-label(title="{{_ 'label-create'}}")
|
||||
i.fa.fa-plus
|
||||
|
||||
template(name="memberPopup")
|
||||
|
|
@ -401,6 +453,40 @@ template(name="leaveBoardPopup")
|
|||
p {{_ 'leave-board-pop' boardTitle=board.title}}
|
||||
button.js-confirm.negate.full(type="submit") {{_ 'leave-board'}}
|
||||
|
||||
template(name="addBoardOrgPopup")
|
||||
select.js-boardOrgs#jsBoardOrgs
|
||||
option(value="-1") {{_ 'organizations'}} :
|
||||
each value in orgsDatas
|
||||
option(value="{{value._id}}") {{_ value.orgDisplayName}}
|
||||
|
||||
template(name="removeBoardOrgPopup")
|
||||
form
|
||||
input.hide#hideOrgId(type="text" value=org._id)
|
||||
label
|
||||
| {{_ 'leave-board'}} ?
|
||||
br
|
||||
hr
|
||||
div.buttonsContainer
|
||||
input.primary.wide.leaveBoardBtn#leaveBoardBtn(type="submit" value="{{_ 'leave-board'}}")
|
||||
input.primary.wide.cancelLeaveBoardBtn#cancelLeaveBoardBtn(type="submit" value="{{_ 'Cancel'}}")
|
||||
|
||||
template(name="addBoardTeamPopup")
|
||||
select.js-boardTeams#jsBoardTeams
|
||||
option(value="-1") {{_ 'teams'}} :
|
||||
each value in teamsDatas
|
||||
option(value="{{value._id}}") {{_ value.teamDisplayName}}
|
||||
|
||||
template(name="removeBoardTeamPopup")
|
||||
form
|
||||
input.hide#hideTeamId(type="text" value=team._id)
|
||||
label
|
||||
| {{_ 'leave-board'}} ?
|
||||
br
|
||||
hr
|
||||
div.buttonsContainer
|
||||
input.primary.wide.leaveBoardBtn#leaveBoardTeamBtn(type="submit" value="{{_ 'leave-board'}}")
|
||||
input.primary.wide.cancelLeaveBoardBtn#cancelLeaveBoardTeamBtn(type="submit" value="{{_ 'Cancel'}}")
|
||||
|
||||
template(name="addMemberPopup")
|
||||
.js-search-member
|
||||
+esInput(index="users")
|
||||
|
|
|
|||
|
|
@ -313,6 +313,8 @@ Template.membersWidget.events({
|
|||
'click .js-member': Popup.open('member'),
|
||||
'click .js-open-board-menu': Popup.open('boardMenu'),
|
||||
'click .js-manage-board-members': Popup.open('addMember'),
|
||||
'click .js-manage-board-addOrg': Popup.open('addBoardOrg'),
|
||||
'click .js-manage-board-addTeam': Popup.open('addBoardTeam'),
|
||||
'click .js-import': Popup.open('boardImportBoard'),
|
||||
submit: this.onSubmit,
|
||||
'click .js-import-board': Popup.open('chooseBoardSource'),
|
||||
|
|
@ -754,6 +756,10 @@ BlazeComponent.extendComponent({
|
|||
return this.currentBoard.allowsRequestedBy;
|
||||
},
|
||||
|
||||
allowsCardSortingByNumber() {
|
||||
return this.currentBoard.allowsCardSortingByNumber;
|
||||
},
|
||||
|
||||
allowsLabels() {
|
||||
return this.currentBoard.allowsLabels;
|
||||
},
|
||||
|
|
@ -968,6 +974,22 @@ BlazeComponent.extendComponent({
|
|||
this.currentBoard.allowsRequestedBy,
|
||||
);
|
||||
},
|
||||
'click .js-field-has-card-sorting-by-number'(evt) {
|
||||
evt.preventDefault();
|
||||
this.currentBoard.allowsCardSortingByNumber = !this.currentBoard
|
||||
.allowsCardSortingByNumber;
|
||||
this.currentBoard.setAllowsCardSortingByNumber(
|
||||
this.currentBoard.allowsCardSortingByNumber,
|
||||
);
|
||||
$(`.js-field-has-card-sorting-by-number ${MCB}`).toggleClass(
|
||||
CKCLS,
|
||||
this.currentBoard.allowsCardSortingByNumber,
|
||||
);
|
||||
$('.js-field-has-card-sorting-by-number').toggleClass(
|
||||
CKCLS,
|
||||
this.currentBoard.allowsCardSortingByNumber,
|
||||
);
|
||||
},
|
||||
'click .js-field-has-labels'(evt) {
|
||||
evt.preventDefault();
|
||||
this.currentBoard.allowsLabels = !this.currentBoard.allowsLabels;
|
||||
|
|
@ -1148,6 +1170,283 @@ BlazeComponent.extendComponent({
|
|||
},
|
||||
}).register('addMemberPopup');
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
onCreated() {
|
||||
this.error = new ReactiveVar('');
|
||||
this.loading = new ReactiveVar(false);
|
||||
this.findOrgsOptions = new ReactiveVar({});
|
||||
|
||||
this.page = new ReactiveVar(1);
|
||||
this.autorun(() => {
|
||||
const limitOrgs = this.page.get() * Number.MAX_SAFE_INTEGER;
|
||||
this.subscribe('org', this.findOrgsOptions.get(), limitOrgs, () => {});
|
||||
});
|
||||
},
|
||||
|
||||
onRendered() {
|
||||
this.setLoading(false);
|
||||
},
|
||||
|
||||
setError(error) {
|
||||
this.error.set(error);
|
||||
},
|
||||
|
||||
setLoading(w) {
|
||||
this.loading.set(w);
|
||||
},
|
||||
|
||||
isLoading() {
|
||||
return this.loading.get();
|
||||
},
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'keyup input'() {
|
||||
this.setError('');
|
||||
},
|
||||
'change #jsBoardOrgs'() {
|
||||
let currentBoard = Boards.findOne(Session.get('currentBoard'));
|
||||
let selectElt = document.getElementById("jsBoardOrgs");
|
||||
let selectedOrgId = selectElt.options[selectElt.selectedIndex].value;
|
||||
let selectedOrgDisplayName = selectElt.options[selectElt.selectedIndex].text;
|
||||
let boardOrganizations = [];
|
||||
if(currentBoard.orgs !== undefined){
|
||||
for(let i = 0; i < currentBoard.orgs.length; i++){
|
||||
boardOrganizations.push(currentBoard.orgs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if(!boardOrganizations.some((org) => org.orgDisplayName == selectedOrgDisplayName)){
|
||||
boardOrganizations.push({
|
||||
"orgId": selectedOrgId,
|
||||
"orgDisplayName": selectedOrgDisplayName,
|
||||
"isActive" : true,
|
||||
})
|
||||
|
||||
if (selectedOrgId != "-1") {
|
||||
Meteor.call('setBoardOrgs', boardOrganizations, currentBoard._id);
|
||||
}
|
||||
}
|
||||
|
||||
Popup.close();
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('addBoardOrgPopup');
|
||||
|
||||
Template.addBoardOrgPopup.helpers({
|
||||
orgsDatas() {
|
||||
// return Org.find({}, {sort: { createdAt: -1 }});
|
||||
let orgs = Org.find({}, {sort: { createdAt: -1 }});
|
||||
return orgs;
|
||||
},
|
||||
});
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
onCreated() {
|
||||
this.error = new ReactiveVar('');
|
||||
this.loading = new ReactiveVar(false);
|
||||
this.findOrgsOptions = new ReactiveVar({});
|
||||
|
||||
this.page = new ReactiveVar(1);
|
||||
this.autorun(() => {
|
||||
const limitOrgs = this.page.get() * Number.MAX_SAFE_INTEGER;
|
||||
this.subscribe('org', this.findOrgsOptions.get(), limitOrgs, () => {});
|
||||
});
|
||||
},
|
||||
|
||||
onRendered() {
|
||||
this.setLoading(false);
|
||||
},
|
||||
|
||||
setError(error) {
|
||||
this.error.set(error);
|
||||
},
|
||||
|
||||
setLoading(w) {
|
||||
this.loading.set(w);
|
||||
},
|
||||
|
||||
isLoading() {
|
||||
return this.loading.get();
|
||||
},
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'keyup input'() {
|
||||
this.setError('');
|
||||
},
|
||||
'click #leaveBoardBtn'(){
|
||||
let stringOrgId = document.getElementById('hideOrgId').value;
|
||||
let currentBoard = Boards.findOne(Session.get('currentBoard'));
|
||||
let boardOrganizations = [];
|
||||
if(currentBoard.orgs !== undefined){
|
||||
for(let i = 0; i < currentBoard.orgs.length; i++){
|
||||
if(currentBoard.orgs[i].orgId != stringOrgId){
|
||||
boardOrganizations.push(currentBoard.orgs[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Meteor.call('setBoardOrgs', boardOrganizations, currentBoard._id);
|
||||
|
||||
Popup.close();
|
||||
},
|
||||
'click #cancelLeaveBoardBtn'(){
|
||||
Popup.close();
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('removeBoardOrgPopup');
|
||||
|
||||
Template.removeBoardOrgPopup.helpers({
|
||||
org() {
|
||||
return Org.findOne(this.orgId);
|
||||
},
|
||||
});
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
onCreated() {
|
||||
this.error = new ReactiveVar('');
|
||||
this.loading = new ReactiveVar(false);
|
||||
this.findOrgsOptions = new ReactiveVar({});
|
||||
|
||||
this.page = new ReactiveVar(1);
|
||||
this.autorun(() => {
|
||||
const limitTeams = this.page.get() * Number.MAX_SAFE_INTEGER;
|
||||
this.subscribe('team', this.findOrgsOptions.get(), limitTeams, () => {});
|
||||
});
|
||||
},
|
||||
|
||||
onRendered() {
|
||||
this.setLoading(false);
|
||||
},
|
||||
|
||||
setError(error) {
|
||||
this.error.set(error);
|
||||
},
|
||||
|
||||
setLoading(w) {
|
||||
this.loading.set(w);
|
||||
},
|
||||
|
||||
isLoading() {
|
||||
return this.loading.get();
|
||||
},
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'keyup input'() {
|
||||
this.setError('');
|
||||
},
|
||||
'change #jsBoardTeams'() {
|
||||
let currentBoard = Boards.findOne(Session.get('currentBoard'));
|
||||
let selectElt = document.getElementById("jsBoardTeams");
|
||||
let selectedTeamId = selectElt.options[selectElt.selectedIndex].value;
|
||||
let selectedTeamDisplayName = selectElt.options[selectElt.selectedIndex].text;
|
||||
let boardTeams = [];
|
||||
if(currentBoard.teams !== undefined){
|
||||
for(let i = 0; i < currentBoard.teams.length; i++){
|
||||
boardTeams.push(currentBoard.teams[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if(!boardTeams.some((team) => team.teamDisplayName == selectedTeamDisplayName)){
|
||||
boardTeams.push({
|
||||
"teamId": selectedTeamId,
|
||||
"teamDisplayName": selectedTeamDisplayName,
|
||||
"isActive" : true,
|
||||
})
|
||||
|
||||
if (selectedTeamId != "-1") {
|
||||
Meteor.call('setBoardTeams', boardTeams, currentBoard._id);
|
||||
}
|
||||
}
|
||||
|
||||
Popup.close();
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('addBoardTeamPopup');
|
||||
|
||||
Template.addBoardTeamPopup.helpers({
|
||||
teamsDatas() {
|
||||
let teams = Team.find({}, {sort: { createdAt: -1 }});
|
||||
return teams;
|
||||
},
|
||||
});
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
onCreated() {
|
||||
this.error = new ReactiveVar('');
|
||||
this.loading = new ReactiveVar(false);
|
||||
this.findOrgsOptions = new ReactiveVar({});
|
||||
|
||||
this.page = new ReactiveVar(1);
|
||||
this.autorun(() => {
|
||||
const limitTeams = this.page.get() * Number.MAX_SAFE_INTEGER;
|
||||
this.subscribe('team', this.findOrgsOptions.get(), limitTeams, () => {});
|
||||
});
|
||||
},
|
||||
|
||||
onRendered() {
|
||||
this.setLoading(false);
|
||||
},
|
||||
|
||||
setError(error) {
|
||||
this.error.set(error);
|
||||
},
|
||||
|
||||
setLoading(w) {
|
||||
this.loading.set(w);
|
||||
},
|
||||
|
||||
isLoading() {
|
||||
return this.loading.get();
|
||||
},
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'keyup input'() {
|
||||
this.setError('');
|
||||
},
|
||||
'click #leaveBoardTeamBtn'(){
|
||||
let stringTeamId = document.getElementById('hideTeamId').value;
|
||||
let currentBoard = Boards.findOne(Session.get('currentBoard'));
|
||||
let boardTeams = [];
|
||||
if(currentBoard.teams !== undefined){
|
||||
for(let i = 0; i < currentBoard.teams.length; i++){
|
||||
if(currentBoard.teams[i].teamId != stringTeamId){
|
||||
boardTeams.push(currentBoard.teams[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Meteor.call('setBoardTeams', boardTeams, currentBoard._id);
|
||||
|
||||
Popup.close();
|
||||
},
|
||||
'click #cancelLeaveBoardTeamBtn'(){
|
||||
Popup.close();
|
||||
},
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('removeBoardTeamPopup');
|
||||
|
||||
Template.removeBoardTeamPopup.helpers({
|
||||
team() {
|
||||
return Team.findOne(this.teamId);
|
||||
},
|
||||
});
|
||||
|
||||
Template.changePermissionsPopup.events({
|
||||
'click .js-set-admin, click .js-set-normal, click .js-set-no-comments, click .js-set-comment-only, click .js-set-worker'(
|
||||
event,
|
||||
|
|
|
|||
|
|
@ -100,13 +100,12 @@
|
|||
margin-right: 10px
|
||||
|
||||
.sidebar-shortcuts
|
||||
margin: 0
|
||||
position: absolute
|
||||
margin-left: 40%
|
||||
padding: 0
|
||||
top: auto
|
||||
text-align: center
|
||||
top: 7px
|
||||
font-size: 0.8em
|
||||
line-height: 1.6em
|
||||
vertical-align: middle
|
||||
color: darken(white, 40%)
|
||||
|
||||
.board-sidebar
|
||||
|
|
@ -215,3 +214,13 @@
|
|||
i.fa
|
||||
padding: 8px 0px 8px 16px
|
||||
font-weight: bold
|
||||
|
||||
#jsBoardOrgs, #jsBoardTeams
|
||||
width: 90%
|
||||
|
||||
.leaveBoardBtn
|
||||
background-color: green !important
|
||||
|
||||
.cancelLeaveBoardBtn
|
||||
margin-left: 5% !important
|
||||
background-color: red !important
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
template(name="swimlaneHeader")
|
||||
.swimlane-header-wrap.js-swimlane-header(class=colorClass)
|
||||
.swimlane-header-wrap.js-swimlane-header(class=colorClass title="{{_ 'rename'}}")
|
||||
if this.isTemplateContainer
|
||||
+swimlaneFixedHeader(this)
|
||||
else
|
||||
|
|
@ -11,13 +11,20 @@ template(name="swimlaneHeader")
|
|||
template(name="swimlaneFixedHeader")
|
||||
.swimlane-header(
|
||||
class="{{#if currentUser.isBoardMember}}js-open-inlined-form is-editable{{/if}}")
|
||||
+viewer
|
||||
= title
|
||||
if $eq title 'Card Templates'
|
||||
| {{_ 'card-templates-swimlane'}}
|
||||
else if $eq title 'List Templates'
|
||||
| {{_ 'list-templates-swimlane'}}
|
||||
else if $eq title 'Board Templates'
|
||||
| {{_ 'board-templates-swimlane'}}
|
||||
else
|
||||
+viewer
|
||||
= title
|
||||
.swimlane-header-menu
|
||||
unless currentUser.isCommentOnly
|
||||
if currentUser.isBoardAdmin
|
||||
a.fa.fa-plus.js-open-add-swimlane-menu.swimlane-header-plus-icon
|
||||
a.fa.fa-navicon.js-open-swimlane-menu
|
||||
a.fa.fa-plus.js-open-add-swimlane-menu.swimlane-header-plus-icon(title="{{_ 'add-swimlane'}}")
|
||||
a.fa.fa-navicon.js-open-swimlane-menu(title="{{_ 'swimlaneActionPopup-title'}}")
|
||||
unless isMiniScreen
|
||||
if showDesktopDragHandles
|
||||
a.swimlane-header-handle.handle.fa.fa-arrows.js-swimlane-header-handle
|
||||
|
|
|
|||
|
|
@ -58,9 +58,8 @@ template(name="addListForm")
|
|||
| {{_ 'or'}}
|
||||
a.js-list-template {{_ 'template'}}
|
||||
else
|
||||
a.open-list-composer.js-open-inlined-form
|
||||
a.open-list-composer.js-open-inlined-form(title="{{_ 'add-list'}}")
|
||||
i.fa.fa-plus
|
||||
| {{_ 'add-list'}}
|
||||
|
||||
template(name="moveSwimlanePopup")
|
||||
unless currentUser.isWorker
|
||||
|
|
|
|||
|
|
@ -19,6 +19,44 @@ template(name="userAvatarInitials")
|
|||
svg.avatar.avatar-initials(viewBox="0 0 {{viewPortWidth}} 15")
|
||||
text(x="50%" y="13" text-anchor="middle")= initials
|
||||
|
||||
template(name="orgAvatar")
|
||||
a.member.orgOrTeamMember(class="js-member" title="{{orgData.orgDisplayName}}")
|
||||
+boardOrgName(orgId=orgData._id)
|
||||
|
||||
template(name="boardOrgRow")
|
||||
tr
|
||||
if orgData.orgIsActive
|
||||
td <s>{{ orgData.orgDisplayName }}</s>
|
||||
else
|
||||
td {{ orgData.orgDisplayName }}
|
||||
td
|
||||
if currentUser.isBoardAdmin
|
||||
a.member.orgOrTeamMember.add-member.js-manage-board-removeOrg(title="{{_ 'remove-from-board'}}")
|
||||
i.fa.fa-minus
|
||||
|
||||
template(name="boardTeamRow")
|
||||
tr
|
||||
if teamData.teamIsActive
|
||||
td <s>{{ teamData.teamDisplayName }}</s>
|
||||
else
|
||||
td {{ teamData.teamDisplayName }}
|
||||
td
|
||||
if currentUser.isBoardAdmin
|
||||
a.member.orgOrTeamMember.add-member.js-manage-board-removeTeam(title="{{_ 'remove-from-board'}}")
|
||||
i.fa.fa-minus
|
||||
|
||||
template(name="boardOrgName")
|
||||
svg.avatar.avatar-initials(viewBox="0 0 {{orgViewPortWidth}} 15")
|
||||
text(x="50%" y="13" text-anchor="middle")= orgName
|
||||
|
||||
template(name="teamAvatar")
|
||||
a.member.orgOrTeamMember(class="js-member" title="{{teamData.teamDisplayName}}")
|
||||
+boardTeamName(orgId=orgData._id)
|
||||
|
||||
template(name="boardTeamName")
|
||||
svg.avatar.avatar-initials(viewBox="0 0 {{teamViewPortWidth}} 15")
|
||||
text(x="50%" y="13" text-anchor="middle")= teamName
|
||||
|
||||
template(name="userPopup")
|
||||
.board-member-menu
|
||||
.mini-profile-info
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import Cards from '/models/cards';
|
||||
import Avatars from '/models/avatars';
|
||||
import Users from '/models/users';
|
||||
import Org from '/models/org';
|
||||
import Team from '/models/team';
|
||||
|
||||
Template.userAvatar.helpers({
|
||||
userData() {
|
||||
|
|
@ -46,6 +48,132 @@ Template.userAvatarInitials.helpers({
|
|||
},
|
||||
});
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
onCreated() {
|
||||
this.error = new ReactiveVar('');
|
||||
this.loading = new ReactiveVar(false);
|
||||
this.findOrgsOptions = new ReactiveVar({});
|
||||
|
||||
this.page = new ReactiveVar(1);
|
||||
this.autorun(() => {
|
||||
const limitOrgs = this.page.get() * Number.MAX_SAFE_INTEGER;
|
||||
this.subscribe('org', this.findOrgsOptions.get(), limitOrgs, () => {});
|
||||
});
|
||||
},
|
||||
|
||||
onRendered() {
|
||||
this.setLoading(false);
|
||||
},
|
||||
|
||||
setError(error) {
|
||||
this.error.set(error);
|
||||
},
|
||||
|
||||
setLoading(w) {
|
||||
this.loading.set(w);
|
||||
},
|
||||
|
||||
isLoading() {
|
||||
return this.loading.get();
|
||||
},
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'keyup input'() {
|
||||
this.setError('');
|
||||
},
|
||||
'click .js-manage-board-removeOrg': Popup.open('removeBoardOrg'),
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('boardOrgRow');
|
||||
|
||||
Template.boardOrgRow.helpers({
|
||||
orgData() {
|
||||
const orgCollection = this.esSearch ? ESSearchResults : Org;
|
||||
return orgCollection.findOne(this.orgId);
|
||||
},
|
||||
currentUser(){
|
||||
return Meteor.user();
|
||||
},
|
||||
});
|
||||
|
||||
Template.boardOrgName.helpers({
|
||||
orgName() {
|
||||
const org = Org.findOne(this.orgId);
|
||||
return org && org.orgDisplayName;
|
||||
},
|
||||
|
||||
orgViewPortWidth() {
|
||||
const org = Org.findOne(this.orgId);
|
||||
return ((org && org.orgDisplayName.length) || 1) * 12;
|
||||
},
|
||||
});
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
onCreated() {
|
||||
this.error = new ReactiveVar('');
|
||||
this.loading = new ReactiveVar(false);
|
||||
this.findOrgsOptions = new ReactiveVar({});
|
||||
|
||||
this.page = new ReactiveVar(1);
|
||||
this.autorun(() => {
|
||||
const limitTeams = this.page.get() * Number.MAX_SAFE_INTEGER;
|
||||
this.subscribe('team', this.findOrgsOptions.get(), limitTeams, () => {});
|
||||
});
|
||||
},
|
||||
|
||||
onRendered() {
|
||||
this.setLoading(false);
|
||||
},
|
||||
|
||||
setError(error) {
|
||||
this.error.set(error);
|
||||
},
|
||||
|
||||
setLoading(w) {
|
||||
this.loading.set(w);
|
||||
},
|
||||
|
||||
isLoading() {
|
||||
return this.loading.get();
|
||||
},
|
||||
|
||||
events() {
|
||||
return [
|
||||
{
|
||||
'keyup input'() {
|
||||
this.setError('');
|
||||
},
|
||||
'click .js-manage-board-removeTeam': Popup.open('removeBoardTeam'),
|
||||
},
|
||||
];
|
||||
},
|
||||
}).register('boardTeamRow');
|
||||
|
||||
Template.boardTeamRow.helpers({
|
||||
teamData() {
|
||||
const teamCollection = this.esSearch ? ESSearchResults : Team;
|
||||
return teamCollection.findOne(this.teamId);
|
||||
},
|
||||
currentUser(){
|
||||
return Meteor.user();
|
||||
},
|
||||
});
|
||||
|
||||
Template.boardTeamName.helpers({
|
||||
teamName() {
|
||||
const team = Team.findOne(this.teamId);
|
||||
return team && team.teamDisplayName;
|
||||
},
|
||||
|
||||
teamViewPortWidth() {
|
||||
const team = Team.findOne(this.teamId);
|
||||
return ((team && team.teamDisplayName.length) || 1) * 12;
|
||||
},
|
||||
});
|
||||
|
||||
BlazeComponent.extendComponent({
|
||||
onCreated() {
|
||||
this.error = new ReactiveVar('');
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
template(name="headerUserBar")
|
||||
#header-user-bar
|
||||
a.header-user-bar-name.js-open-header-member-menu
|
||||
a.header-user-bar-name.js-open-header-member-menu(title="{{_ 'memberMenuPopup-title'}}")
|
||||
.header-user-bar-avatar
|
||||
+userAvatar(userId=currentUser._id)
|
||||
unless isMiniScreen
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue