From dd3d91c67e6b4194b72e7fddd3aeb29f9b61a502 Mon Sep 17 00:00:00 2001 From: Nithin David Thomas Date: Fri, 18 Dec 2020 01:19:44 +0530 Subject: [PATCH 01/58] feat: Add link for "intitated from" in sidebar (#1523) --- .../routes/dashboard/conversation/ContactDetailsItem.vue | 4 +++- .../routes/dashboard/conversation/ContactPanel.vue | 6 +++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/javascript/dashboard/routes/dashboard/conversation/ContactDetailsItem.vue b/app/javascript/dashboard/routes/dashboard/conversation/ContactDetailsItem.vue index 75bf0c018..401c025bf 100644 --- a/app/javascript/dashboard/routes/dashboard/conversation/ContactDetailsItem.vue +++ b/app/javascript/dashboard/routes/dashboard/conversation/ContactDetailsItem.vue @@ -10,7 +10,9 @@
- {{ value }} + + {{ value }} +
diff --git a/app/javascript/dashboard/routes/dashboard/conversation/ContactPanel.vue b/app/javascript/dashboard/routes/dashboard/conversation/ContactPanel.vue index 32d703a1e..b0e216ee3 100644 --- a/app/javascript/dashboard/routes/dashboard/conversation/ContactPanel.vue +++ b/app/javascript/dashboard/routes/dashboard/conversation/ContactPanel.vue @@ -34,7 +34,11 @@ :title="$t('CONTACT_PANEL.INITIATED_FROM')" :value="referer" icon="ion-link" - /> + > + + {{ referer }} + + Date: Thu, 17 Dec 2020 23:12:14 -0800 Subject: [PATCH 02/58] chore: Fix translation link in readme (#1525) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a27754a70..b5c0fc2be 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ Detailed documentation is available at [www.chatwoot.com/help-center](https://ww ### Translation process -The translation process for Chatwoot web and mobile app is managed at [https://translate.chatwoot.com](https://translate.chatwoot.com) using Crowdin. Please read the [translation guide](https://www.chatwoot/docs/contributing/translating-chatwoot-to-your-language) for contributing to Chatwoot. +The translation process for Chatwoot web and mobile app is managed at [https://translate.chatwoot.com](https://translate.chatwoot.com) using Crowdin. Please read the [translation guide](https://www.chatwoot.com/docs/contributing/translating-chatwoot-to-your-language) for contributing to Chatwoot. --- From 8e2b4acc43d8f1108d90711a9f818c4bcd1365a1 Mon Sep 17 00:00:00 2001 From: Pranav Raj S Date: Sat, 19 Dec 2020 18:11:43 +0530 Subject: [PATCH 03/58] chore: Remove account.destroy listener (#1530) --- app/builders/account_builder.rb | 1 - .../installation_webhook_listener.rb | 18 ++++++++++------ app/models/account.rb | 5 ----- lib/events/types.rb | 1 - .../installation_webhook_listener_spec.rb | 21 +------------------ 5 files changed, 13 insertions(+), 33 deletions(-) diff --git a/app/builders/account_builder.rb b/app/builders/account_builder.rb index 3d81a8e68..31d0e1aba 100644 --- a/app/builders/account_builder.rb +++ b/app/builders/account_builder.rb @@ -15,7 +15,6 @@ class AccountBuilder end [@user, @account] rescue StandardError => e - @account&.destroy puts e.inspect raise e end diff --git a/app/listeners/installation_webhook_listener.rb b/app/listeners/installation_webhook_listener.rb index d45a3ef3b..b523369e6 100644 --- a/app/listeners/installation_webhook_listener.rb +++ b/app/listeners/installation_webhook_listener.rb @@ -1,16 +1,22 @@ class InstallationWebhookListener < BaseListener def account_created(event) - payload = event.data[:account].webhook_data.merge(event: __method__.to_s) - deliver_webhook_payloads(payload) - end - - def account_destroyed(event) - payload = event.data[:account].webhook_data.merge(event: __method__.to_s) + payload = account(event).webhook_data.merge( + event: __method__.to_s, + users: users(event) + ) deliver_webhook_payloads(payload) end private + def account(event) + event.data[:account] + end + + def users(event) + account(event).administrators.map(&:webhook_data) + end + def deliver_webhook_payloads(payload) # Deliver the installation event webhook_url = InstallationConfig.find_by(name: 'INSTALLATION_EVENTS_WEBHOOK_URL')&.value diff --git a/app/models/account.rb b/app/models/account.rb index 9b94194bd..36acd1e75 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -60,7 +60,6 @@ class Account < ApplicationRecord enum locale: LANGUAGES_CONFIG.map { |key, val| [val[:iso_639_1_code], key] }.to_h after_create_commit :notify_creation - after_destroy :notify_deletion def agents users.where(account_users: { role: :agent }) @@ -92,8 +91,4 @@ class Account < ApplicationRecord def notify_creation Rails.configuration.dispatcher.dispatch(ACCOUNT_CREATED, Time.zone.now, account: self) end - - def notify_deletion - Rails.configuration.dispatcher.dispatch(ACCOUNT_DESTROYED, Time.zone.now, account: self) - end end diff --git a/lib/events/types.rb b/lib/events/types.rb index 6416cce1f..d1bc0885b 100644 --- a/lib/events/types.rb +++ b/lib/events/types.rb @@ -4,7 +4,6 @@ module Events::Types ### Installation Events ### # account events ACCOUNT_CREATED = 'account.created' - ACCOUNT_DESTROYED = 'account.destroyed' #### Account Events ### # channel events diff --git a/spec/listeners/installation_webhook_listener_spec.rb b/spec/listeners/installation_webhook_listener_spec.rb index 534553c28..e77ce91e5 100644 --- a/spec/listeners/installation_webhook_listener_spec.rb +++ b/spec/listeners/installation_webhook_listener_spec.rb @@ -17,28 +17,9 @@ describe InstallationWebhookListener do context 'when installation config is configured' do it 'triggers webhook' do create(:installation_config, name: 'INSTALLATION_EVENTS_WEBHOOK_URL', value: 'https://test.com') - expect(WebhookJob).to receive(:perform_later).with('https://test.com', account.webhook_data.merge(event: 'account_created')).once + expect(WebhookJob).to receive(:perform_later).with('https://test.com', account.webhook_data.merge(event: 'account_created', users: [])).once listener.account_created(event) end end end - - describe '#account_destroyed' do - let(:event_name) { :'account.destroyed' } - - context 'when installation config is not configured' do - it 'does not trigger webhook' do - expect(WebhookJob).to receive(:perform_later).exactly(0).times - listener.account_destroyed(event) - end - end - - context 'when installation config is configured' do - it 'triggers webhook' do - create(:installation_config, name: 'INSTALLATION_EVENTS_WEBHOOK_URL', value: 'https://test.com') - expect(WebhookJob).to receive(:perform_later).with('https://test.com', account.webhook_data.merge(event: 'account_destroyed')).once - listener.account_destroyed(event) - end - end - end end From f3f2542baee8486b6af3aaa3177bd09ba6cc6953 Mon Sep 17 00:00:00 2001 From: Muhsin Keloth Date: Sat, 19 Dec 2020 22:21:20 -0800 Subject: [PATCH 04/58] fix: Update agent select placeholder translation (#1533) --- .../dashboard/routes/dashboard/settings/inbox/AddAgents.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/javascript/dashboard/routes/dashboard/settings/inbox/AddAgents.vue b/app/javascript/dashboard/routes/dashboard/settings/inbox/AddAgents.vue index 18888d008..3a8c93350 100644 --- a/app/javascript/dashboard/routes/dashboard/settings/inbox/AddAgents.vue +++ b/app/javascript/dashboard/routes/dashboard/settings/inbox/AddAgents.vue @@ -23,7 +23,7 @@ selected-label :select-label="$t('FORMS.MULTISELECT.ENTER_TO_SELECT')" :deselect-label="$t('FORMS.MULTISELECT.ENTER_TO_REMOVE')" - :placeholder="$t('INBOX_MGMT.ADD.AGENTS.PICK_AGENTS ')" + :placeholder="$t('INBOX_MGMT.ADD.AGENTS.PICK_AGENTS')" @select="$v.selectedAgents.$touch" > From 796e376fa7c3f28087ab99a5bb93fd490cd2efa0 Mon Sep 17 00:00:00 2001 From: Muhsin Keloth Date: Sat, 19 Dec 2020 22:22:40 -0800 Subject: [PATCH 05/58] feat: Add smart app banner in website for iOS (#1531) --- .env.example | 6 ++++++ app/views/layouts/vueapp.html.erb | 3 +++ 2 files changed, 9 insertions(+) diff --git a/.env.example b/.env.example index 4fe8ec3c8..eeb61f00f 100644 --- a/.env.example +++ b/.env.example @@ -110,6 +110,12 @@ SLACK_CLIENT_SECRET= ## Mobile app env variables IOS_APP_ID=6C953F3RX2.com.chatwoot.app + +### Smart App Banner +# https://developer.apple.com/library/archive/documentation/AppleApplications/Reference/SafariWebContent/PromotingAppswithAppBanners/PromotingAppswithAppBanners.html +# You can find your app-id in https://itunesconnect.apple.com +#IOS_APP_IDENTIFIER=1495796682 + ## Push Notification ## generate a new key value here : https://d3v.one/vapid-key-generator/ # VAPID_PUBLIC_KEY= diff --git a/app/views/layouts/vueapp.html.erb b/app/views/layouts/vueapp.html.erb index 40d9b7a1b..dfe100726 100644 --- a/app/views/layouts/vueapp.html.erb +++ b/app/views/layouts/vueapp.html.erb @@ -10,6 +10,9 @@ + <% if ENV['IOS_APP_IDENTIFIER'].present? %> + '> + <% end %> From 9d3dda9a6136a1b73eb70cb6e81c07cacd84fb1d Mon Sep 17 00:00:00 2001 From: Pranav Raj S Date: Mon, 21 Dec 2020 14:05:19 +0530 Subject: [PATCH 06/58] feat: Add full name to the user signup form (#1534) --- app/builders/account_builder.rb | 9 +- app/controllers/api/v1/accounts_controller.rb | 3 +- app/javascript/dashboard/api/auth.js | 3 +- .../dashboard/assets/scss/_woot.scss | 1 - .../dashboard/assets/scss/views/_signup.scss | 94 -------- .../dashboard/assets/scss/widgets/_forms.scss | 5 +- .../components/widgets/forms/Input.vue | 11 + .../dashboard/i18n/locale/en/signup.json | 25 +- .../dashboard/routes/auth/Signup.vue | 216 ++++++++++-------- .../api/v1/accounts_controller_spec.rb | 15 +- 10 files changed, 163 insertions(+), 219 deletions(-) delete mode 100644 app/javascript/dashboard/assets/scss/views/_signup.scss diff --git a/app/builders/account_builder.rb b/app/builders/account_builder.rb index 31d0e1aba..807f499e1 100644 --- a/app/builders/account_builder.rb +++ b/app/builders/account_builder.rb @@ -2,7 +2,7 @@ class AccountBuilder include CustomExceptions::Account - pattr_initialize [:account_name!, :email!, :confirmed!, :user] + pattr_initialize [:account_name!, :email!, :confirmed!, :user, :user_full_name] def perform if @user.nil? @@ -60,18 +60,13 @@ class AccountBuilder ) end - def email_to_name(email) - name = email[/[^@]+/] - name.split('.').map(&:capitalize).join(' ') - end - def create_user password = SecureRandom.alphanumeric(12) @user = User.new(email: @email, password: password, password_confirmation: password, - name: email_to_name(@email)) + name: @user_full_name) @user.confirm if @confirmed @user.save! end diff --git a/app/controllers/api/v1/accounts_controller.rb b/app/controllers/api/v1/accounts_controller.rb index 51dcb1a57..548f86175 100644 --- a/app/controllers/api/v1/accounts_controller.rb +++ b/app/controllers/api/v1/accounts_controller.rb @@ -16,6 +16,7 @@ class Api::V1::AccountsController < Api::BaseController def create @user, @account = AccountBuilder.new( account_name: account_params[:account_name], + user_full_name: account_params[:user_full_name], email: account_params[:email], confirmed: confirmed?, user: current_user @@ -54,7 +55,7 @@ class Api::V1::AccountsController < Api::BaseController end def account_params - params.permit(:account_name, :email, :name, :locale, :domain, :support_email, :auto_resolve_duration) + params.permit(:account_name, :email, :name, :locale, :domain, :support_email, :auto_resolve_duration, :user_full_name) end def check_signup_enabled diff --git a/app/javascript/dashboard/api/auth.js b/app/javascript/dashboard/api/auth.js index 1a16108ca..46379ab1e 100644 --- a/app/javascript/dashboard/api/auth.js +++ b/app/javascript/dashboard/api/auth.js @@ -26,7 +26,8 @@ export default { const fetchPromise = new Promise((resolve, reject) => { axios .post(urlData.url, { - account_name: creds.name, + account_name: creds.accountName.trim(), + user_full_name: creds.fullName.trim(), email: creds.email, }) .then(response => { diff --git a/app/javascript/dashboard/assets/scss/_woot.scss b/app/javascript/dashboard/assets/scss/_woot.scss index 7f9041b93..1877895bc 100644 --- a/app/javascript/dashboard/assets/scss/_woot.scss +++ b/app/javascript/dashboard/assets/scss/_woot.scss @@ -23,7 +23,6 @@ @import 'views/settings/inbox'; @import 'views/settings/channel'; @import 'views/settings/integrations'; -@import 'views/signup'; @import 'plugins/multiselect'; @import 'plugins/dropdown'; diff --git a/app/javascript/dashboard/assets/scss/views/_signup.scss b/app/javascript/dashboard/assets/scss/views/_signup.scss deleted file mode 100644 index 5233e3de0..000000000 --- a/app/javascript/dashboard/assets/scss/views/_signup.scss +++ /dev/null @@ -1,94 +0,0 @@ -.signup { - // margin-top: $space-larger*1.2; - - .signup--hero { - margin-bottom: $space-larger * 1.5; - - .hero--logo { - width: 180px; - } - - .hero--title { - margin-top: $space-large; - font-weight: $font-weight-light; - } - - .hero--sub { - font-size: $font-size-medium; - color: $medium-gray; - } - } - - .signup--features { - list-style-type: none; - font-size: $font-size-medium; - - > li { - padding: $space-slab; - - > i { - margin-right: $space-two; - font-size: $font-size-large; - - &.beer { - color: #dfb63b; - } - - &.report { - color: #2196f3; - } - - &.canned { - color: #1cad22; - } - - &.uptime { - color: #a753b5; - } - - &.secure { - color: #607d8b; - } - } - } - } - - .signup--box { - @include elegant-card; - padding: $space-large; - - label { - font-size: $font-size-default; - color: $color-gray; - - input { - padding: $space-slab; - height: $space-larger; - font-size: $font-size-default; - } - - .error { - font-size: $font-size-small - } - } - } - - .sigin--footer { - padding: $space-medium; - font-size: $font-size-default; - - > a { - font-weight: $font-weight-bold; - } - } - - .accept--terms { - font-size: $font-size-mini; - text-align: center; - @include margin($zero); - - a { - font-size: $font-size-mini; - } - } -} diff --git a/app/javascript/dashboard/assets/scss/widgets/_forms.scss b/app/javascript/dashboard/assets/scss/widgets/_forms.scss index d824f9d48..231f4c535 100644 --- a/app/javascript/dashboard/assets/scss/widgets/_forms.scss +++ b/app/javascript/dashboard/assets/scss/widgets/_forms.scss @@ -2,12 +2,13 @@ #{$all-text-inputs}, select, .multiselect > .multiselect__tags { - @include thin-border(darken(get-color(alert), 25%)); + @include thin-border(var(--r-400)); } .message { - color: darken(get-color(alert), 25%); + color: var(--r-400); display: block; + font-size: var(--font-size-small); font-weight: $font-weight-normal; margin-bottom: $space-one; margin-top: -$space-normal; diff --git a/app/javascript/dashboard/components/widgets/forms/Input.vue b/app/javascript/dashboard/components/widgets/forms/Input.vue index db8dcb130..7322cda77 100644 --- a/app/javascript/dashboard/components/widgets/forms/Input.vue +++ b/app/javascript/dashboard/components/widgets/forms/Input.vue @@ -6,8 +6,12 @@ :type="type" :placeholder="placeholder" @input="onChange" + @blur="onBlur" />

+ + {{ error }} + @@ -34,11 +38,18 @@ export default { type: String, default: '', }, + error: { + type: String, + default: '', + }, }, methods: { onChange(e) { this.$emit('input', e.target.value); }, + onBlur(e) { + this.$emit('blur', e.target.value); + }, }, }; diff --git a/app/javascript/dashboard/i18n/locale/en/signup.json b/app/javascript/dashboard/i18n/locale/en/signup.json index 08366a1e3..6eaa5d646 100644 --- a/app/javascript/dashboard/i18n/locale/en/signup.json +++ b/app/javascript/dashboard/i18n/locale/en/signup.json @@ -4,14 +4,19 @@ "TITLE": "Register", "TERMS_ACCEPT": "By signing up, you agree to our T & C and Privacy policy", "ACCOUNT_NAME": { - "LABEL": "Account Name", - "PLACEHOLDER": "Wayne Enterprises", - "ERROR": "Account Name is too short" + "LABEL": "Account name", + "PLACEHOLDER": "Enter an account name. eg: Wayne Enterprises", + "ERROR": "Account name is too short" + }, + "FULL_NAME": { + "LABEL": "Full name", + "PLACEHOLDER": "Enter your full name. eg: Bruce Wayne", + "ERROR": "Full name is too short" }, "EMAIL": { - "LABEL": "Email", - "PLACEHOLDER": "bruce@wayne.enterprises", - "ERROR": "Email is invalid" + "LABEL": "Work email", + "PLACEHOLDER": "Enter your work email address. eg: bruce@wayne.enterprises", + "ERROR": "Email address is invalid" }, "PASSWORD": { "LABEL": "Password", @@ -28,12 +33,6 @@ "ERROR_MESSAGE": "Could not connect to Woot Server, Please try again later" }, "SUBMIT": "Submit", - "FEATURES": { - "UNLIMITED_INBOXES": "Unlimited inboxes", - "ROBUST_REPORTING": "Robust Reporting", - "CANNED_RESPONSES": "Canned Responses", - "AUTO_ASSIGNMENT": "Auto Assignment", - "SECURITY": "Enterprise level security" - } + "HAVE_AN_ACCOUNT": "Already have an account?" } } diff --git a/app/javascript/dashboard/routes/auth/Signup.vue b/app/javascript/dashboard/routes/auth/Signup.vue index 1c3835596..ed6743c62 100644 --- a/app/javascript/dashboard/routes/auth/Signup.vue +++ b/app/javascript/dashboard/routes/auth/Signup.vue @@ -11,73 +11,54 @@
-
- -
-
-