From 1dfb6ef477dba4d0faf4bf86026647f43fb2f5f6 Mon Sep 17 00:00:00 2001 From: lkisme Date: Fri, 24 Feb 2017 22:10:38 +0800 Subject: Admin panel: Only invited user can register in strict mode, Set mail server in admin panel, Switch strict mode in admin panel, Invite people to system in admin panel --- client/components/main/layouts.js | 2 + client/components/settings/invitationCode.jade | 5 + client/components/settings/invitationCode.js | 6 ++ client/components/settings/settingBody.jade | 72 ++++++++++++++ client/components/settings/settingBody.js | 126 +++++++++++++++++++++++++ client/components/settings/settingBody.styl | 112 ++++++++++++++++++++++ client/components/settings/settingHeader.jade | 21 +++++ client/components/settings/settingHeader.styl | 25 +++++ client/components/users/userHeader.jade | 2 + client/components/users/userHeader.js | 3 + 10 files changed, 374 insertions(+) create mode 100644 client/components/settings/invitationCode.jade create mode 100644 client/components/settings/invitationCode.js create mode 100644 client/components/settings/settingBody.jade create mode 100644 client/components/settings/settingBody.js create mode 100644 client/components/settings/settingBody.styl create mode 100644 client/components/settings/settingHeader.jade create mode 100644 client/components/settings/settingHeader.styl (limited to 'client/components') diff --git a/client/components/main/layouts.js b/client/components/main/layouts.js index 3df17f41..1e50b01a 100644 --- a/client/components/main/layouts.js +++ b/client/components/main/layouts.js @@ -1,4 +1,6 @@ Meteor.subscribe('boards'); +Meteor.subscribe('setting'); +Meteor.subscribe('user-admin'); BlazeLayout.setRoot('body'); diff --git a/client/components/settings/invitationCode.jade b/client/components/settings/invitationCode.jade new file mode 100644 index 00000000..171a2663 --- /dev/null +++ b/client/components/settings/invitationCode.jade @@ -0,0 +1,5 @@ +template(name='invitationCode') + .at-input#invitationcode + label(for='at-field-code') {{_ 'invitation-code'}} + + input#at-field-invitationcode(type="text" name='at-field-invitationcode' placeholder="{{_ 'invitation-code'}}") diff --git a/client/components/settings/invitationCode.js b/client/components/settings/invitationCode.js new file mode 100644 index 00000000..8143d5af --- /dev/null +++ b/client/components/settings/invitationCode.js @@ -0,0 +1,6 @@ +Template.invitationCode.onRendered(() => { + const strict = Settings.findOne().strict; + if(!strict){ + $('#invitationcode').hide(); + } +}); diff --git a/client/components/settings/settingBody.jade b/client/components/settings/settingBody.jade new file mode 100644 index 00000000..5d77bc60 --- /dev/null +++ b/client/components/settings/settingBody.jade @@ -0,0 +1,72 @@ +template(name="setting") + .setting-content + .content-title + span Settings + .content-body + .side-menu + ul + li.active + a.js-setting-menu(data-id="general-setting") System + li + a.js-setting-menu(data-id="email-setting") Email + .main-body + if loading.get + +spinner + else if generalSetting.get + +general + else if emailSetting.get + +email + +template(name="general") + ul#general-setting.setting-detail + li + a.flex.js-toggle-strict-mode + .materialCheckBox(class="{{#if currentSetting.strict}}is-checked{{/if}}") + + span Use Strict Mode + li + .invite-people(class="{{#if currentSetting.strict}}{{else}}hide{{/if}}") + ul + li + .title Invite People + textarea#email-to-invite.form-control(rows='5', placeholder="Email Adresses") + li + .title To board(s) + .bg-white + each boards + a.option.flex.js-toggle-board-choose(id= _id) + .materialCheckBox(data-id= _id) + + span= title + + li + button.js-email-invite.primary Invite + +template(name='email') + ul#email-setting.setting-detail + li.smtp-form + .title SMTP Host {{currentSetting.mailServer.port}} + .description The address of the SMTP server that handles your emails. + .form-group + input.form-control#mail-server-host(type="text", placeholder="smtp.domain.com" value="{{currentSetting.mailServer.host}}") + li.smtp-form + .title SMTP Port + .description The port your SMTP server uses for outgoing emails. + .form-group + input.form-control#mail-server-port(type="text", placeholder="25" value="{{currentSetting.mailServer.port}}") + li.smtp-form + .title SMTP user name + .form-group + input.form-control#mail-server-username(type="text", placeholder="user name" value="{{currentSetting.mailServer.username}}") + li.smtp-form + .title SMTP password + .form-group + input.form-control#mail-server-password(type="text", placeholder="password" value="{{currentSetting.mailServer.password}}") + li.smtp-form + .title From + .Email address you want to use to send emails. + .form-group + input.form-control#mail-server-from(type="email", placeholder="no-reply@domain.com" value="{{currentSetting.mailServer.from}}") + + li + button.js-save.primary Save diff --git a/client/components/settings/settingBody.js b/client/components/settings/settingBody.js new file mode 100644 index 00000000..047bbd1c --- /dev/null +++ b/client/components/settings/settingBody.js @@ -0,0 +1,126 @@ +Meteor.subscribe('setting'); +Meteor.subscribe('mailServer'); + +BlazeComponent.extendComponent({ + onCreated() { + this.error = new ReactiveVar(''); + this.loading = new ReactiveVar(false); + this.generalSetting = new ReactiveVar(true); + this.emailSetting = new ReactiveVar(false); + }, + + setError(error) { + this.error.set(error); + }, + + setLoading(w) { + this.loading.set(w); + }, + + checkField(selector) { + const value = $(selector).val(); + if(!value || value.trim() === ''){ + $(selector).parents('li.smtp-form').addClass('has-error'); + throw Error('blank field'); + } else { + return value; + } + }, + + currentSetting(){ + return Settings.findOne(); + }, + + boards() { + return Boards.find({ + archived: false, + 'members.userId': Meteor.userId(), + 'members.isAdmin': true, + }, { + sort: ['title'], + }); + }, + toggleStrictMode(){ + this.setLoading(true); + const isStrictMode = this.currentSetting().strict; + Settings.update(Settings.findOne()._id, {$set:{strict: !isStrictMode}}); + this.setLoading(false); + if(isStrictMode){ + $('.invite-people').slideUp(); + }else{ + $('.invite-people').slideDown(); + } + }, + + switchMenu(event){ + const target = $(event.target); + if(!target.hasClass('active')){ + $('.side-menu li.active').removeClass('active'); + target.parent().addClass('active'); + const targetID = target.data('id'); + this.generalSetting.set('general-setting' === targetID); + this.emailSetting.set('email-setting' === targetID); + } + }, + + checkBoard(event){ + let target = $(event.target); + if(!target.hasClass('js-toggle-board-choose')){ + target = target.parent(); + } + const checkboxId = target.attr('id'); + $(`#${checkboxId} .materialCheckBox`).toggleClass('is-checked'); + $(`#${checkboxId}`).toggleClass('is-checked'); + }, + + inviteThroughEmail(){ + this.setLoading(true); + const emails = $('#email-to-invite').val().trim().split('\n').join(',').split(','); + const boardsToInvite = []; + $('.js-toggle-board-choose .materialCheckBox.is-checked').each(function () { + boardsToInvite.push($(this).data('id')); + }); + const validEmails = []; + emails.forEach((email) => { + if (email && SimpleSchema.RegEx.Email.test(email.trim())) { + validEmails.push(email.trim()); + } + }); + Meteor.call('sendInvitation', validEmails, boardsToInvite, () => { + // if (!err) { + // TODO - show more info to user + // } + this.setLoading(false); + }); + }, + + saveMailServerInfo(){ + this.setLoading(true); + $('li').removeClass('has-error'); + + try{ + const host = this.checkField('#mail-server-host'); + const port = this.checkField('#mail-server-port'); + const username = this.checkField('#mail-server-username'); + const password = this.checkField('#mail-server-password'); + const from = this.checkField('#mail-server-from'); + Settings.update(Settings.findOne()._id, {$set:{'mailServer.host':host, 'mailServer.port': port, 'mailServer.username': username, + 'mailServer.password': password, 'mailServer.from': from}}); + } catch (e) { + return; + } finally { + this.setLoading(false); + } + + }, + + events(){ + return [{ + 'click a.js-toggle-strict-mode': this.toggleStrictMode, + 'click a.js-setting-menu': this.switchMenu, + 'click a.js-toggle-board-choose': this.checkBoard, + 'click button.js-email-invite': this.inviteThroughEmail, + 'click button.js-save': this.saveMailServerInfo, + }]; + }, +}).register('setting'); diff --git a/client/components/settings/settingBody.styl b/client/components/settings/settingBody.styl new file mode 100644 index 00000000..118d364c --- /dev/null +++ b/client/components/settings/settingBody.styl @@ -0,0 +1,112 @@ +.flex + display: -webkit-box + display: -moz-box + display: -webkit-flex + display: -moz-flex + display: -ms-flexbox + display: flex + +.setting-content + padding 30px + color: #727479 + background: #dedede + width 100% + height 100% + position: absolute; + + .content-title + font-size 20px + + .content-body + display flex + padding-top 15px + height 100% + + .side-menu + background-color: #f7f7f7; + border: 1px solid #f0f0f0; + border-radius: 4px; + width: 250px; + box-shadow: inset -1px -1px 3px rgba(0,0,0,.05); + + ul + + li + margin: 0.1rem 0.2rem; + + &.active + background #fff + box-shadow 0 1px 2px rgba(0,0,0,0.15); + + &:hover + background #fff + box-shadow 0 1px 2px rgba(0,0,0,0.15); + a + @extends .flex + padding: 1rem 0 1rem 1rem + width: 100% - 5rem + + + span + font-size: 13px + + .main-body + padding: 0.1em 1em + + ul + li + padding: 0.5rem 0.5rem; + + a + .is-checked + border-bottom: 2px solid #2980b9; + border-right: 2px solid #2980b9; + + span + padding: 0 0.5rem + + .invite-people + padding-left 20px; + li + min-width: 500px; + + ul.no-margin-bottom + margin-bottom: 0; + + .bg-white + a + background #f7f7f7 + &.is-checked + background #fff + + +.option + @extends .flex + -webkit-border-radius: 3px; + border-radius: 3px; + background: #fff; + text-decoration: none; + -webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.2); + box-shadow: 0 1px 2px rgba(0,0,0,0.2); + margin-top: 5px; + padding: 5px; + +.title + font-weight 700; + margin-bottom 0.5rem; +.description + margin-bottom 0.5rem; +.bg-white + background #f9fbfc; + +.form-control.has-error + border-color: #a94442; + box-shadow: inset 0 1px 1px rgba(0,0,0,.075); + +li.has-error + color #a94442 + .form-group + .form-control + border-color: #a94442; + box-shadow: inset 0 1px 1px rgba(0,0,0,.075); + diff --git a/client/components/settings/settingHeader.jade b/client/components/settings/settingHeader.jade new file mode 100644 index 00000000..01873eae --- /dev/null +++ b/client/components/settings/settingHeader.jade @@ -0,0 +1,21 @@ +template(name="settingHeaderBar") + h1.header-setting-menu + span {{_ 'admin-panel'}} + + .setting-header-btns.left + unless isMiniScreen + unless isSandstorm + if currentUser + a.setting-header-btn.settings.active + i.fa(class="fa-cog") + span {{_ 'option-setting'}} +//TODO +// a.setting-header-btn.people +// i.fa(class="fa-users") +// span {{_ 'option-people'}} + + else + a.setting-header-btn.js-log-in( + title="{{_ 'log-in'}}") + i.fa.fa-sign-in + span {{_ 'log-in'}} diff --git a/client/components/settings/settingHeader.styl b/client/components/settings/settingHeader.styl new file mode 100644 index 00000000..995ed26d --- /dev/null +++ b/client/components/settings/settingHeader.styl @@ -0,0 +1,25 @@ +#header #header-main-bar .setting-header-btn + &.active, + &:hover:not(.is-disabled) + background: rgba(0, 0, 0, .15) + color: darken(white, 5%) + margin-left: 20px; + padding-right: 10px; + height: 28px; + font-size: 13px; + float: left; + overflow: hidden; + line-height: @height; + margin: 0 2px; + + i.fa + float: left + display: block + line-height: 28px + color: darken(white, 5%) + margin: 0 10px + + + span + display: inline-block + margin-top: 1px + margin-right: 10px \ No newline at end of file diff --git a/client/components/users/userHeader.jade b/client/components/users/userHeader.jade index ad41e8aa..51b0888b 100644 --- a/client/components/users/userHeader.jade +++ b/client/components/users/userHeader.jade @@ -17,6 +17,8 @@ template(name="memberMenuPopup") li: a.js-change-password {{_ 'changePasswordPopup-title'}} li: a.js-change-language {{_ 'changeLanguagePopup-title'}} li: a.js-edit-notification {{_ 'editNotificationPopup-title'}} + if currentUser.isAdmin + li: a.js-go-setting(href='/setting') {{_ 'admin-panel'}} hr ul.pop-over-list li: a.js-logout {{_ 'log-out'}} diff --git a/client/components/users/userHeader.js b/client/components/users/userHeader.js index 98053ed1..73a11fc0 100644 --- a/client/components/users/userHeader.js +++ b/client/components/users/userHeader.js @@ -15,6 +15,9 @@ Template.memberMenuPopup.events({ AccountsTemplates.logout(); }, + 'click .js-go-setting'() { + Popup.close(); + }, }); Template.editProfilePopup.events({ -- cgit v1.2.3-1-g7c22