diff --git a/.circleci/config.yml b/.circleci/config.yml
index 99795db91..65ceda04c 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -1,6 +1,7 @@
version: 2.1
orbs:
node: circleci/node@6.1.0
+ qlty-orb: qltysh/qlty-orb@0.0
defaults: &defaults
working_directory: ~/build
@@ -89,14 +90,6 @@ jobs:
command: |
source ~/.rvm/scripts/rvm
bundle install
- # pnpm install
-
- - run:
- name: Download cc-test-reporter
- command: |
- mkdir -p ~/tmp
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ~/tmp/cc-test-reporter
- chmod +x ~/tmp/cc-test-reporter
# Swagger verification
- run:
@@ -108,10 +101,11 @@ jobs:
echo "ERROR: The swagger.json file is not in sync with the yaml specification. Run 'rake swagger:build' and commit 'swagger/swagger.json'."
exit 1
fi
+ mkdir -p ~/tmp
curl -L https://repo1.maven.org/maven2/org/openapitools/openapi-generator-cli/6.3.0/openapi-generator-cli-6.3.0.jar > ~/tmp/openapi-generator-cli-6.3.0.jar
java -jar ~/tmp/openapi-generator-cli-6.3.0.jar validate -i swagger/swagger.json
- # we remove the FRONTED_URL from the .env before running the tests
+ # Configure environment and database
- run:
name: Database Setup and Configure Environment Variables
command: |
@@ -149,17 +143,11 @@ jobs:
command: pnpm run eslint
- run:
- name: Run frontend tests
+ name: Run frontend tests (with coverage)
command: |
mkdir -p ~/build/coverage/frontend
- ~/tmp/cc-test-reporter before-build
pnpm run test:coverage
- - run:
- name: Code Climate Test Coverage (Frontend)
- command: |
- ~/tmp/cc-test-reporter format-coverage -t lcov -o "~/build/coverage/frontend/codeclimate.frontend_$CIRCLE_NODE_INDEX.json"
-
# Run backend tests
- run:
name: Run backend tests
@@ -167,18 +155,18 @@ jobs:
mkdir -p ~/tmp/test-results/rspec
mkdir -p ~/tmp/test-artifacts
mkdir -p ~/build/coverage/backend
- ~/tmp/cc-test-reporter before-build
TESTFILES=$(circleci tests glob "spec/**/*_spec.rb" | circleci tests split --split-by=timings)
- bundle exec rspec --format progress \
+ bundle exec rspec -I ./spec --require coverage_helper --require spec_helper --format progress \
--format RspecJunitFormatter \
--out ~/tmp/test-results/rspec.xml \
-- ${TESTFILES}
no_output_timeout: 30m
- - run:
- name: Code Climate Test Coverage (Backend)
- command: |
- ~/tmp/cc-test-reporter format-coverage -t simplecov -o "~/build/coverage/backend/codeclimate.$CIRCLE_NODE_INDEX.json"
+ # Qlty coverage publish
+ - qlty-orb/coverage_publish:
+ files: |
+ coverage/coverage.json
+ coverage/lcov.info
- run:
name: List coverage directory contents
@@ -189,3 +177,7 @@ jobs:
root: ~/build
paths:
- coverage
+
+ - store_artifacts:
+ path: coverage
+ destination: coverage
diff --git a/Gemfile b/Gemfile
index 26d943fa0..927a853a0 100644
--- a/Gemfile
+++ b/Gemfile
@@ -229,6 +229,7 @@ group :test do
gem 'webmock'
# test profiling
gem 'test-prof'
+ gem 'simplecov_json_formatter', require: false
end
group :development, :test do
@@ -253,7 +254,7 @@ group :development, :test do
gem 'rubocop-factory_bot', require: false
gem 'seed_dump'
gem 'shoulda-matchers'
- gem 'simplecov', '0.17.1', require: false
+ gem 'simplecov', '>= 0.21', require: false
gem 'spring'
gem 'spring-watcher-listen'
end
diff --git a/Gemfile.lock b/Gemfile.lock
index b038bbadc..2cce9f322 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -219,7 +219,7 @@ GEM
diff-lcs (1.5.1)
digest-crc (0.6.5)
rake (>= 12.0.0, < 14.0.0)
- docile (1.4.0)
+ docile (1.4.1)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dotenv (3.1.2)
@@ -447,7 +447,7 @@ GEM
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
- json (2.12.0)
+ json (2.13.2)
json_refs (0.1.8)
hana
json_schemer (0.2.24)
@@ -864,11 +864,12 @@ GEM
faraday (>= 0.17.5, < 3.a)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
- simplecov (0.17.1)
+ simplecov (0.22.0)
docile (~> 1.1)
- json (>= 1.8, < 3)
- simplecov-html (~> 0.10.0)
- simplecov-html (0.10.2)
+ simplecov-html (~> 0.11)
+ simplecov_json_formatter (~> 0.1)
+ simplecov-html (0.13.2)
+ simplecov_json_formatter (0.1.4)
slack-ruby-client (2.5.2)
faraday (>= 2.0)
faraday-mashify
@@ -1093,7 +1094,8 @@ DEPENDENCIES
sidekiq (>= 7.3.1)
sidekiq-cron (>= 1.12.0)
sidekiq_alive
- simplecov (= 0.17.1)
+ simplecov (>= 0.21)
+ simplecov_json_formatter
slack-ruby-client (~> 2.5.2)
spring
spring-watcher-listen
diff --git a/app/helpers/portal_helper.rb b/app/helpers/portal_helper.rb
index 3ed303556..e98f0a72d 100644
--- a/app/helpers/portal_helper.rb
+++ b/app/helpers/portal_helper.rb
@@ -74,6 +74,17 @@ module PortalHelper
end
end
+ def generate_portal_brand_url(brand_url, referer)
+ url = URI.parse(brand_url.to_s)
+ query_params = Rack::Utils.parse_query(url.query)
+ query_params['utm_medium'] = 'helpcenter'
+ query_params['utm_campaign'] = 'branding'
+ query_params['utm_source'] = URI.parse(referer).host if referer.present? && referer.match?(URI::DEFAULT_PARSER.make_regexp)
+
+ url.query = query_params.to_query
+ url.to_s
+ end
+
def render_category_content(content)
ChatwootMarkdownRenderer.new(content).render_markdown_to_plain_text
end
diff --git a/app/javascript/dashboard/components-next/NewConversation/components/ActionButtons.vue b/app/javascript/dashboard/components-next/NewConversation/components/ActionButtons.vue
index 6f2178408..773ebe315 100644
--- a/app/javascript/dashboard/components-next/NewConversation/components/ActionButtons.vue
+++ b/app/javascript/dashboard/components-next/NewConversation/components/ActionButtons.vue
@@ -11,12 +11,14 @@ import { extractTextFromMarkdown } from 'dashboard/helper/editorHelper';
import Button from 'dashboard/components-next/button/Button.vue';
import WhatsAppOptions from './WhatsAppOptions.vue';
+import ContentTemplateSelector from './ContentTemplateSelector.vue';
const props = defineProps({
attachedFiles: { type: Array, default: () => [] },
isWhatsappInbox: { type: Boolean, default: false },
isEmailOrWebWidgetInbox: { type: Boolean, default: false },
isTwilioSmsInbox: { type: Boolean, default: false },
+ isTwilioWhatsAppInbox: { type: Boolean, default: false },
messageTemplates: { type: Array, default: () => [] },
channelType: { type: String, default: '' },
isLoading: { type: Boolean, default: false },
@@ -32,6 +34,7 @@ const emit = defineEmits([
'discard',
'sendMessage',
'sendWhatsappMessage',
+ 'sendTwilioMessage',
'insertEmoji',
'addSignature',
'removeSignature',
@@ -63,6 +66,20 @@ const sendWithSignature = computed(() => {
return fetchSignatureFlagFromUISettings(props.channelType);
});
+const showTwilioContentTemplates = computed(() => {
+ return props.isTwilioWhatsAppInbox && props.inboxId;
+});
+
+const shouldShowEmojiButton = computed(() => {
+ return (
+ !props.isWhatsappInbox && !props.isTwilioWhatsAppInbox && !props.hasNoInbox
+ );
+});
+
+const isRegularMessageMode = computed(() => {
+ return !props.isWhatsappInbox && !props.isTwilioWhatsAppInbox;
+});
+
const setSignature = () => {
if (signatureToApply.value) {
if (sendWithSignature.value) {
@@ -125,7 +142,7 @@ const keyboardEvents = {
action: () => {
if (
isEditorHotKeyEnabled('enter') &&
- !props.isWhatsappInbox &&
+ isRegularMessageMode.value &&
!props.isDropdownActive
) {
emit('sendMessage');
@@ -136,7 +153,7 @@ const keyboardEvents = {
action: () => {
if (
isEditorHotKeyEnabled('cmd_enter') &&
- !props.isWhatsappInbox &&
+ isRegularMessageMode.value &&
!props.isDropdownActive
) {
emit('sendMessage');
@@ -158,8 +175,13 @@ useKeyboardEvents(keyboardEvents);
:message-templates="messageTemplates"
@send-message="emit('sendWhatsappMessage', $event)"
/>
+
@@ -172,7 +194,7 @@ useKeyboardEvents(keyboardEvents);
/>
@@ -199,7 +221,7 @@ useKeyboardEvents(keyboardEvents);
/>