diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/components/activities/activities.jade | 2 | ||||
-rw-r--r-- | client/components/activities/activities.styl | 5 | ||||
-rw-r--r-- | client/components/boards/boardColors.styl | 11 | ||||
-rw-r--r-- | client/components/cards/cardDetails.jade | 11 | ||||
-rw-r--r-- | client/components/cards/cardDetails.js | 8 | ||||
-rw-r--r-- | client/components/cards/checklists.jade | 21 | ||||
-rw-r--r-- | client/components/cards/checklists.js | 75 | ||||
-rw-r--r-- | client/components/cards/checklists.styl | 40 | ||||
-rw-r--r-- | client/components/cards/labels.jade | 3 | ||||
-rw-r--r-- | client/components/forms/forms.styl | 53 | ||||
-rw-r--r-- | client/components/main/header.jade | 8 | ||||
-rw-r--r-- | client/components/main/header.js | 14 | ||||
-rw-r--r-- | client/components/main/header.styl | 1 | ||||
-rw-r--r-- | client/components/settings/settingBody.jade | 20 | ||||
-rw-r--r-- | client/components/settings/settingBody.js | 45 | ||||
-rw-r--r-- | client/components/settings/settingBody.styl | 7 |
16 files changed, 299 insertions, 25 deletions
diff --git a/client/components/activities/activities.jade b/client/components/activities/activities.jade index be12a728..4d5410d4 100644 --- a/client/components/activities/activities.jade +++ b/client/components/activities/activities.jade @@ -31,7 +31,7 @@ template(name="boardActivities") .activity-checklist(href="{{ card.absoluteUrl }}") +viewer = checklist.title - + if($eq activityType 'addChecklistItem') | {{{_ 'activity-checklist-item-added' checklist.title cardLink}}}. .activity-checklist(href="{{ card.absoluteUrl }}") diff --git a/client/components/activities/activities.styl b/client/components/activities/activities.styl index 2285fc0a..36efd771 100644 --- a/client/components/activities/activities.styl +++ b/client/components/activities/activities.styl @@ -1,5 +1,10 @@ @import 'nib' +.activity-title + margin: 0 0.5em 0.8em + display: flex + justify-content:space-between + .activities clear: both diff --git a/client/components/boards/boardColors.styl b/client/components/boards/boardColors.styl index 8e28fcfa..57a121a2 100644 --- a/client/components/boards/boardColors.styl +++ b/client/components/boards/boardColors.styl @@ -51,6 +51,17 @@ setBoardColor(color) &:not(.is-checked) + .minicard:hover:not(.minicard-composer) background: lighten(color, 97%) + .toggle-label + + &:after + background-color: darken(color, 20%) + + .toggle-switch:checked ~ .toggle-label + background-color: lighten(color, 20%) + + &:after + background-color: darken(color, 20%) + @media screen and (max-width: 800px) &.pop-over .header background: color diff --git a/client/components/cards/cardDetails.jade b/client/components/cards/cardDetails.jade index 09e0532c..ce93d6fd 100644 --- a/client/components/cards/cardDetails.jade +++ b/client/components/cards/cardDetails.jade @@ -85,7 +85,16 @@ template(name="cardDetails") +attachmentsGalery hr - h2 {{ _ 'activity'}} + .activity-title + h2 {{ _ 'activity'}} + 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 currentUser.isBoardMember +commentForm if isLoaded.get diff --git a/client/components/cards/cardDetails.js b/client/components/cards/cardDetails.js index 7c6c3ce7..836a2353 100644 --- a/client/components/cards/cardDetails.js +++ b/client/components/cards/cardDetails.js @@ -28,6 +28,10 @@ BlazeComponent.extendComponent({ return card.findWatcher(Meteor.userId()); }, + hiddenSystemMessages() { + return Meteor.user().hasHiddenSystemMessages(); + }, + canModifyCard() { return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly(); }, @@ -99,6 +103,9 @@ BlazeComponent.extendComponent({ this.parentComponent().showOverlay.set(true); this.parentComponent().mouseHasEnterCardDetails = true; }, + 'click #toggleButton'() { + Meteor.call('toggleSystemMessages'); + }, }]; }, }).register('cardDetails'); @@ -220,6 +227,7 @@ Template.copyCardPopup.events({ if (title) { card.title = title; + card.coverId = ''; const _id = Cards.insert(card); // In case the filter is active we need to add the newly inserted card in // the list of exceptions -- cards that are not filtered. Otherwise the diff --git a/client/components/cards/checklists.jade b/client/components/cards/checklists.jade index e1dd1d14..9ff52d8e 100644 --- a/client/components/cards/checklists.jade +++ b/client/components/cards/checklists.jade @@ -1,8 +1,14 @@ template(name="checklists") h2 {{_ 'checklists'}} + if toggleDeleteDialog.get + .board-overlay#card-details-overlay + +checklistDeleteDialog(checklist = checklistToDelete) + + .card-checklist-items each checklist in currentCard.checklists +checklistDetail(checklist = checklist) + if canModifyCard +inlinedForm(autoclose=false classNames="js-add-checklist" cardId = cardId) +addChecklistItemForm @@ -18,7 +24,8 @@ template(name="checklistDetail") .checklist-title .checkbox.fa.fa-check-square-o if canModifyCard - a.js-delete-checklist {{_ "delete"}}... + a.js-delete-checklist.toggle-delete-checklist-dialog {{_ "delete"}}... + span.checklist-stat(class="{{#if checklist.isFinished}}is-finished{{/if}}") {{checklist.finishedCount}}/{{checklist.itemCount}} if canModifyCard h2.title.js-open-inlined-form.is-editable {{checklist.title}} @@ -26,6 +33,18 @@ template(name="checklistDetail") h2.title {{checklist.title}} +checklistItems(checklist = checklist) +template(name="checklistDeleteDialog") + .js-confirm-checklist-delete + p + i(class="fa fa-exclamation-triangle" aria-hidden="true") + p + | {{_ 'confirm-checklist-delete-dialog'}} + span {{checklist.title}} + | ? + .js-checklist-delete-buttons + button.confirm-checklist-delete(type="button") {{_ 'delete'}} + button.toggle-delete-checklist-dialog(type="button") {{_ 'cancel'}} + template(name="addChecklistItemForm") textarea.js-add-checklist-item(rows='1' autofocus) .edit-controls.clearfix diff --git a/client/components/cards/checklists.js b/client/components/cards/checklists.js index ba3384a9..1cd77c9f 100644 --- a/client/components/cards/checklists.js +++ b/client/components/cards/checklists.js @@ -66,6 +66,7 @@ Template.checklists.onRendered(function () { }); BlazeComponent.extendComponent({ + addChecklist(event) { event.preventDefault(); const textarea = this.find('textarea.js-add-checklist-item'); @@ -101,6 +102,26 @@ BlazeComponent.extendComponent({ textarea.focus(); }, + canModifyCard() { + return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly(); + }, + + deleteChecklist() { + const checklist = this.currentData().checklist; + if (checklist && checklist._id) { + Checklists.remove(checklist._id); + this.toggleDeleteDialog.set(false); + } + }, + + deleteItem() { + const checklist = this.currentData().checklist; + const item = this.currentData().item; + if (checklist && item && item._id) { + checklist.removeItem(item._id); + } + }, + editChecklist(event) { event.preventDefault(); const textarea = this.find('textarea.js-edit-checklist-item'); @@ -109,10 +130,6 @@ BlazeComponent.extendComponent({ checklist.setTitle(title); }, - canModifyCard() { - return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly(); - }, - editChecklistItem(event) { event.preventDefault(); @@ -123,19 +140,9 @@ BlazeComponent.extendComponent({ checklist.editItem(itemId, title); }, - deleteItem() { - const checklist = this.currentData().checklist; - const item = this.currentData().item; - if (checklist && item && item._id) { - checklist.removeItem(item._id); - } - }, - - deleteChecklist() { - const checklist = this.currentData().checklist; - if (checklist && checklist._id) { - Checklists.remove(checklist._id); - } + onCreated() { + this.toggleDeleteDialog = new ReactiveVar(false); + this.checklistToDelete = null; //Store data context to pass to checklistDeleteDialog template }, pressKey(event) { @@ -148,18 +155,50 @@ BlazeComponent.extendComponent({ }, events() { + const events = { + 'click .toggle-delete-checklist-dialog'(event) { + if($(event.target).hasClass('js-delete-checklist')){ + this.checklistToDelete = this.currentData().checklist; //Store data context + } + this.toggleDeleteDialog.set(!this.toggleDeleteDialog.get()); + }, + }; + return [{ + ...events, 'submit .js-add-checklist': this.addChecklist, 'submit .js-edit-checklist-title': this.editChecklist, 'submit .js-add-checklist-item': this.addChecklistItem, 'submit .js-edit-checklist-item': this.editChecklistItem, 'click .js-delete-checklist-item': this.deleteItem, - 'click .js-delete-checklist': this.deleteChecklist, + 'click .confirm-checklist-delete': this.deleteChecklist, keydown: this.pressKey, }]; }, }).register('checklists'); +Template.checklistDeleteDialog.onCreated(() => { + const $cardDetails = this.$('.card-details'); + this.scrollState = { position: $cardDetails.scrollTop(), //save current scroll position + top: false, //required for smooth scroll animation + }; + //Callback's purpose is to only prevent scrolling after animation is complete + $cardDetails.animate({ scrollTop: 0 }, 500, () => { this.scrollState.top = true; }); + + //Prevent scrolling while dialog is open + $cardDetails.on('scroll', () => { + if(this.scrollState.top) { //If it's already in position, keep it there. Otherwise let animation scroll + $cardDetails.scrollTop(0); + } + }); +}); + +Template.checklistDeleteDialog.onDestroyed(() => { + const $cardDetails = this.$('.card-details'); + $cardDetails.off('scroll'); //Reactivate scrolling + $cardDetails.animate( { scrollTop: this.scrollState.position }); +}); + Template.itemDetail.helpers({ canModifyCard() { return Meteor.user() && Meteor.user().isBoardMember() && !Meteor.user().isCommentOnly(); diff --git a/client/components/cards/checklists.styl b/client/components/cards/checklists.styl index 77668349..d4776397 100644 --- a/client/components/cards/checklists.styl +++ b/client/components/cards/checklists.styl @@ -38,6 +38,46 @@ textarea.js-add-checklist-item, textarea.js-edit-checklist-item .js-delete-checklist @extends .delete-text + +.js-confirm-checklist-delete + background-color: darken(white, 3%) + position: absolute + float: left; + width: 60% + margin-top: 0 + margin-left: 13% + padding-bottom: 2% + padding-left: 3% + padding-right: 3% + z-index: 17 + border-radius: 3px + + p + position: relative + margin-top: 3% + width: 100% + text-align: center + span + font-weight: bold + + i + font-size: 2em + + .js-checklist-delete-buttons + position: relative + padding: left 2% right 2% + .confirm-checklist-delete + margin-left: 12% + float: left + .toggle-delete-checklist-dialog + margin-right: 12% + float: right + +#card-details-overlay + top: 0 + bottom: -600px + right: 0 + .checklist-items margin: 0 0 0.5em 1.33em diff --git a/client/components/cards/labels.jade b/client/components/cards/labels.jade index 31bd4d06..6c6efb08 100644 --- a/client/components/cards/labels.jade +++ b/client/components/cards/labels.jade @@ -34,4 +34,5 @@ template(name="cardLabelsPopup") = name if(isLabelSelected ../_id) i.card-label-selectable-icon.fa.fa-check - a.quiet-button.full.js-add-label {{_ 'label-create'}} + if currentUser.isBoardAdmin + a.quiet-button.full.js-add-label {{_ 'label-create'}} diff --git a/client/components/forms/forms.styl b/client/components/forms/forms.styl index 646da657..1947c11d 100644 --- a/client/components/forms/forms.styl +++ b/client/components/forms/forms.styl @@ -630,6 +630,59 @@ button a, .quiet color: white +// Material Design Toggle Switch +.material-toggle-switch + display: flex + +.toggle-label + position: relative + display: block + height: 20px + width: 44px + background-color: #a6a6a6 + border-radius: 100px + cursor: pointer + transition: all 0.3s ease + + &:after + position: absolute + left: -2px + top: -3px + display: block + width: 26px + height: 26px + border-radius: 100px + background-color: #fff + box-shadow: 0px 3px 3px rgba(0,0,0,0.05) + content: '' + transition: all 0.3s ease + + &:active + &:after + transform: scale(1.15, 0.85) + +.toggle-switch:checked ~ .toggle-label + background-color: #6fbeb5 + + &:after + left: 20px + background-color: #179588 + +.toggle-switch:checked:disabled ~ .toggle-label + background-color: #d5d5d5 + pointer-events: none + + &:after + background-color: #bcbdbc + +.toggle-switch + display: none + +.toggle-switch-title + margin: 0 0.5em + display: flex + + @media screen and (max-width: 800px) .edit-controls, .add-controls diff --git a/client/components/main/header.jade b/client/components/main/header.jade index bd0af880..51bccd09 100644 --- a/client/components/main/header.jade +++ b/client/components/main/header.jade @@ -49,6 +49,14 @@ template(name="header") if appIsOffline +offlineWarning + if currentUser.isBoardMember + if hasAnnouncement + .announcement + p + i.fa.fa-bullhorn + | #{announcement} + i.fa.fa-times-circle.js-close-announcement + template(name="offlineWarning") .offline-warning p diff --git a/client/components/main/header.js b/client/components/main/header.js index 49acbfef..c8f415df 100644 --- a/client/components/main/header.js +++ b/client/components/main/header.js @@ -10,8 +10,22 @@ Template.header.helpers({ appIsOffline() { return !Meteor.status().connected; }, + + hasAnnouncement() { + const announcements = Announcements.findOne(); + return announcements && announcements.enabled; + }, + + announcement() { + $('.announcement').show(); + const announcements = Announcements.findOne(); + return announcements && announcements.body; + }, }); Template.header.events({ 'click .js-create-board': Popup.open('headerBarCreateBoard'), + 'click .js-close-announcement'() { + $('.announcement').hide(); + }, }); diff --git a/client/components/main/header.styl b/client/components/main/header.styl index 0e35d38a..191e8893 100644 --- a/client/components/main/header.styl +++ b/client/components/main/header.styl @@ -197,6 +197,7 @@ li height: 28px +.announcement, .offline-warning width: 100% text-align: center diff --git a/client/components/settings/settingBody.jade b/client/components/settings/settingBody.jade index 5864efd5..2152cc2c 100644 --- a/client/components/settings/settingBody.jade +++ b/client/components/settings/settingBody.jade @@ -14,6 +14,8 @@ template(name="setting") a.js-setting-menu(data-id="email-setting") {{_ 'email'}} li a.js-setting-menu(data-id="account-setting") {{_ 'accounts'}} + li + a.js-setting-menu(data-id="announcement-setting") {{_ 'admin-announcement'}} .main-body if loading.get +spinner @@ -23,6 +25,8 @@ template(name="setting") +email else if accountSetting.get +accountSettings + else if announcementSetting.get + +announcementSettings template(name="general") ul#registration-setting.setting-detail @@ -96,3 +100,19 @@ template(name='accountSettings') span {{_ 'no'}} li button.js-accounts-save.primary {{_ 'save'}} + +template(name='announcementSettings') + ul#announcement-setting.setting-detail + li + a.flex.js-toggle-activemessage + .materialCheckBox(class="{{#if currentSetting.enabled}}is-checked{{/if}}") + + span {{_ 'admin-announcement-active'}} + li + .admin-announcement(class="{{#if currentSetting.enabled}}{{else}}hide{{/if}}") + ul + li + .title {{_ 'admin-announcement-title'}} + textarea#admin-announcement.form-control= currentSetting.body + li + button.js-announcement-save.primary {{_ 'save'}} diff --git a/client/components/settings/settingBody.js b/client/components/settings/settingBody.js index a2993426..27f690ee 100644 --- a/client/components/settings/settingBody.js +++ b/client/components/settings/settingBody.js @@ -1,6 +1,7 @@ Meteor.subscribe('setting'); Meteor.subscribe('mailServer'); Meteor.subscribe('accountSettings'); +Meteor.subscribe('announcements'); BlazeComponent.extendComponent({ onCreated() { @@ -9,6 +10,7 @@ BlazeComponent.extendComponent({ this.generalSetting = new ReactiveVar(true); this.emailSetting = new ReactiveVar(false); this.accountSetting = new ReactiveVar(false); + this.announcementSetting = new ReactiveVar(false); }, setError(error) { @@ -65,6 +67,7 @@ BlazeComponent.extendComponent({ this.generalSetting.set('registration-setting' === targetID); this.emailSetting.set('email-setting' === targetID); this.accountSetting.set('account-setting' === targetID); + this.announcementSetting.set('announcement-setting' === targetID); } }, @@ -152,3 +155,45 @@ BlazeComponent.extendComponent({ }]; }, }).register('accountSettings'); + +BlazeComponent.extendComponent({ + onCreated() { + this.loading = new ReactiveVar(false); + }, + + setLoading(w) { + this.loading.set(w); + }, + + currentSetting(){ + return Announcements.findOne(); + }, + + saveMessage() { + const message = $('#admin-announcement').val().trim(); + Announcements.update(Announcements.findOne()._id, { + $set: { 'body': message }, + }); + }, + + toggleActive(){ + this.setLoading(true); + const isActive = this.currentSetting().enabled; + Announcements.update(Announcements.findOne()._id, { + $set:{ 'enabled': !isActive}, + }); + this.setLoading(false); + if(isActive){ + $('.admin-announcement').slideUp(); + }else{ + $('.admin-announcement').slideDown(); + } + }, + + events() { + return [{ + 'click a.js-toggle-activemessage': this.toggleActive, + 'click button.js-announcement-save': this.saveMessage, + }]; + }, +}).register('announcementSettings'); diff --git a/client/components/settings/settingBody.styl b/client/components/settings/settingBody.styl index 118d364c..fec64cee 100644 --- a/client/components/settings/settingBody.styl +++ b/client/components/settings/settingBody.styl @@ -61,10 +61,11 @@ .is-checked border-bottom: 2px solid #2980b9; border-right: 2px solid #2980b9; - - span + + span padding: 0 0.5rem - + + .admin-announcement, .invite-people padding-left 20px; li |