Merge branch 'develop' into unread-zindex

pull/9514/head
Guilherme Gazzo 7 years ago committed by GitHub
commit d57f947d44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 16
      packages/rocketchat-channel-settings-mail-messages/client/views/mailMessagesInstructions.html
  2. 117
      packages/rocketchat-channel-settings-mail-messages/client/views/mailMessagesInstructions.js
  3. 2
      packages/rocketchat-i18n/i18n/en.i18n.json
  4. 3367
      packages/rocketchat-livechat/.app/package-lock.json
  5. 58
      packages/rocketchat-livechat/client/views/app/tabbar/visitorEdit.html
  6. 5
      packages/rocketchat-livechat/client/views/app/tabbar/visitorEdit.js
  7. 3
      packages/rocketchat-livechat/plugin/build.sh
  8. 16
      packages/rocketchat-theme/client/imports/components/contextual-bar.css
  9. 2
      packages/rocketchat-theme/client/imports/general/variables.css
  10. 1
      tests/end-to-end/ui/12-settings.js
  11. 1
      tests/pageobjects/flex-tab.page.js

@ -36,11 +36,9 @@
</div> </div>
{{#with config}} {{#with config}}
{{#if autocomplete 'isShowing'}} {{#if autocomplete 'isShowing'}}
<div class="fadeInDown"> {{#if autocomplete 'isLoaded'}}
{{#if autocomplete 'isLoaded'}} {{> popupList data=config items=items}}
{{> popupList data=config items=items}} {{/if}}
{{/if}}
</div>
{{/if}} {{/if}}
{{/with}} {{/with}}
</label> </label>
@ -72,6 +70,14 @@
</div> </div>
</label> </label>
</div> </div>
{{#if errorMessage}}
<div class="mail-messages__instructions mail-messages__instructions--warning">
<div class="mail-messages__instructions-wrapper">
<div class="mail-messages__instructions-text">{{errorMessage}}</div>
</div>
</div>
{{/if}}
</main> </main>
<div class="rc-user-info__flex rc-user-info__row"> <div class="rc-user-info__flex rc-user-info__row">
<button class="rc-button rc-button--outline js-cancel" title="{{_ 'Cancel'}}">{{_ 'Cancel'}}</button> <button class="rc-button rc-button--outline js-cancel" title="{{_ 'Cancel'}}">{{_ 'Cancel'}}</button>

@ -1,6 +1,4 @@
/* global AutoComplete Deps */ /* global AutoComplete Deps */
import _ from 'underscore';
import toastr from 'toastr'; import toastr from 'toastr';
import resetSelection from '../resetSelection'; import resetSelection from '../resetSelection';
@ -102,6 +100,9 @@ Template.mailMessagesInstructions.helpers({
}, },
items() { items() {
return Template.instance().ac.filteredList(); return Template.instance().ac.filteredList();
},
errorMessage() {
return Template.instance().errorMessage.get();
} }
}); });
@ -109,83 +110,52 @@ Template.mailMessagesInstructions.events({
'click .js-cancel, click .mail-messages__instructions--selected'(e, t) { 'click .js-cancel, click .mail-messages__instructions--selected'(e, t) {
t.reset(true); t.reset(true);
}, },
'click .js-send'(e, t) { 'click .js-send'(e, instance) {
t.$('.error').hide(); const selectedUsers = instance.selectedUsers;
const $btn = t.$('button.send'); const selectedEmails = instance.selectedEmails;
const oldBtnValue = $btn.html(); const $emailsInput = instance.$('[name="emails"]');
$btn.html(TAPi18n.__('Sending')); const selectedMessages = instance.selectedMessages;
const selectedMessages = $('.messages-box .message.selected'); const subject = instance.$('[name="subject"]').val();
let error = false;
if (selectedMessages.length === 0) { if (!selectedUsers.get().length && !selectedEmails.get().length && $emailsInput.val().trim() === '') {
t.$('.error-select').show(); instance.errorMessage.set(t('Mail_Message_Missing_to'));
error = true; return false;
} }
if (t.$('input[name=to_emails]').val().trim()) {
const rfcMailPatternWithName = /^(?:.*<)?([a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*)(?:>?)$/; if ($emailsInput.val() !== '') {
const emails = t.$('input[name=to_emails]').val().trim().split(','); if (isEmail($emailsInput.val())) {
const erroredEmails = []; const emailsArr = selectedEmails.get();
emails.forEach((email) => { emailsArr.push({text: $emailsInput.val()});
if (!rfcMailPatternWithName.test(email.trim())) { $('[name="emails"]').val('');
erroredEmails.push(email.trim()); selectedEmails.set(emailsArr);
} } else {
}); instance.errorMessage.set(t('Mail_Message_Invalid_emails', $emailsInput.val()));
t.erroredEmails.set(erroredEmails); return false;
if (erroredEmails.length > 0) {
t.$('.error-invalid-emails').show();
error = true;
} }
} else if (!t.selectedUsers.get().length) {
t.$('.error-missing-to').show();
error = true;
} }
if (error) {
return $btn.html(oldBtnValue); if (!selectedMessages.get().length) {
instance.errorMessage.set(t('Mail_Message_No_messages_selected_select_all'));
return false;
} }
const data = { const data = {
rid: Session.get('openedRoom'), rid: Session.get('openedRoom'),
to_users: t.selectedUsers.get(), to_users: selectedUsers.get().map(user => user.username),
to_emails: t.$('input[name=to_emails]').val().trim(), to_emails: selectedEmails.get().map(email => email.text).toString(),
subject: t.$('input[name=subject]').val().trim(), subject,
messages: selectedMessages.map(function(i, message) { messages: selectedMessages.get(),
return message.id;
}).toArray(),
language: localStorage.getItem('userLanguage') language: localStorage.getItem('userLanguage')
}; };
return Meteor.call('mailMessages', data, function(err, result) {
$btn.html(oldBtnValue); Meteor.call('mailMessages', data, function(err, result) {
if (err != null) { if (err != null) {
return handleError(err); return handleError(err);
} }
console.log(result); console.log(result);
toastr.success(TAPi18n.__('Your_email_has_been_queued_for_sending')); toastr.success(t('Your_email_has_been_queued_for_sending'));
return t.reset(); instance.reset(true);
});
},
'click .select-all'(e, t) {
t.$('.error-select').hide();
const view = Blaze.getView($('.messages-box')[0]);
if (view != null) {
if (typeof view.templateInstance === 'function') {
const chat = ChatMessage.find({
rid: Session.get('openedRoom')
});
view.templateInstance().selectedMessages = _.pluck(chat && chat.fetch(), '_id');
}
}
return $('.messages-box .message').addClass('selected');
},
'autocompleteselect #to_users'(event, instance, doc) {
instance.selectedUsers.set(instance.selectedUsers.get().concat(doc.username));
event.currentTarget.value = '';
return event.currentTarget.focus();
},
'click .remove-to-user'() {
let users = Template.instance().selectedUsers.get();
users = _.reject(Template.instance().selectedUsers.get(), (_id) => {
return _id === this.valueOf();
}); });
Template.instance().selectedUsers.set(users);
return $('#to_users').focus();
}, },
'click .rc-input--usernames .rc-tags__tag'({target}, t) { 'click .rc-input--usernames .rc-tags__tag'({target}, t) {
const {username} = Blaze.getData(target); const {username} = Blaze.getData(target);
@ -271,13 +241,12 @@ Template.mailMessagesInstructions.onRendered(function() {
$('.messages-box .message').on('click', function() { $('.messages-box .message').on('click', function() {
const id = this.id; const id = this.id;
const timestamp = this.dataset.timestamp;
const messages = selectedMessages.get(); const messages = selectedMessages.get();
if ($(this).hasClass('selected')) { if ($(this).hasClass('selected')) {
selectedMessages.set(messages.filter(message => message.id !== id)); selectedMessages.set(messages.filter(message => message !== id));
} else { } else {
selectedMessages.set(messages.concat({id, timestamp})); selectedMessages.set(messages.concat(id));
} }
}); });
}); });
@ -285,6 +254,9 @@ Template.mailMessagesInstructions.onRendered(function() {
Template.mailMessagesInstructions.onCreated(function() { Template.mailMessagesInstructions.onCreated(function() {
resetSelection(true); resetSelection(true);
this.selectedEmails = new ReactiveVar([]);
this.selectedMessages = new ReactiveVar([]);
this.errorMessage = new ReactiveVar('');
this.selectedUsers = new ReactiveVar([]); this.selectedUsers = new ReactiveVar([]);
this.userFilter = new ReactiveVar(''); this.userFilter = new ReactiveVar('');
@ -318,18 +290,13 @@ Template.mailMessagesInstructions.onCreated(function() {
] ]
}); });
this.ac.tmplInst = this; this.ac.tmplInst = this;
this.selectedEmails = new ReactiveVar([]);
this.selectedMessages = new ReactiveVar([]);
this.autoCompleteCollection = new Mongo.Collection(null);
this.erroredEmails = new ReactiveVar([]);
this.reset = (bool) => { this.reset = (bool) => {
this.selectedUsers.set([]); this.selectedUsers.set([]);
this.selectedEmails.set([]); this.selectedEmails.set([]);
this.selectedMessages.set([]); this.selectedMessages.set([]);
this.errorMessage.set('');
resetSelection(bool); resetSelection(bool);
}; };
}); });

@ -1154,7 +1154,7 @@
"mail-messages_description": "Permission to use the mail messages option", "mail-messages_description": "Permission to use the mail messages option",
"Mail_Message_Invalid_emails": "You have provided one or more invalid emails: %s", "Mail_Message_Invalid_emails": "You have provided one or more invalid emails: %s",
"Mail_Message_Missing_to": "You must select one or more users or provide one or more email addresses, separated by commas.", "Mail_Message_Missing_to": "You must select one or more users or provide one or more email addresses, separated by commas.",
"Mail_Message_No_messages_selected_select_all": "You haven't selected any messages. Would you like to <a href='#' class='select-all'>select all</a> visible messages?", "Mail_Message_No_messages_selected_select_all": "You haven't selected any messages",
"Mail_Messages": "Mail Messages", "Mail_Messages": "Mail Messages",
"Mail_Messages_Instructions": "Choose which messages you want to send via email by clicking the messages", "Mail_Messages_Instructions": "Choose which messages you want to send via email by clicking the messages",
"Mail_Messages_Subject": "Here's a selected portion of %s messages", "Mail_Messages_Subject": "Here's a selected portion of %s messages",

File diff suppressed because it is too large Load Diff

@ -3,35 +3,55 @@
<form class="edit-form" autocomplete="off"> <form class="edit-form" autocomplete="off">
{{#with visitor}} {{#with visitor}}
<h3>{{username}}</h3> <h3>{{username}}</h3>
<div class="input-line"> <div class="rc-input">
<label for="name">{{_ "Name"}}</label> <label class="rc-input__label">
<input type="text" name="name" autocomplete="off" value="{{name}}"> <div class="rc-input__title">{{_ "Name"}}</div>
<div class="rc-input__wrapper">
<input class="rc-input__element" type="text" name="name" autocomplete="off" value="{{name}}">
</div>
</label>
</div> </div>
<div class="input-line"> <div class="rc-input">
<label for="email">{{_ "Email"}}</label> <label class="rc-input__label">
<input type="email" name="email" autocomplete="off" value="{{email}}"> <div class="rc-input__title">{{_ "Email"}}</div>
<div class="rc-input__wrapper">
<input class="rc-input__element" type="text" name="email" autocomplete="off" value="{{email}}">
</div>
</label>
</div> </div>
<div class="input-line"> <div class="rc-input">
<label for="phone">{{_ "Phone"}}</label> <label class="rc-input__label">
<input type="text" name="phone" autocomplete="off" value="{{phone}}"> <div class="rc-input__title">{{_ "Phone"}}</div>
<div class="rc-input__wrapper">
<input class="rc-input__element" type="text" name="phone" autocomplete="off" value="{{phone}}">
</div>
</label>
</div> </div>
{{/with}} {{/with}}
{{#with room}} {{#with room}}
<h3>{{_ "Conversation" }}</h3> <h3>{{_ "Conversation" }}</h3>
<div class="input-line"> <div class="rc-input">
<label for="topic">{{_ "Topic"}}</label> <label class="rc-input__label">
<input type="text" name="topic" autocomplete="off" value="{{topic}}"> <div class="rc-input__title">{{_ "Topic"}}</div>
<div class="rc-input__wrapper">
<input class="rc-input__element" type="text" name="topic" autocomplete="off" value="{{topic}}">
</div>
</label>
</div> </div>
<div class="input-line"> <div class="rc-input">
<label for="tags">{{_ "Tags"}}</label> <label class="rc-input__label">
<input type="text" name="tags" autocomplete="off" value="{{joinTags}}"> <div class="rc-input__title">{{_ "Tags"}}</div>
<div class="rc-input__wrapper">
<input class="rc-input__element" type="text" name="tags" autocomplete="off" value="{{tags}}">
</div>
</label>
</div> </div>
{{/with}} {{/with}}
<nav> <div class="rc-user-info__flex rc-user-info__row">
<button class='button button-block cancel' type="button"><span>{{_ "Cancel"}}</span></button> <button class='rc-button cancel' type="button"><span>{{_ "Cancel"}}</span></button>
<button class='button button-block primary save'><span>{{_ "Save"}}</span></button> <button class='rc-button rc-button--primary save'><span>{{_ "Save"}}</span></button>
</nav> </div>
</form> </form>
</div> </div>
</template> </template>

@ -1,3 +1,5 @@
/* globals LivechatVisitor */
import toastr from 'toastr'; import toastr from 'toastr';
Template.visitorEdit.helpers({ Template.visitorEdit.helpers({
visitor() { visitor() {
@ -32,7 +34,7 @@ Template.visitorEdit.onCreated(function() {
this.room = new ReactiveVar(); this.room = new ReactiveVar();
this.autorun(() => { this.autorun(() => {
this.visitor.set(Meteor.users.findOne({ _id: Template.currentData().visitorId })); this.visitor.set(LivechatVisitor.findOne({ _id: Template.currentData().visitorId }));
}); });
this.autorun(() => { this.autorun(() => {
@ -42,7 +44,6 @@ Template.visitorEdit.onCreated(function() {
Template.visitorEdit.events({ Template.visitorEdit.events({
'submit form'(event, instance) { 'submit form'(event, instance) {
console.log('this ->', this);
event.preventDefault(); event.preventDefault();
const userData = { _id: instance.visitor.get()._id }; const userData = { _id: instance.visitor.get()._id };
const roomData = { _id: instance.room.get()._id }; const roomData = { _id: instance.room.get()._id };

@ -4,7 +4,8 @@ export BUILD_DIR="../build"
export BUNDLE_DIR="../build/bundle/programs/web.browser" export BUNDLE_DIR="../build/bundle/programs/web.browser"
cd packages/rocketchat-livechat/.app cd packages/rocketchat-livechat/.app
# could remove `npm_config_package-lock` when upgrade to npm 5.6 https://github.com/npm/npm/issues/17858#issuecomment-350736221 # could remove `npm_config_package-lock` and `rm -f package-lock.json` when upgrade to npm 5.6 https://github.com/npm/npm/issues/17858#issuecomment-350736221
rm -f package-lock.json
env npm_config_package-lock=false meteor npm install --production env npm_config_package-lock=false meteor npm install --production
meteor build --headless --directory $BUILD_DIR meteor build --headless --directory $BUILD_DIR

@ -223,8 +223,14 @@
} }
} }
.contextual-bar.mail-messages .rc-input:not(:last-child) { .contextual-bar__content.mail-messages {
margin-bottom: 2rem; & .rc-popup-list {
z-index: 1;
}
& .rc-input:not(:last-child) {
margin-bottom: 2rem;
}
} }
.mail-messages__instructions { .mail-messages__instructions {
@ -245,6 +251,12 @@
cursor: pointer; cursor: pointer;
} }
&--warning {
color: var(--rc-color-alert-message-warning);
border-color: var(--rc-color-alert-message-warning);
background: var(--rc-color-alert-message-warning-background);
}
&-wrapper { &-wrapper {
display: flex; display: flex;
margin: 0 -10px; margin: 0 -10px;

@ -28,6 +28,8 @@
--rc-color-alert-message-primary-background: #f1f6ff; --rc-color-alert-message-primary-background: #f1f6ff;
--rc-color-alert-message-secondary: #7ca52b; --rc-color-alert-message-secondary: #7ca52b;
--rc-color-alert-message-secondary-background: #fafff1; --rc-color-alert-message-secondary-background: #fafff1;
--rc-color-alert-message-warning: #d52d24;
--rc-color-alert-message-warning-background: #fff3f3;
--rc-color-primary: var(--color-dark); --rc-color-primary: var(--color-dark);
--rc-color-primary-darkest: var(--color-darkest); --rc-color-primary-darkest: var(--color-darkest);

@ -488,7 +488,6 @@ describe('[Api Settings Change]', () => {
const userEl = admin.getUserFromList(`setting${ username }`); const userEl = admin.getUserFromList(`setting${ username }`);
userEl.waitForVisible(5000); userEl.waitForVisible(5000);
userEl.click(); userEl.click();
flexTab.userViewTabButton.click();
flexTab.usersView.waitForVisible(5000); flexTab.usersView.waitForVisible(5000);
}); });

@ -98,7 +98,6 @@ class FlexTab extends Page {
get emojiNewAliases() { return browser.element('#aliases'); } get emojiNewAliases() { return browser.element('#aliases'); }
get emojiNewImageInput() { return browser.element('#image'); } get emojiNewImageInput() { return browser.element('#image'); }
get usersView() { return browser.element('.rc-user-info-action'); } get usersView() { return browser.element('.rc-user-info-action'); }
get userViewTabButton() { return browser.element('.tab-button-icon--user'); }
get usersActivate() { return browser.element('.rc-popover__item[data-id=activate]'); } get usersActivate() { return browser.element('.rc-popover__item[data-id=activate]'); }
get usersDeactivate() { return browser.element('.rc-popover__item[data-id=deactivate]'); } get usersDeactivate() { return browser.element('.rc-popover__item[data-id=deactivate]'); }

Loading…
Cancel
Save