Compare commits
97
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dbe4bc2833 | ||
|
|
e9950afb1a | ||
|
|
f21298aeb9 | ||
|
|
7b6a56714f | ||
|
|
94a20af9db | ||
|
|
616371adbb | ||
|
|
2d4ef0c328 | ||
|
|
5e6e234afe | ||
|
|
18e9e771b5 | ||
|
|
0245e01763 | ||
|
|
1c9993e01b | ||
|
|
fcd40e9636 | ||
|
|
4f5c5e9f85 | ||
|
|
cb07ac16d1 | ||
|
|
4fa299ff15 | ||
|
|
71e9566854 | ||
|
|
a1a59684cd | ||
|
|
272f920811 | ||
|
|
e39d19b1e8 | ||
|
|
6c39aed882 | ||
|
|
8d43101892 | ||
|
|
f05535c5ad | ||
|
|
4503ba018d | ||
|
|
8bc2bc6d40 | ||
|
|
bfd192ebb2 | ||
|
|
6e13d22ff7 | ||
|
|
3e8b6e1aee | ||
|
|
3038aaef67 | ||
|
|
57a68666cb | ||
|
|
4acb824857 | ||
|
|
5c74674c2b | ||
|
|
52e49d5f9d | ||
|
|
e529e1206e | ||
|
|
a8009c7b39 | ||
|
|
99bb074656 | ||
|
|
9322112481 | ||
|
|
ce4cfee8bd | ||
|
|
f31fc2b375 | ||
|
|
e5f7807833 | ||
|
|
2483d99d3c | ||
|
|
336584c95a | ||
|
|
9ebabb9832 | ||
|
|
2acf09b3eb | ||
|
|
d18d3e9e2e | ||
|
|
deec1d213b | ||
|
|
25c3fb3c36 | ||
|
|
e2a6dc3e04 | ||
|
|
57feedbf25 | ||
|
|
71310c21ad | ||
|
|
623cd72897 | ||
|
|
04aa13e8aa | ||
|
|
6ab964b161 | ||
|
|
5598b4b27e | ||
|
|
64ae9f625a | ||
|
|
3dd3b7b3aa | ||
|
|
f451e59aec | ||
|
|
c04f67e8a5 | ||
|
|
6ddc99d066 | ||
|
|
4cbb3208e8 | ||
|
|
5f2a720920 | ||
|
|
acb7debd3f | ||
|
|
44f6a9ec3c | ||
|
|
24468d71fb | ||
|
|
26ef21a243 | ||
|
|
18235d3fb5 | ||
|
|
55972cc17a | ||
|
|
2daf1ae827 | ||
|
|
22421b5ac8 | ||
|
|
0d41853b0b | ||
|
|
355926897a | ||
|
|
4101a7b566 | ||
|
|
2d31535620 | ||
|
|
c54b469dcb | ||
|
|
29e8e41443 | ||
|
|
178bc80b25 | ||
|
|
ab039e14fd | ||
|
|
961c911c26 | ||
|
|
12ae49089b | ||
|
|
996f842882 | ||
|
|
616f702871 | ||
|
|
8015490aba | ||
|
|
b89c917198 | ||
|
|
7b8a3fcae0 | ||
|
|
2df83276e0 | ||
|
|
7b68a7639f | ||
|
|
e3b8c1fbb5 | ||
|
|
310c127693 | ||
|
|
37c0f1306c | ||
|
|
396ef02b0c | ||
|
|
ebefb2e201 | ||
|
|
6f09f20991 | ||
|
|
cfe86d9c06 | ||
|
|
84240e197a | ||
|
|
bafff90f18 | ||
|
|
961d810645 | ||
|
|
1a06bfd69c | ||
|
|
1cac2e86c3 |
@@ -15,9 +15,9 @@ defaults: &defaults
|
||||
- image: cimg/postgres:15.3
|
||||
- image: cimg/redis:6.2.6
|
||||
environment:
|
||||
- RAILS_LOG_TO_STDOUT: false
|
||||
- COVERAGE: true
|
||||
- LOG_LEVEL: warn
|
||||
- RAILS_LOG_TO_STDOUT: false
|
||||
- COVERAGE: true
|
||||
- LOG_LEVEL: warn
|
||||
parallelism: 4
|
||||
resource_class: large
|
||||
|
||||
@@ -46,7 +46,7 @@ jobs:
|
||||
export NVM_DIR="$HOME/.nvm"
|
||||
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
|
||||
[ -s "$NVM_DIR/bash_completion" ] && \. "$NVM_DIR/bash_completion"
|
||||
nvm install v16
|
||||
nvm install v20
|
||||
echo 'export NVM_DIR="$HOME/.nvm"' >> $BASH_ENV
|
||||
echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> $BASH_ENV
|
||||
|
||||
@@ -64,7 +64,6 @@ jobs:
|
||||
- ~/.bundle
|
||||
key: chatwoot-bundle-{{ .Environment.CACHE_VERSION }}-v20220524-{{ checksum "Gemfile.lock" }}
|
||||
|
||||
|
||||
# Only necessary if app uses webpacker or yarn in some other way
|
||||
- restore_cache:
|
||||
keys:
|
||||
@@ -82,7 +81,7 @@ jobs:
|
||||
- ~/.cache/yarn
|
||||
|
||||
- run:
|
||||
name: Download cc-test-reporter
|
||||
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
|
||||
@@ -182,7 +181,7 @@ jobs:
|
||||
- attach_workspace:
|
||||
at: ~/build
|
||||
- run:
|
||||
name: Download cc-test-reporter
|
||||
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
|
||||
@@ -204,4 +203,4 @@ workflows:
|
||||
- build
|
||||
- upload-coverage:
|
||||
requires:
|
||||
- build
|
||||
- build
|
||||
|
||||
@@ -199,6 +199,8 @@ ANDROID_SHA256_CERT_FINGERPRINT=AC:73:8E:DE:EB:56:EA:CC:10:87:02:A7:65:37:7B:38:
|
||||
## Rack Attack configuration
|
||||
## To prevent and throttle abusive requests
|
||||
# ENABLE_RACK_ATTACK=true
|
||||
# RACK_ATTACK_IP_LIMIT=3000
|
||||
# ENABLE_RACK_ATTACK_WIDGET_API=true
|
||||
|
||||
## Running chatwoot as an API only server
|
||||
## setting this value to true will disable the frontend dashboard endpoints
|
||||
|
||||
@@ -52,7 +52,8 @@ jobs:
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
cache: yarn
|
||||
|
||||
- name: yarn
|
||||
run: yarn install
|
||||
@@ -75,6 +76,8 @@ jobs:
|
||||
- name: Run backend tests
|
||||
run: |
|
||||
bundle exec rspec --profile=10 --format documentation
|
||||
env:
|
||||
NODE_OPTIONS: --openssl-legacy-provider
|
||||
|
||||
- name: Upload rails log folder
|
||||
uses: actions/upload-artifact@v3
|
||||
|
||||
@@ -51,7 +51,8 @@ jobs:
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
cache: yarn
|
||||
|
||||
- name: yarn
|
||||
run: yarn install
|
||||
|
||||
@@ -21,7 +21,8 @@ jobs:
|
||||
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 16
|
||||
node-version: 20
|
||||
cache: 'yarn'
|
||||
|
||||
- name: yarn
|
||||
run: yarn install
|
||||
@@ -30,9 +31,11 @@ jobs:
|
||||
run: |
|
||||
rm -rf enterprise
|
||||
rm -rf spec/enterprise
|
||||
|
||||
|
||||
- name: Run asset compile
|
||||
run: bundle exec rake assets:precompile
|
||||
env:
|
||||
NODE_OPTIONS: --openssl-legacy-provider
|
||||
|
||||
- name: Size Check
|
||||
run: yarn run size
|
||||
|
||||
+4
-9
@@ -8,15 +8,11 @@ Layout/LineLength:
|
||||
Max: 150
|
||||
|
||||
Metrics/ClassLength:
|
||||
Max: 125
|
||||
Max: 175
|
||||
Exclude:
|
||||
- 'app/models/conversation.rb'
|
||||
- 'app/models/contact.rb'
|
||||
- 'app/mailers/conversation_reply_mailer.rb'
|
||||
- 'app/models/message.rb'
|
||||
- 'app/builders/messages/facebook/message_builder.rb'
|
||||
- 'app/controllers/api/v1/accounts/contacts_controller.rb'
|
||||
- 'app/listeners/action_cable_listener.rb'
|
||||
- 'app/models/conversation.rb'
|
||||
|
||||
RSpec/ExampleLength:
|
||||
Max: 25
|
||||
Style/Documentation:
|
||||
@@ -73,7 +69,7 @@ Rails/ApplicationController:
|
||||
- 'app/controllers/survey/responses_controller.rb'
|
||||
Rails/FindEach:
|
||||
Enabled: true
|
||||
Include:
|
||||
Include:
|
||||
- 'app/**/*.rb'
|
||||
Rails/CompactBlank:
|
||||
Enabled: false
|
||||
@@ -189,7 +185,6 @@ RSpec/IndexedLet:
|
||||
RSpec/NamedSubject:
|
||||
Enabled: false
|
||||
|
||||
|
||||
# we should bring this down
|
||||
RSpec/MultipleMemoizedHelpers:
|
||||
Max: 14
|
||||
|
||||
@@ -4,7 +4,7 @@ ruby '3.2.2'
|
||||
|
||||
##-- base gems for rails --##
|
||||
gem 'rack-cors', require: 'rack/cors'
|
||||
gem 'rails', '~> 7.0.5.1'
|
||||
gem 'rails', '~> 7.0.8.0'
|
||||
# Reduces boot times through caching; required in config/boot.rb
|
||||
gem 'bootsnap', require: false
|
||||
|
||||
@@ -108,14 +108,14 @@ gem 'elastic-apm', require: false
|
||||
gem 'newrelic_rpm', require: false
|
||||
gem 'newrelic-sidekiq-metrics', require: false
|
||||
gem 'scout_apm', require: false
|
||||
gem 'sentry-rails', '>= 5.10.0', require: false
|
||||
gem 'sentry-rails', '>= 5.11.0', require: false
|
||||
gem 'sentry-ruby', require: false
|
||||
gem 'sentry-sidekiq', '>= 5.10.0', require: false
|
||||
gem 'sentry-sidekiq', '>= 5.11.0', require: false
|
||||
|
||||
##-- background job processing --##
|
||||
gem 'sidekiq'
|
||||
gem 'sidekiq', '>= 7.1.3'
|
||||
# We want cron jobs
|
||||
gem 'sidekiq-cron'
|
||||
gem 'sidekiq-cron', '>= 1.10.1'
|
||||
|
||||
##-- Push notification service --##
|
||||
gem 'fcm'
|
||||
@@ -188,7 +188,7 @@ group :development do
|
||||
gem 'bullet'
|
||||
gem 'letter_opener'
|
||||
gem 'scss_lint', require: false
|
||||
gem 'web-console'
|
||||
gem 'web-console', '>= 4.2.1'
|
||||
|
||||
# used in swagger build
|
||||
gem 'json_refs'
|
||||
|
||||
+81
-81
@@ -33,70 +33,70 @@ GIT
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actioncable (7.0.5.1)
|
||||
actionpack (= 7.0.5.1)
|
||||
activesupport (= 7.0.5.1)
|
||||
actioncable (7.0.8)
|
||||
actionpack (= 7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (>= 0.6.1)
|
||||
actionmailbox (7.0.5.1)
|
||||
actionpack (= 7.0.5.1)
|
||||
activejob (= 7.0.5.1)
|
||||
activerecord (= 7.0.5.1)
|
||||
activestorage (= 7.0.5.1)
|
||||
activesupport (= 7.0.5.1)
|
||||
actionmailbox (7.0.8)
|
||||
actionpack (= 7.0.8)
|
||||
activejob (= 7.0.8)
|
||||
activerecord (= 7.0.8)
|
||||
activestorage (= 7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
mail (>= 2.7.1)
|
||||
net-imap
|
||||
net-pop
|
||||
net-smtp
|
||||
actionmailer (7.0.5.1)
|
||||
actionpack (= 7.0.5.1)
|
||||
actionview (= 7.0.5.1)
|
||||
activejob (= 7.0.5.1)
|
||||
activesupport (= 7.0.5.1)
|
||||
actionmailer (7.0.8)
|
||||
actionpack (= 7.0.8)
|
||||
actionview (= 7.0.8)
|
||||
activejob (= 7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
net-imap
|
||||
net-pop
|
||||
net-smtp
|
||||
rails-dom-testing (~> 2.0)
|
||||
actionpack (7.0.5.1)
|
||||
actionview (= 7.0.5.1)
|
||||
activesupport (= 7.0.5.1)
|
||||
actionpack (7.0.8)
|
||||
actionview (= 7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
rack (~> 2.0, >= 2.2.4)
|
||||
rack-test (>= 0.6.3)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
||||
actiontext (7.0.5.1)
|
||||
actionpack (= 7.0.5.1)
|
||||
activerecord (= 7.0.5.1)
|
||||
activestorage (= 7.0.5.1)
|
||||
activesupport (= 7.0.5.1)
|
||||
actiontext (7.0.8)
|
||||
actionpack (= 7.0.8)
|
||||
activerecord (= 7.0.8)
|
||||
activestorage (= 7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
globalid (>= 0.6.0)
|
||||
nokogiri (>= 1.8.5)
|
||||
actionview (7.0.5.1)
|
||||
activesupport (= 7.0.5.1)
|
||||
actionview (7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
builder (~> 3.1)
|
||||
erubi (~> 1.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
||||
active_record_query_trace (1.8)
|
||||
activejob (7.0.5.1)
|
||||
activesupport (= 7.0.5.1)
|
||||
activejob (7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
globalid (>= 0.3.6)
|
||||
activemodel (7.0.5.1)
|
||||
activesupport (= 7.0.5.1)
|
||||
activerecord (7.0.5.1)
|
||||
activemodel (= 7.0.5.1)
|
||||
activesupport (= 7.0.5.1)
|
||||
activemodel (7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
activerecord (7.0.8)
|
||||
activemodel (= 7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
activerecord-import (1.4.1)
|
||||
activerecord (>= 4.2)
|
||||
activestorage (7.0.5.1)
|
||||
actionpack (= 7.0.5.1)
|
||||
activejob (= 7.0.5.1)
|
||||
activerecord (= 7.0.5.1)
|
||||
activesupport (= 7.0.5.1)
|
||||
activestorage (7.0.8)
|
||||
actionpack (= 7.0.8)
|
||||
activejob (= 7.0.8)
|
||||
activerecord (= 7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
marcel (~> 1.0)
|
||||
mini_mime (>= 1.1.0)
|
||||
activesupport (7.0.5.1)
|
||||
activesupport (7.0.8)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
@@ -269,8 +269,8 @@ GEM
|
||||
grpc (~> 1.36)
|
||||
geocoder (1.8.1)
|
||||
gli (2.21.0)
|
||||
globalid (1.1.0)
|
||||
activesupport (>= 5.0)
|
||||
globalid (1.2.1)
|
||||
activesupport (>= 6.1)
|
||||
gmail_xoauth (0.4.2)
|
||||
oauth (>= 0.3.6)
|
||||
google-apis-core (0.11.0)
|
||||
@@ -450,9 +450,9 @@ GEM
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2023.0218.1)
|
||||
mini_magick (4.12.0)
|
||||
mini_mime (1.1.2)
|
||||
mini_mime (1.1.5)
|
||||
mini_portile2 (2.8.4)
|
||||
minitest (5.19.0)
|
||||
minitest (5.20.0)
|
||||
mock_redis (0.36.0)
|
||||
ruby2_keywords
|
||||
msgpack (1.7.0)
|
||||
@@ -463,7 +463,7 @@ GEM
|
||||
activerecord (>= 5.2)
|
||||
net-http-persistent (4.0.2)
|
||||
connection_pool (~> 2.2)
|
||||
net-imap (0.3.6)
|
||||
net-imap (0.3.7)
|
||||
date
|
||||
net-protocol
|
||||
net-pop (0.1.2)
|
||||
@@ -478,14 +478,14 @@ GEM
|
||||
sidekiq
|
||||
newrelic_rpm (8.16.0)
|
||||
nio4r (2.5.9)
|
||||
nokogiri (1.15.3)
|
||||
nokogiri (1.15.4)
|
||||
mini_portile2 (~> 2.8.2)
|
||||
racc (~> 1.4)
|
||||
nokogiri (1.15.3-arm64-darwin)
|
||||
nokogiri (1.15.4-arm64-darwin)
|
||||
racc (~> 1.4)
|
||||
nokogiri (1.15.3-x86_64-darwin)
|
||||
nokogiri (1.15.4-x86_64-darwin)
|
||||
racc (~> 1.4)
|
||||
nokogiri (1.15.3-x86_64-linux)
|
||||
nokogiri (1.15.4-x86_64-linux)
|
||||
racc (~> 1.4)
|
||||
numo-narray (0.9.2.1)
|
||||
oauth (1.1.0)
|
||||
@@ -543,7 +543,7 @@ GEM
|
||||
pry-rails (0.3.9)
|
||||
pry (>= 0.10.4)
|
||||
public_suffix (5.0.1)
|
||||
puma (6.2.2)
|
||||
puma (6.3.1)
|
||||
nio4r (~> 2.0)
|
||||
pundit (2.3.0)
|
||||
activesupport (>= 3.0.0)
|
||||
@@ -563,30 +563,30 @@ GEM
|
||||
rack-test (2.1.0)
|
||||
rack (>= 1.3)
|
||||
rack-timeout (0.6.3)
|
||||
rails (7.0.5.1)
|
||||
actioncable (= 7.0.5.1)
|
||||
actionmailbox (= 7.0.5.1)
|
||||
actionmailer (= 7.0.5.1)
|
||||
actionpack (= 7.0.5.1)
|
||||
actiontext (= 7.0.5.1)
|
||||
actionview (= 7.0.5.1)
|
||||
activejob (= 7.0.5.1)
|
||||
activemodel (= 7.0.5.1)
|
||||
activerecord (= 7.0.5.1)
|
||||
activestorage (= 7.0.5.1)
|
||||
activesupport (= 7.0.5.1)
|
||||
rails (7.0.8)
|
||||
actioncable (= 7.0.8)
|
||||
actionmailbox (= 7.0.8)
|
||||
actionmailer (= 7.0.8)
|
||||
actionpack (= 7.0.8)
|
||||
actiontext (= 7.0.8)
|
||||
actionview (= 7.0.8)
|
||||
activejob (= 7.0.8)
|
||||
activemodel (= 7.0.8)
|
||||
activerecord (= 7.0.8)
|
||||
activestorage (= 7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
bundler (>= 1.15.0)
|
||||
railties (= 7.0.5.1)
|
||||
rails-dom-testing (2.1.1)
|
||||
railties (= 7.0.8)
|
||||
rails-dom-testing (2.2.0)
|
||||
activesupport (>= 5.0.0)
|
||||
minitest
|
||||
nokogiri (>= 1.6)
|
||||
rails-html-sanitizer (1.6.0)
|
||||
loofah (~> 2.21)
|
||||
nokogiri (~> 1.14)
|
||||
railties (7.0.5.1)
|
||||
actionpack (= 7.0.5.1)
|
||||
activesupport (= 7.0.5.1)
|
||||
railties (7.0.8)
|
||||
actionpack (= 7.0.8)
|
||||
activesupport (= 7.0.8)
|
||||
method_source
|
||||
rake (>= 12.2)
|
||||
thor (~> 1.0)
|
||||
@@ -598,7 +598,7 @@ GEM
|
||||
ffi (~> 1.0)
|
||||
redis (5.0.6)
|
||||
redis-client (>= 0.9.0)
|
||||
redis-client (0.14.1)
|
||||
redis-client (0.17.0)
|
||||
connection_pool
|
||||
redis-namespace (1.10.0)
|
||||
redis (>= 4)
|
||||
@@ -697,23 +697,23 @@ GEM
|
||||
activesupport (>= 4)
|
||||
selectize-rails (0.12.6)
|
||||
semantic_range (3.0.0)
|
||||
sentry-rails (5.10.0)
|
||||
sentry-rails (5.11.0)
|
||||
railties (>= 5.0)
|
||||
sentry-ruby (~> 5.10.0)
|
||||
sentry-ruby (5.10.0)
|
||||
sentry-ruby (~> 5.11.0)
|
||||
sentry-ruby (5.11.0)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
sentry-sidekiq (5.10.0)
|
||||
sentry-ruby (~> 5.10.0)
|
||||
sentry-sidekiq (5.11.0)
|
||||
sentry-ruby (~> 5.11.0)
|
||||
sidekiq (>= 3.0)
|
||||
sexp_processor (4.17.0)
|
||||
shoulda-matchers (5.3.0)
|
||||
activesupport (>= 5.2.0)
|
||||
sidekiq (7.1.2)
|
||||
sidekiq (7.1.3)
|
||||
concurrent-ruby (< 2)
|
||||
connection_pool (>= 2.3.0)
|
||||
rack (>= 2.2.4)
|
||||
redis-client (>= 0.14.0)
|
||||
sidekiq-cron (1.10.0)
|
||||
sidekiq-cron (1.10.1)
|
||||
fugit (~> 1.8)
|
||||
globalid (>= 1.0.1)
|
||||
sidekiq (>= 6)
|
||||
@@ -786,7 +786,7 @@ GEM
|
||||
version_gem (1.1.2)
|
||||
warden (1.2.9)
|
||||
rack (>= 2.0.9)
|
||||
web-console (4.2.0)
|
||||
web-console (4.2.1)
|
||||
actionview (>= 6.0.0)
|
||||
activemodel (>= 6.0.0)
|
||||
bindex (>= 0.4.0)
|
||||
@@ -805,14 +805,14 @@ GEM
|
||||
railties (>= 5.2)
|
||||
semantic_range (>= 2.3.0)
|
||||
webrick (1.8.1)
|
||||
websocket-driver (0.7.5)
|
||||
websocket-driver (0.7.6)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.5)
|
||||
wisper (2.0.0)
|
||||
working_hours (1.4.1)
|
||||
activesupport (>= 3.2)
|
||||
tzinfo
|
||||
zeitwerk (2.6.9)
|
||||
zeitwerk (2.6.11)
|
||||
|
||||
PLATFORMS
|
||||
arm64-darwin-20
|
||||
@@ -907,7 +907,7 @@ DEPENDENCIES
|
||||
rack-cors
|
||||
rack-mini-profiler (>= 3.1.1)
|
||||
rack-timeout
|
||||
rails (~> 7.0.5.1)
|
||||
rails (~> 7.0.8.0)
|
||||
redis
|
||||
redis-namespace
|
||||
responders
|
||||
@@ -922,12 +922,12 @@ DEPENDENCIES
|
||||
scout_apm
|
||||
scss_lint
|
||||
seed_dump
|
||||
sentry-rails (>= 5.10.0)
|
||||
sentry-rails (>= 5.11.0)
|
||||
sentry-ruby
|
||||
sentry-sidekiq (>= 5.10.0)
|
||||
sentry-sidekiq (>= 5.11.0)
|
||||
shoulda-matchers
|
||||
sidekiq
|
||||
sidekiq-cron
|
||||
sidekiq (>= 7.1.3)
|
||||
sidekiq-cron (>= 1.10.1)
|
||||
simplecov (= 0.17.1)
|
||||
slack-ruby-client (~> 2.0.0)
|
||||
spring
|
||||
@@ -943,7 +943,7 @@ DEPENDENCIES
|
||||
tzinfo-data
|
||||
uglifier
|
||||
valid_email2
|
||||
web-console
|
||||
web-console (>= 4.2.1)
|
||||
web-push
|
||||
webmock
|
||||
webpacker
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
backend: bin/rails s -p 3000
|
||||
frontend: bin/webpack-dev-server
|
||||
frontend: export NODE_OPTIONS=--openssl-legacy-provider && bin/webpack-dev-server
|
||||
# https://github.com/mperham/sidekiq/issues/3090#issuecomment-389748695
|
||||
worker: dotenv bundle exec sidekiq -C config/sidekiq.yml
|
||||
|
||||
@@ -60,6 +60,9 @@
|
||||
],
|
||||
"stack": "heroku-20",
|
||||
"buildpacks": [
|
||||
{
|
||||
"url": "heroku/nodejs"
|
||||
},
|
||||
{
|
||||
"url": "heroku/ruby"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class Api::V1::Accounts::ArticlesController < Api::V1::Accounts::BaseController
|
||||
before_action :portal
|
||||
before_action :check_authorization
|
||||
before_action :fetch_article, except: [:index, :create, :attach_file, :reorder]
|
||||
before_action :fetch_article, except: [:index, :create, :reorder]
|
||||
before_action :set_current_page, only: [:index]
|
||||
|
||||
def index
|
||||
@@ -36,17 +36,6 @@ class Api::V1::Accounts::ArticlesController < Api::V1::Accounts::BaseController
|
||||
head :ok
|
||||
end
|
||||
|
||||
def attach_file
|
||||
file_blob = ActiveStorage::Blob.create_and_upload!(
|
||||
key: nil,
|
||||
io: params[:background_image].tempfile,
|
||||
filename: params[:background_image].original_filename,
|
||||
content_type: params[:background_image].content_type
|
||||
)
|
||||
file_blob.save!
|
||||
render json: { file_url: url_for(file_blob) }
|
||||
end
|
||||
|
||||
def reorder
|
||||
Article.update_positions(params[:positions_hash])
|
||||
head :ok
|
||||
|
||||
@@ -20,16 +20,6 @@ class Api::V1::Accounts::AutomationRulesController < Api::V1::Accounts::BaseCont
|
||||
@automation_rule
|
||||
end
|
||||
|
||||
def attach_file
|
||||
file_blob = ActiveStorage::Blob.create_and_upload!(
|
||||
key: nil,
|
||||
io: params[:attachment].tempfile,
|
||||
filename: params[:attachment].original_filename,
|
||||
content_type: params[:attachment].content_type
|
||||
)
|
||||
render json: { blob_key: file_blob.key, blob_id: file_blob.id }
|
||||
end
|
||||
|
||||
def update
|
||||
ActiveRecord::Base.transaction do
|
||||
automation_rule_update
|
||||
|
||||
@@ -18,7 +18,7 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController
|
||||
|
||||
def index
|
||||
@contacts_count = resolved_contacts.count
|
||||
@contacts = fetch_contacts_with_conversation_count(resolved_contacts)
|
||||
@contacts = fetch_contacts(resolved_contacts)
|
||||
end
|
||||
|
||||
def search
|
||||
@@ -29,7 +29,7 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController
|
||||
search: "%#{params[:q].strip}%"
|
||||
)
|
||||
@contacts_count = contacts.count
|
||||
@contacts = fetch_contacts_with_conversation_count(contacts)
|
||||
@contacts = fetch_contacts(contacts)
|
||||
end
|
||||
|
||||
def import
|
||||
@@ -63,7 +63,7 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController
|
||||
result = ::Contacts::FilterService.new(params.permit!, current_user).perform
|
||||
contacts = result[:contacts]
|
||||
@contacts_count = result[:count]
|
||||
@contacts = fetch_contacts_with_conversation_count(contacts)
|
||||
@contacts = fetch_contacts(contacts)
|
||||
end
|
||||
|
||||
def contactable_inboxes
|
||||
@@ -125,17 +125,14 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController
|
||||
@current_page = params[:page] || 1
|
||||
end
|
||||
|
||||
def fetch_contacts_with_conversation_count(contacts)
|
||||
conversation_count_sub_query = 'SELECT COUNT(*) FROM "conversations" WHERE "conversations"."contact_id" = "contacts"."id"'
|
||||
contacts_with_conversation_count = filtrate(contacts)
|
||||
.select("contacts.*, (#{conversation_count_sub_query}) as conversations_count")
|
||||
.group('contacts.id')
|
||||
.includes([{ avatar_attachment: [:blob] }])
|
||||
.page(@current_page).per(RESULTS_PER_PAGE)
|
||||
def fetch_contacts(contacts)
|
||||
contacts_with_avatar = filtrate(contacts)
|
||||
.includes([{ avatar_attachment: [:blob] }])
|
||||
.page(@current_page).per(RESULTS_PER_PAGE)
|
||||
|
||||
return contacts_with_conversation_count.includes([{ contact_inboxes: [:inbox] }]) if @include_contact_inboxes
|
||||
return contacts_with_avatar.includes([{ contact_inboxes: [:inbox] }]) if @include_contact_inboxes
|
||||
|
||||
contacts_with_conversation_count
|
||||
contacts_with_avatar
|
||||
end
|
||||
|
||||
def build_contact_inbox
|
||||
|
||||
@@ -39,16 +39,6 @@ class Api::V1::Accounts::MacrosController < Api::V1::Accounts::BaseController
|
||||
head :ok
|
||||
end
|
||||
|
||||
def attach_file
|
||||
file_blob = ActiveStorage::Blob.create_and_upload!(
|
||||
key: nil,
|
||||
io: params[:attachment].tempfile,
|
||||
filename: params[:attachment].original_filename,
|
||||
content_type: params[:attachment].content_type
|
||||
)
|
||||
render json: { blob_key: file_blob.key, blob_id: file_blob.id }
|
||||
end
|
||||
|
||||
def execute
|
||||
::MacrosExecutionJob.perform_later(@macro, conversation_ids: params[:conversation_ids], user: Current.user)
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
class Api::V1::Accounts::PortalsController < Api::V1::Accounts::BaseController
|
||||
include ::FileTypeHelper
|
||||
|
||||
before_action :fetch_portal, except: [:index, :create, :attach_file]
|
||||
before_action :fetch_portal, except: [:index, :create]
|
||||
before_action :check_authorization
|
||||
before_action :set_current_page, only: [:index]
|
||||
|
||||
@@ -53,16 +53,6 @@ class Api::V1::Accounts::PortalsController < Api::V1::Accounts::BaseController
|
||||
@portal.logo.attach(blob)
|
||||
end
|
||||
|
||||
def attach_file
|
||||
file_blob = ActiveStorage::Blob.create_and_upload!(
|
||||
key: nil,
|
||||
io: params[:logo].tempfile,
|
||||
filename: params[:logo].original_filename,
|
||||
content_type: params[:logo].content_type
|
||||
)
|
||||
render json: { blob_key: file_blob.key, blob_id: file_blob.id }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def fetch_portal
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
class Api::V1::UploadController < Api::BaseController
|
||||
def create
|
||||
file_blob = ActiveStorage::Blob.create_and_upload!(
|
||||
key: nil,
|
||||
io: params[:attachment].tempfile,
|
||||
filename: params[:attachment].original_filename,
|
||||
content_type: params[:attachment].content_type
|
||||
)
|
||||
file_blob.save!
|
||||
|
||||
render json: { file_url: url_for(file_blob), blob_key: file_blob.key, blob_id: file_blob.id }
|
||||
end
|
||||
end
|
||||
@@ -8,7 +8,7 @@ module EnsureCurrentAccountHelper
|
||||
|
||||
def ensure_current_account
|
||||
account = Account.find(params[:account_id])
|
||||
ensure_account_is_active?(account)
|
||||
render_unauthorized('Account is suspended') and return unless account.active?
|
||||
|
||||
if current_user
|
||||
account_accessible_for_user?(account)
|
||||
@@ -27,8 +27,4 @@ module EnsureCurrentAccountHelper
|
||||
def account_accessible_for_bot?(account)
|
||||
render_unauthorized('You are not authorized to access this account') unless @resource.agent_bot_inboxes.find_by(account_id: account.id)
|
||||
end
|
||||
|
||||
def ensure_account_is_active?(account)
|
||||
render_unauthorized('Account is suspended') unless account.active?
|
||||
end
|
||||
end
|
||||
|
||||
@@ -55,7 +55,7 @@ class DashboardController < ActionController::Base
|
||||
VAPID_PUBLIC_KEY: VapidService.public_key,
|
||||
ENABLE_ACCOUNT_SIGNUP: GlobalConfigService.load('ENABLE_ACCOUNT_SIGNUP', 'false'),
|
||||
FB_APP_ID: GlobalConfigService.load('FB_APP_ID', ''),
|
||||
FACEBOOK_API_VERSION: 'v14.0',
|
||||
FACEBOOK_API_VERSION: 'v17.0',
|
||||
IS_ENTERPRISE: ChatwootApp.enterprise?,
|
||||
AZURE_APP_ID: ENV.fetch('AZURE_APP_ID', ''),
|
||||
GIT_SHA: GIT_HASH
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
class Public::Api::V1::Portals::BaseController < PublicController
|
||||
before_action :show_plain_layout
|
||||
around_action :set_locale
|
||||
after_action :allow_iframe_requests
|
||||
|
||||
private
|
||||
|
||||
@@ -39,4 +40,8 @@ class Public::Api::V1::Portals::BaseController < PublicController
|
||||
|
||||
I18n.with_locale(@locale, &)
|
||||
end
|
||||
|
||||
def allow_iframe_requests
|
||||
response.headers.delete('X-Frame-Options') if @is_plain_layout_enabled
|
||||
end
|
||||
end
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div
|
||||
v-if="!authUIFlags.isFetching"
|
||||
id="app"
|
||||
class="app-wrapper app-root"
|
||||
class="app-wrapper h-full flex-grow-0 min-h-0 w-full"
|
||||
:class="{ 'app-rtl--wrapper': isRTLView }"
|
||||
:dir="isRTLView ? 'rtl' : 'ltr'"
|
||||
>
|
||||
|
||||
@@ -9,14 +9,6 @@ class AutomationsAPI extends ApiClient {
|
||||
clone(automationId) {
|
||||
return axios.post(`${this.url}/${automationId}/clone`);
|
||||
}
|
||||
|
||||
attachment(file) {
|
||||
return axios.post(`${this.url}/attach_file`, file, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export default new AutomationsAPI();
|
||||
|
||||
@@ -47,20 +47,6 @@ class ArticlesAPI extends PortalsAPI {
|
||||
return axios.delete(`${this.url}/${portalSlug}/articles/${articleId}`);
|
||||
}
|
||||
|
||||
uploadImage({ portalSlug, file }) {
|
||||
let formData = new FormData();
|
||||
formData.append('background_image', file);
|
||||
return axios.post(
|
||||
`${this.url}/${portalSlug}/articles/attach_file`,
|
||||
formData,
|
||||
{
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
reorderArticles({ portalSlug, reorderedGroup, categorySlug }) {
|
||||
return axios.post(`${this.url}/${portalSlug}/articles/reorder`, {
|
||||
positions_hash: reorderedGroup,
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<svg width="495" height="384" viewBox="0 0 495 384" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="No Chat History">
|
||||
<path id="Fill 1" fill-rule="evenodd" clip-rule="evenodd" d="M266.903 0C221.687 0 180.128 15.7196 147.313 42.0198H94.2771C87.3866 42.0198 81.749 47.6925 81.749 54.6257C81.749 61.559 87.3866 67.2317 94.2771 67.2317H121.268H129.178C136.068 67.2317 141.706 72.9043 141.706 79.8376C141.706 83.3 140.294 86.4599 138.023 88.7374C135.759 91.0233 132.619 92.4435 129.178 92.4435H112.303H102.986H57.5281C50.6376 92.4435 45 98.1162 45 105.049C45 111.983 50.6376 117.655 57.5281 117.655H90.071C80.2473 140.886 74.8059 166.446 74.8059 193.291C74.8059 203.031 75.5242 212.603 76.9023 221.957C77.4786 225.865 78.1718 229.739 78.982 233.571C102.618 229.932 127.691 227.008 153.866 224.873L155.837 226.68L157.692 224.571C189.137 222.108 222.144 220.797 256.187 220.797C328.516 220.797 396.201 226.714 454.072 237C456.302 227.268 457.806 217.259 458.516 207.023C458.841 202.485 459 197.905 459 193.291C459 86.5356 372.999 0 266.903 0Z" fill="#43484C"/>
|
||||
<path id="Fill 3" fill-rule="evenodd" clip-rule="evenodd" d="M20.2465 91.4282H12.6678C5.7005 91.4282 0 97.1882 0 104.228C0 111.268 5.7005 117.028 12.6678 117.028H20.2465C27.2137 117.028 32.9142 111.268 32.9142 104.228C32.9142 97.1882 27.2137 91.4282 20.2465 91.4282Z" fill="#43484C"/>
|
||||
<g id="Group 7">
|
||||
<mask id="mask0_201_141" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="78" y="219" width="417" height="165">
|
||||
<path id="Clip 6" fill-rule="evenodd" clip-rule="evenodd" d="M495 219V384H286.5H78V219H495Z" fill="white"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_201_141)">
|
||||
<path id="Fill 5" fill-rule="evenodd" clip-rule="evenodd" d="M495 279.775C495 286.675 489.336 292.321 482.413 292.321H402.016C398.559 292.321 395.405 293.734 393.131 296.009C390.849 298.276 389.43 301.421 389.43 304.867C389.43 311.768 395.094 317.413 402.016 317.413H416.954C420.41 317.413 423.566 318.827 425.84 321.102C428.122 323.369 429.54 326.514 429.54 329.96C429.54 336.86 423.876 342.506 416.954 342.506H382.608C350.344 366.662 310.251 380.981 266.802 380.981C174.004 380.981 96.5026 315.699 78 228.695C101.747 225.073 126.937 222.162 153.235 220.038L155.215 221.836L157.079 219.736C188.671 217.286 221.833 215.981 256.036 215.981C328.703 215.981 396.705 221.869 454.847 232.107C452.02 244.302 448.026 256.045 442.991 267.228H482.413C485.879 267.228 489.017 268.642 491.3 270.917C493.582 273.184 495 276.328 495 279.775Z" fill="#34393D"/>
|
||||
</g>
|
||||
</g>
|
||||
<path id="Fill 8" fill-rule="evenodd" clip-rule="evenodd" d="M459 206.12C458.285 216.665 456.771 226.975 454.525 237C396.235 226.404 328.06 220.31 255.208 220.31C220.919 220.31 187.673 221.66 156 224.196L177.965 198.615L212.134 221.028L258.388 208.19L337.959 220.31L372.503 208.19L381.252 220.31L402.126 204.736L421.632 222.707L452.396 198L459 206.12Z" fill="#55575E"/>
|
||||
<path id="Fill 10" fill-rule="evenodd" clip-rule="evenodd" d="M344.905 216.502C353.565 203.915 358.526 188.987 358.397 173.012C358.043 128.578 318.46 92.8734 269.986 93.2602C221.512 93.6478 182.505 129.983 182.86 174.416C183.214 218.849 222.798 254.555 271.271 254.168C288.59 254.03 304.7 249.3 318.238 241.253L354.454 249.78L344.905 216.502Z" fill="#686B73"/>
|
||||
<path id="Fill 12" fill-rule="evenodd" clip-rule="evenodd" d="M245.029 171.813C245.069 176.862 241.008 180.988 235.959 181.028C230.909 181.069 226.783 177.008 226.743 171.959C226.703 166.909 230.763 162.784 235.813 162.743C240.861 162.703 244.987 166.763 245.029 171.813Z" fill="#BEC0D6"/>
|
||||
<path id="Fill 14" fill-rule="evenodd" clip-rule="evenodd" d="M277.942 171.812C277.982 176.862 273.922 180.988 268.872 181.028C263.822 181.068 259.696 177.008 259.657 171.959C259.616 166.909 263.677 162.783 268.726 162.743C273.775 162.703 277.901 166.763 277.942 171.812Z" fill="#BEC0D6"/>
|
||||
<path id="Fill 16" fill-rule="evenodd" clip-rule="evenodd" d="M310.856 171.812C310.897 176.861 306.836 180.987 301.786 181.028C296.737 181.068 292.611 177.008 292.571 171.958C292.53 166.908 296.591 162.783 301.641 162.743C306.689 162.702 310.815 166.763 310.856 171.812Z" fill="#BEC0D6"/>
|
||||
<path id="Fill 20" fill-rule="evenodd" clip-rule="evenodd" d="M173.714 235.887C173.714 241.693 175.571 247.099 178.763 251.649L175.376 263.789L188.564 260.581C193.523 263.465 199.402 265.143 205.714 265.143C223.388 265.143 237.714 252.044 237.714 235.887C237.714 219.728 223.388 206.629 205.714 206.629C188.041 206.629 173.714 219.728 173.714 235.887Z" fill="url(#paint0_linear_201_141)"/>
|
||||
<g id="Frame 148">
|
||||
<path id="Fill 26" fill-rule="evenodd" clip-rule="evenodd" d="M189 234.658C189 236.677 190.637 238.314 192.657 238.314C194.676 238.314 196.314 236.677 196.314 234.658C196.314 232.638 194.676 231 192.657 231C190.637 231 189 232.638 189 234.658Z" fill="#0D0D0D"/>
|
||||
<path id="Fill 24" fill-rule="evenodd" clip-rule="evenodd" d="M202.314 234.658C202.314 236.677 203.951 238.314 205.971 238.314C207.99 238.314 209.628 236.677 209.628 234.658C209.628 232.638 207.99 231 205.971 231C203.951 231 202.314 232.638 202.314 234.658Z" fill="#0D0D0D"/>
|
||||
<path id="Fill 22" fill-rule="evenodd" clip-rule="evenodd" d="M215.629 234.658C215.629 236.677 217.265 238.314 219.285 238.314C221.305 238.314 222.943 236.677 222.943 234.658C222.943 232.638 221.305 231 219.285 231C217.265 231 215.629 232.638 215.629 234.658Z" fill="#0D0D0D"/>
|
||||
</g>
|
||||
<path id="Fill 28" fill-rule="evenodd" clip-rule="evenodd" d="M153.6 223.557C127.481 225.685 102.461 228.601 78.8755 232.228C78.0671 228.408 77.3754 224.546 76.8003 220.65L117.229 190.171L153.6 223.557Z" fill="#55575E"/>
|
||||
<path id="Fill 30" fill-rule="evenodd" clip-rule="evenodd" d="M336.457 286.171C336.457 289.706 304.529 292.571 265.143 292.571C225.757 292.571 193.829 289.706 193.829 286.171C193.829 282.638 225.757 279.771 265.143 279.771C304.529 279.771 336.457 282.638 336.457 286.171Z" fill="#686B73"/>
|
||||
<path id="Fill 32" fill-rule="evenodd" clip-rule="evenodd" d="M453.486 345.599C446.446 345.599 440.686 339.839 440.686 332.799C440.686 325.76 446.446 320 453.486 320C460.526 320 466.286 325.76 466.286 332.799C466.286 339.839 460.526 345.599 453.486 345.599Z" fill="#34393D"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_201_141" x1="205.714" y1="177.372" x2="147.434" y2="241.115" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#9DC9FB"/>
|
||||
<stop offset="1" stop-color="#9DC9FB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.2 KiB |
@@ -0,0 +1,33 @@
|
||||
<svg width="495" height="387" viewBox="0 0 495 387" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g id="No Chat History">
|
||||
<path id="Fill 1" fill-rule="evenodd" clip-rule="evenodd" d="M267.927 1.5C222.792 1.5 181.307 17.1457 148.551 43.3222H95.611C88.7329 43.3222 83.1054 48.9682 83.1054 55.8688C83.1054 62.7695 88.7329 68.4155 95.611 68.4155H122.554H130.449C137.327 68.4155 142.955 74.0615 142.955 80.9621C142.955 84.4083 141.546 87.5533 139.278 89.8201C137.019 92.0952 133.884 93.5088 130.449 93.5088H113.605H104.304H58.9279C52.0499 93.5088 46.4224 99.1548 46.4224 106.055C46.4224 112.956 52.0499 118.602 58.9279 118.602H91.4124C81.6064 141.723 76.1748 167.164 76.1748 193.882C76.1748 203.576 76.8918 213.103 78.2674 222.413C78.8426 226.303 79.5346 230.159 80.3433 233.973C103.937 230.351 128.965 227.44 155.093 225.316L157.061 227.114L158.912 225.014C190.301 222.564 223.249 221.259 257.23 221.259C329.429 221.259 396.993 227.147 454.76 237.385C456.986 227.699 458.487 217.737 459.196 207.549C459.521 203.033 459.679 198.474 459.679 193.882C459.679 87.6286 373.832 1.5 267.927 1.5Z" fill="#F1F2F7"/>
|
||||
<path id="Fill 3" fill-rule="evenodd" clip-rule="evenodd" d="M20.954 92.9282H13.3753C6.40802 92.9282 0.70752 98.6882 0.70752 105.728C0.70752 112.768 6.40802 118.528 13.3753 118.528H20.954C27.9213 118.528 33.6218 112.768 33.6218 105.728C33.6218 98.6882 27.9213 92.9282 20.954 92.9282Z" fill="#F1F2F7"/>
|
||||
<g id="Group 7">
|
||||
<mask id="mask0_156_62" style="mask-type:luminance" maskUnits="userSpaceOnUse" x="80" y="221" width="415" height="165">
|
||||
<path id="Clip 6" fill-rule="evenodd" clip-rule="evenodd" d="M494.293 221.536V385.5H287.188H80.083V221.536H494.293Z" fill="white"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_156_62)">
|
||||
<path id="Fill 5" fill-rule="evenodd" clip-rule="evenodd" d="M494.293 284.929C494.293 291.786 488.667 297.396 481.79 297.396H401.932C398.498 297.396 395.364 298.801 393.106 301.062C390.838 303.314 389.429 306.439 389.429 309.864C389.429 316.721 395.055 322.331 401.932 322.331H416.769C420.202 322.331 423.337 323.736 425.596 325.997C427.863 328.249 429.271 331.374 429.271 334.799C429.271 341.656 423.645 347.266 416.769 347.266H382.653C350.604 371.271 310.78 385.5 267.622 385.5C175.444 385.5 98.4618 320.627 80.083 234.169C103.671 230.57 128.693 227.678 154.815 225.567L156.781 227.354L158.632 225.268C190.013 222.832 222.954 221.536 256.928 221.536C329.108 221.536 396.656 227.387 454.409 237.561C451.601 249.679 447.633 261.349 442.632 272.461H481.79C485.233 272.461 488.35 273.866 490.617 276.127C492.884 278.379 494.293 281.504 494.293 284.929Z" fill="#E8EBF2"/>
|
||||
</g>
|
||||
</g>
|
||||
<path id="Fill 8" fill-rule="evenodd" clip-rule="evenodd" d="M457.85 206.981C457.142 217.363 455.643 227.515 453.42 237.386C395.73 226.953 328.256 220.953 256.153 220.953C222.216 220.953 189.312 222.282 157.964 224.779L179.704 199.591L213.521 221.659L259.3 209.019L338.053 220.953L372.242 209.019L380.901 220.953L401.56 205.618L420.866 223.313L451.314 198.986L457.85 206.981Z" fill="#E0E2EE"/>
|
||||
<path id="Fill 10" fill-rule="evenodd" clip-rule="evenodd" d="M345.614 218.002C354.273 205.415 359.234 190.487 359.106 174.512C358.752 130.078 319.168 94.3734 270.694 94.7602C222.22 95.1478 183.213 131.483 183.568 175.916C183.923 220.349 223.506 256.055 271.979 255.668C289.298 255.53 305.408 250.8 318.946 242.753L355.162 251.28L345.614 218.002Z" fill="#D8DBEA"/>
|
||||
<path id="Fill 12" fill-rule="evenodd" clip-rule="evenodd" d="M245.736 173.313C245.776 178.362 241.716 182.488 236.667 182.528C231.616 182.569 227.49 178.508 227.451 173.459C227.411 168.409 231.471 164.284 236.52 164.243C241.569 164.203 245.695 168.263 245.736 173.313Z" fill="#BEC0D6"/>
|
||||
<path id="Fill 14" fill-rule="evenodd" clip-rule="evenodd" d="M278.65 173.312C278.69 178.362 274.629 182.488 269.58 182.528C264.53 182.568 260.404 178.508 260.365 173.459C260.323 168.409 264.384 164.283 269.434 164.243C274.483 164.203 278.609 168.263 278.65 173.312Z" fill="#BEC0D6"/>
|
||||
<path id="Fill 16" fill-rule="evenodd" clip-rule="evenodd" d="M311.565 173.312C311.605 178.361 307.544 182.487 302.495 182.528C297.445 182.568 293.319 178.508 293.28 173.458C293.239 168.408 297.299 164.283 302.349 164.243C307.398 164.202 311.524 168.263 311.565 173.312Z" fill="#BEC0D6"/>
|
||||
<path id="Fill 18" fill-rule="evenodd" clip-rule="evenodd" d="M157.965 224.585L156.192 226.414L154.308 224.848C155.521 224.753 156.744 224.666 157.965 224.585Z" fill="#F1F2F7"/>
|
||||
<path id="Fill 20" fill-rule="evenodd" clip-rule="evenodd" d="M174.422 237.387C174.422 243.193 176.279 248.599 179.47 253.149L176.083 265.289L189.272 262.081C194.23 264.965 200.11 266.643 206.422 266.643C224.095 266.643 238.422 253.544 238.422 237.387C238.422 221.228 224.095 208.129 206.422 208.129C188.748 208.129 174.422 221.228 174.422 237.387Z" fill="url(#paint0_linear_156_62)"/>
|
||||
<path id="Fill 22" fill-rule="evenodd" clip-rule="evenodd" d="M214.651 237.386C214.651 239.405 216.287 241.043 218.308 241.043C220.327 241.043 221.965 239.405 221.965 237.386C221.965 235.366 220.327 233.728 218.308 233.728C216.287 233.728 214.651 235.366 214.651 237.386Z" fill="white"/>
|
||||
<path id="Fill 24" fill-rule="evenodd" clip-rule="evenodd" d="M203.679 237.386C203.679 239.405 205.316 241.043 207.336 241.043C209.355 241.043 210.993 239.405 210.993 237.386C210.993 235.366 209.355 233.728 207.336 233.728C205.316 233.728 203.679 235.366 203.679 237.386Z" fill="white"/>
|
||||
<path id="Fill 26" fill-rule="evenodd" clip-rule="evenodd" d="M190.879 237.386C190.879 239.405 192.516 241.043 194.537 241.043C196.556 241.043 198.194 239.405 198.194 237.386C198.194 235.366 196.556 233.728 194.537 233.728C192.516 233.728 190.879 235.366 190.879 237.386Z" fill="white"/>
|
||||
<path id="Fill 28" fill-rule="evenodd" clip-rule="evenodd" d="M154.308 225.057C128.188 227.185 103.169 230.101 79.583 233.728C78.7746 229.908 78.0829 226.046 77.5078 222.15L117.936 191.671L154.308 225.057Z" fill="#E0E2EE"/>
|
||||
<path id="Fill 30" fill-rule="evenodd" clip-rule="evenodd" d="M337.164 287.671C337.164 291.206 305.235 294.071 265.85 294.071C226.464 294.071 194.536 291.206 194.536 287.671C194.536 284.138 226.464 281.271 265.85 281.271C305.235 281.271 337.164 284.138 337.164 287.671Z" fill="#D8DBEA"/>
|
||||
<path id="Fill 32" fill-rule="evenodd" clip-rule="evenodd" d="M454.193 347.099C447.153 347.099 441.393 341.339 441.393 334.299C441.393 327.26 447.153 321.5 454.193 321.5C461.233 321.5 466.993 327.26 466.993 334.299C466.993 341.339 461.233 347.099 454.193 347.099Z" fill="#E1E3EF"/>
|
||||
</g>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_156_62" x1="206.422" y1="178.872" x2="148.142" y2="242.615" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#9DC9FB"/>
|
||||
<stop offset="1" stop-color="#9DC9FB"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 6.5 KiB |
@@ -26,7 +26,7 @@ code {
|
||||
background: $color-background;
|
||||
border-radius: var(--border-radius-large);
|
||||
padding: $space-two;
|
||||
@apply bg-slate-50 dark:bg-slate-600 text-slate-800 dark:text-slate-100;
|
||||
@apply bg-slate-50 dark:bg-slate-700 text-slate-800 dark:text-slate-100;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,87 +9,25 @@ body {
|
||||
}
|
||||
|
||||
.app-wrapper {
|
||||
@include full-height;
|
||||
flex-grow: 0;
|
||||
min-height: 0;
|
||||
width: 100%;
|
||||
@apply h-full flex-grow-0 min-h-0 w-full;
|
||||
|
||||
.button--fixed-top {
|
||||
@apply fixed ltr:right-2 rtl:left-2 top-2 flex flex-row;
|
||||
}
|
||||
}
|
||||
|
||||
.banner + .app-wrapper {
|
||||
// Reduce the height of the dashboard to make room for the banner.
|
||||
// And causing the top right green-action button to be pushed down when scrolling.
|
||||
@apply h-[calc(100%-48px)];
|
||||
|
||||
.button--fixed-top {
|
||||
top: 5.6 * $space-one;
|
||||
@apply top-14;
|
||||
}
|
||||
|
||||
.off-canvas-content {
|
||||
.button--fixed-top {
|
||||
top: $space-small;
|
||||
@apply top-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
is-closed .app-root {
|
||||
@include flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.app-content {
|
||||
@include flex;
|
||||
@include full-height;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.view-box {
|
||||
@include full-height;
|
||||
@include space-between-column;
|
||||
|
||||
height: 100vh;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.view-panel {
|
||||
flex-direction: column;
|
||||
margin: 0;
|
||||
overflow-y: auto;
|
||||
padding: $space-normal;
|
||||
}
|
||||
|
||||
.content-box {
|
||||
overflow: auto;
|
||||
padding: $space-normal;
|
||||
}
|
||||
|
||||
.back-button {
|
||||
@include flex;
|
||||
|
||||
align-items: center;
|
||||
color: $color-woot;
|
||||
cursor: pointer;
|
||||
font-size: $font-size-default;
|
||||
font-weight: $font-weight-normal;
|
||||
margin-right: $space-normal;
|
||||
|
||||
&::before {
|
||||
font-size: $font-size-large;
|
||||
margin-right: $space-small;
|
||||
vertical-align: text-bottom;
|
||||
}
|
||||
}
|
||||
|
||||
.button-spinner {
|
||||
float: right;
|
||||
}
|
||||
|
||||
.no-items-error-message {
|
||||
@include flex;
|
||||
@include full-height;
|
||||
|
||||
align-items: center;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
|
||||
img {
|
||||
max-width: $space-mega;
|
||||
padding: $space-one;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,6 @@
|
||||
.app-rtl--wrapper {
|
||||
direction: rtl;
|
||||
|
||||
.header-section.back-button {
|
||||
direction: initial;
|
||||
margin-left: var(--space-normal);
|
||||
margin-right: var(--space-smaller);
|
||||
}
|
||||
|
||||
// Settings header action button
|
||||
.button--fixed-top {
|
||||
left: $space-small;
|
||||
position: fixed;
|
||||
right: unset;
|
||||
top: $space-small;
|
||||
}
|
||||
|
||||
// Woot Tabs
|
||||
.tabs-title {
|
||||
&:first-child {
|
||||
|
||||
@@ -71,9 +71,3 @@
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.button--fixed-top {
|
||||
position: fixed;
|
||||
right: var(--space-small);
|
||||
top: var(--space-small);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
.button {
|
||||
@apply items-center inline-flex h-10 mb-0;
|
||||
@apply items-center inline-flex h-10 mb-0 gap-2;
|
||||
|
||||
.button__content {
|
||||
@apply w-full;
|
||||
@@ -14,17 +14,9 @@
|
||||
@apply px-2 py-0;
|
||||
}
|
||||
|
||||
.icon--emoji + .button__content {
|
||||
@apply pl-2 rtl:pr-2 rtl:pl-0;
|
||||
}
|
||||
|
||||
.icon--font + .button__content {
|
||||
@apply pl-2 rtl:pr-2 rtl:pl-0;
|
||||
}
|
||||
|
||||
// @TODDO - Remove after moving all buttons to woot-button
|
||||
.icon + .button__content {
|
||||
@apply pl-2 w-auto rtl:pr-2 rtl:pl-0;
|
||||
@apply w-auto;
|
||||
}
|
||||
|
||||
&.expanded {
|
||||
@@ -157,18 +149,10 @@
|
||||
// Sizes
|
||||
&.tiny {
|
||||
@apply h-6;
|
||||
|
||||
.icon + .button__content {
|
||||
@apply pl-1 rtl:pr-1 rtl:pl-0;
|
||||
}
|
||||
}
|
||||
|
||||
&.small {
|
||||
@apply h-8 pb-1 pt-1;
|
||||
|
||||
.icon + .button__content {
|
||||
@apply pl-1 rtl:pr-1 rtl:pl-0;
|
||||
}
|
||||
}
|
||||
|
||||
&.large {
|
||||
|
||||
@@ -76,13 +76,13 @@ table {
|
||||
|
||||
.ve-pagination-goto {
|
||||
@apply text-slate-600 dark:text-slate-200;
|
||||
|
||||
.ve-pagination-goto-input {
|
||||
@apply bg-white dark:bg-slate-900 text-slate-600 dark:text-slate-200;
|
||||
}
|
||||
}
|
||||
|
||||
.ve-pagination-li {
|
||||
@apply bg-white dark:bg-slate-900 text-slate-600 dark:text-slate-200 border-slate-75 dark:border-slate-700;
|
||||
}
|
||||
|
||||
.ve-pagination-goto-input {
|
||||
@apply bg-white dark:bg-slate-900 text-slate-600 dark:text-slate-200;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@
|
||||
>
|
||||
<a
|
||||
v-if="isAttributeTypeLink"
|
||||
:href="value"
|
||||
:href="hrefURL"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
class="value inline-block rounded-sm mb-0 break-all py-0.5 px-1"
|
||||
@@ -188,6 +188,9 @@ export default {
|
||||
urlValue() {
|
||||
return isValidURL(this.value) ? this.value : '---';
|
||||
},
|
||||
hrefURL() {
|
||||
return isValidURL(this.value) ? this.value : '';
|
||||
},
|
||||
notAttributeTypeCheckboxAndList() {
|
||||
return !this.isAttributeTypeCheckbox && !this.isAttributeTypeList;
|
||||
},
|
||||
|
||||
@@ -1,11 +1,21 @@
|
||||
<template>
|
||||
<kbd class="hotkey">
|
||||
<kbd class="hotkey p-0.5 min-w-[1rem] uppercase" :class="customClass">
|
||||
<slot />
|
||||
</kbd>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
customClass: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
kbd.hotkey {
|
||||
@apply inline-flex p-0.5 leading-[0.625rem] min-w-[1rem] tracking-wide uppercase text-slate-800 dark:text-slate-100 bg-slate-50 dark:bg-slate-600 text-xxs border border-solid border-slate-75 dark:border-slate-600 rounded flex-shrink-0 items-center select-none justify-center;
|
||||
@apply inline-flex leading-[0.625rem] rounded tracking-wide flex-shrink-0 items-center select-none justify-center;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<div
|
||||
v-if="show"
|
||||
v-on-clickaway="onClickAway"
|
||||
class="left-3 rtl:left-auto rtl:right-3 bottom-16 w-64 absolute z-20 rounded-md shadow-xl bg-white dark:bg-slate-800 py-2 px-2 border border-slate-25 dark:border-slate-700"
|
||||
class="left-3 rtl:left-auto rtl:right-3 bottom-16 w-64 absolute z-30 rounded-md shadow-xl bg-white dark:bg-slate-800 py-2 px-2 border border-slate-25 dark:border-slate-700"
|
||||
:class="{ 'block visible': show }"
|
||||
>
|
||||
<availability-status />
|
||||
|
||||
@@ -46,6 +46,7 @@ import AgentDetails from './AgentDetails';
|
||||
import NotificationBell from './NotificationBell';
|
||||
import wootConstants from 'dashboard/constants/globals';
|
||||
import { frontendURL } from 'dashboard/helper/URLHelper';
|
||||
import { ACCOUNT_EVENTS } from '../../../helper/AnalyticsHelper/events';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
@@ -99,6 +100,7 @@ export default {
|
||||
window.$chatwoot.toggle();
|
||||
},
|
||||
openNotificationPanel() {
|
||||
this.$track(ACCOUNT_EVENTS.OPENED_NOTIFICATIONS);
|
||||
this.$emit('open-notification-panel');
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<div class="banner" :class="bannerClasses">
|
||||
<div
|
||||
class="banner flex items-center h-12 gap-4 text-white dark:text-white text-xs py-3 px-4 justify-center"
|
||||
:class="bannerClasses"
|
||||
>
|
||||
<span class="banner-message">
|
||||
{{ bannerMessage }}
|
||||
<a
|
||||
@@ -96,8 +99,6 @@ export default {
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.banner {
|
||||
@apply flex items-center gap-4 text-white dark:text-white text-xs py-3 px-4 justify-center;
|
||||
|
||||
&.primary {
|
||||
@apply bg-woot-500 dark:bg-woot-500;
|
||||
.banner-action__button {
|
||||
|
||||
@@ -1,41 +1,60 @@
|
||||
<template>
|
||||
<div v-if="isAIIntegrationEnabled" class="position-relative">
|
||||
<woot-button
|
||||
v-tooltip.top-end="$t('INTEGRATION_SETTINGS.OPEN_AI.AI_ASSIST')"
|
||||
icon="wand"
|
||||
color-scheme="secondary"
|
||||
variant="smooth"
|
||||
size="small"
|
||||
@click="openAIAssist"
|
||||
/>
|
||||
<woot-modal
|
||||
:show.sync="showAIAssistanceModal"
|
||||
:on-close="hideAIAssistanceModal"
|
||||
>
|
||||
<AIAssistanceModal
|
||||
:ai-option="aiOption"
|
||||
@apply-text="insertText"
|
||||
@close="hideAIAssistanceModal"
|
||||
<div v-if="!isFetchingAppIntegrations">
|
||||
<div v-if="isAIIntegrationEnabled" class="relative">
|
||||
<AIAssistanceCTAButton
|
||||
v-if="shouldShowAIAssistCTAButton"
|
||||
@click="openAIAssist"
|
||||
/>
|
||||
</woot-modal>
|
||||
<woot-button
|
||||
v-else
|
||||
v-tooltip.top-end="$t('INTEGRATION_SETTINGS.OPEN_AI.AI_ASSIST')"
|
||||
icon="wand"
|
||||
color-scheme="secondary"
|
||||
variant="smooth"
|
||||
size="small"
|
||||
@click="openAIAssist"
|
||||
/>
|
||||
<woot-modal
|
||||
:show.sync="showAIAssistanceModal"
|
||||
:on-close="hideAIAssistanceModal"
|
||||
>
|
||||
<AIAssistanceModal
|
||||
:ai-option="aiOption"
|
||||
@apply-text="insertText"
|
||||
@close="hideAIAssistanceModal"
|
||||
/>
|
||||
</woot-modal>
|
||||
</div>
|
||||
<div v-else-if="shouldShowAIAssistCTAButtonForAdmin" class="relative">
|
||||
<AIAssistanceCTAButton @click="openAICta" />
|
||||
<woot-modal :show.sync="showAICtaModal" :on-close="hideAICtaModal">
|
||||
<AICTAModal @close="hideAICtaModal" />
|
||||
</woot-modal>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
|
||||
import AICTAModal from './AICTAModal.vue';
|
||||
import AIAssistanceModal from './AIAssistanceModal.vue';
|
||||
import aiMixin from 'dashboard/mixins/aiMixin';
|
||||
import adminMixin from 'dashboard/mixins/aiMixin';
|
||||
import aiMixin from 'dashboard/mixins/isAdmin';
|
||||
import { CMD_AI_ASSIST } from 'dashboard/routes/dashboard/commands/commandBarBusEvents';
|
||||
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
|
||||
import { buildHotKeys } from 'shared/helpers/KeyboardHelpers';
|
||||
import uiSettingsMixin from 'dashboard/mixins/uiSettings';
|
||||
import AIAssistanceCTAButton from './AIAssistanceCTAButton.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
AIAssistanceModal,
|
||||
AICTAModal,
|
||||
AIAssistanceCTAButton,
|
||||
},
|
||||
mixins: [aiMixin, eventListenerMixins],
|
||||
mixins: [aiMixin, eventListenerMixins, adminMixin, uiSettingsMixin],
|
||||
data: () => ({
|
||||
showAIAssistanceModal: false,
|
||||
showAICtaModal: false,
|
||||
aiOption: '',
|
||||
initialMessage: '',
|
||||
}),
|
||||
@@ -43,6 +62,21 @@ export default {
|
||||
...mapGetters({
|
||||
currentChat: 'getSelectedChat',
|
||||
}),
|
||||
isAICTAModalDismissed() {
|
||||
return this.uiSettings.is_open_ai_cta_modal_dismissed;
|
||||
},
|
||||
// Display a AI CTA button for admins if the AI integration has not been added yet and the AI assistance modal has not been dismissed.
|
||||
shouldShowAIAssistCTAButtonForAdmin() {
|
||||
return (
|
||||
this.isAdmin &&
|
||||
!this.isAIIntegrationEnabled &&
|
||||
!this.isAICTAModalDismissed
|
||||
);
|
||||
},
|
||||
// Display a AI CTA button for agents and other admins who have not yet opened the AI assistance modal.
|
||||
shouldShowAIAssistCTAButton() {
|
||||
return this.isAIIntegrationEnabled && !this.isAICTAModalDismissed;
|
||||
},
|
||||
},
|
||||
|
||||
mounted() {
|
||||
@@ -67,10 +101,22 @@ export default {
|
||||
this.showAIAssistanceModal = false;
|
||||
},
|
||||
openAIAssist() {
|
||||
// Dismiss the CTA modal if it is not dismissed
|
||||
if (!this.isAICTAModalDismissed) {
|
||||
this.updateUISettings({
|
||||
is_open_ai_cta_modal_dismissed: true,
|
||||
});
|
||||
}
|
||||
this.initialMessage = this.draftMessage;
|
||||
const ninja = document.querySelector('ninja-keys');
|
||||
ninja.open({ parent: 'ai_assist' });
|
||||
},
|
||||
hideAICtaModal() {
|
||||
this.showAICtaModal = false;
|
||||
},
|
||||
openAICta() {
|
||||
this.showAICtaModal = true;
|
||||
},
|
||||
onAIAssist(option) {
|
||||
this.aiOption = option;
|
||||
this.showAIAssistanceModal = true;
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
<template>
|
||||
<div class="relative">
|
||||
<woot-button
|
||||
icon="wand"
|
||||
color-scheme="secondary"
|
||||
variant="smooth"
|
||||
size="small"
|
||||
class-names="cta-btn cta-btn-light dark:cta-btn-dark hover:cta-btn-light-hover dark:hover:cta-btn-dark-hover"
|
||||
@click="onClick"
|
||||
>
|
||||
{{ $t('INTEGRATION_SETTINGS.OPEN_AI.AI_ASSIST') }}
|
||||
</woot-button>
|
||||
|
||||
<div
|
||||
class="radar-ping-animation absolute top-0 right-0 -mt-1 -mr-1 rounded-full w-3 h-3 bg-woot-500 dark:bg-woot-500"
|
||||
/>
|
||||
<div
|
||||
class="absolute top-0 right-0 -mt-1 -mr-1 rounded-full w-3 h-3 bg-woot-500 dark:bg-woot-500 opacity-50"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
methods: {
|
||||
onClick() {
|
||||
this.$emit('click');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped>
|
||||
@tailwind components;
|
||||
@layer components {
|
||||
/* Gradient animation */
|
||||
@keyframes gradient {
|
||||
0% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
50% {
|
||||
background-position: 100% 50%;
|
||||
}
|
||||
100% {
|
||||
background-position: 0% 50%;
|
||||
}
|
||||
}
|
||||
.cta-btn {
|
||||
animation: gradient 5s ease infinite;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.cta-btn-light {
|
||||
background: linear-gradient(
|
||||
255.98deg,
|
||||
rgba(161, 87, 246, 0.2) 15.83%,
|
||||
rgba(71, 145, 247, 0.2) 81.39%
|
||||
),
|
||||
linear-gradient(0deg, #f2f5f8, #f2f5f8);
|
||||
}
|
||||
|
||||
.cta-btn-dark {
|
||||
background: linear-gradient(
|
||||
255.98deg,
|
||||
rgba(161, 87, 246, 0.2) 15.83%,
|
||||
rgba(71, 145, 247, 0.2) 81.39%
|
||||
),
|
||||
linear-gradient(0deg, #313538, #313538);
|
||||
}
|
||||
|
||||
.cta-btn-light-hover {
|
||||
background: linear-gradient(
|
||||
255.98deg,
|
||||
rgba(161, 87, 246, 0.2) 15.83%,
|
||||
rgba(71, 145, 247, 0.2) 81.39%
|
||||
),
|
||||
linear-gradient(0deg, #e3e5e7, #e3e5e7);
|
||||
}
|
||||
|
||||
.cta-btn-dark-hover {
|
||||
background: linear-gradient(
|
||||
255.98deg,
|
||||
rgba(161, 87, 246, 0.2) 15.83%,
|
||||
rgba(71, 145, 247, 0.2) 81.39%
|
||||
),
|
||||
linear-gradient(0deg, #202425, #202425);
|
||||
}
|
||||
|
||||
/* Radar ping animation */
|
||||
@keyframes ping {
|
||||
75%,
|
||||
100% {
|
||||
transform: scale(2);
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
.radar-ping-animation {
|
||||
animation: ping 1s ease infinite;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<div class="px-0 min-w-0 flex-1">
|
||||
<woot-modal-header
|
||||
:header-title="$t('INTEGRATION_SETTINGS.OPEN_AI.CTA_MODAL.TITLE')"
|
||||
:header-content="$t('INTEGRATION_SETTINGS.OPEN_AI.CTA_MODAL.DESC')"
|
||||
/>
|
||||
<form
|
||||
class="flex flex-wrap flex-col modal-content"
|
||||
@submit.prevent="finishOpenAI"
|
||||
>
|
||||
<div class="mt-2 w-full">
|
||||
<woot-input
|
||||
v-model="value"
|
||||
type="text"
|
||||
:class="{ error: $v.value.$error }"
|
||||
:placeholder="
|
||||
$t('INTEGRATION_SETTINGS.OPEN_AI.CTA_MODAL.KEY_PLACEHOLDER')
|
||||
"
|
||||
@blur="$v.value.$touch"
|
||||
/>
|
||||
</div>
|
||||
<div class="flex flex-row justify-between gap-2 py-2 px-0 w-full">
|
||||
<woot-button variant="link" @click.prevent="openOpenAIDoc">
|
||||
{{ $t('INTEGRATION_SETTINGS.OPEN_AI.CTA_MODAL.BUTTONS.NEED_HELP') }}
|
||||
</woot-button>
|
||||
<div class="flex items-center gap-1">
|
||||
<woot-button variant="clear" @click.prevent="onDismiss">
|
||||
{{ $t('INTEGRATION_SETTINGS.OPEN_AI.CTA_MODAL.BUTTONS.DISMISS') }}
|
||||
</woot-button>
|
||||
<woot-button :is-disabled="$v.value.$invalid">
|
||||
{{ $t('INTEGRATION_SETTINGS.OPEN_AI.CTA_MODAL.BUTTONS.FINISH') }}
|
||||
</woot-button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { required } from 'vuelidate/lib/validators';
|
||||
import { mapGetters } from 'vuex';
|
||||
import aiMixin from 'dashboard/mixins/aiMixin';
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
import uiSettingsMixin from 'dashboard/mixins/uiSettings';
|
||||
import { OPEN_AI_EVENTS } from 'dashboard/helper/AnalyticsHelper/events';
|
||||
|
||||
export default {
|
||||
mixins: [aiMixin, alertMixin, uiSettingsMixin],
|
||||
data() {
|
||||
return {
|
||||
value: '',
|
||||
};
|
||||
},
|
||||
validations: {
|
||||
value: {
|
||||
required,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
...mapGetters({
|
||||
appIntegrations: 'integrations/getAppIntegrations',
|
||||
}),
|
||||
},
|
||||
methods: {
|
||||
onClose() {
|
||||
this.$emit('close');
|
||||
},
|
||||
|
||||
onDismiss() {
|
||||
this.showAlert(
|
||||
this.$t('INTEGRATION_SETTINGS.OPEN_AI.CTA_MODAL.DISMISS_MESSAGE')
|
||||
);
|
||||
this.updateUISettings({
|
||||
is_open_ai_cta_modal_dismissed: true,
|
||||
});
|
||||
this.onClose();
|
||||
},
|
||||
|
||||
async finishOpenAI() {
|
||||
const payload = {
|
||||
app_id: 'openai',
|
||||
settings: {
|
||||
api_key: this.value,
|
||||
},
|
||||
};
|
||||
try {
|
||||
await this.$store.dispatch('integrations/createHook', payload);
|
||||
this.alertMessage = this.$t(
|
||||
'INTEGRATION_SETTINGS.OPEN_AI.CTA_MODAL.SUCCESS_MESSAGE'
|
||||
);
|
||||
this.recordAnalytics(
|
||||
OPEN_AI_EVENTS.ADDED_AI_INTEGRATION_VIA_CTA_BUTTON
|
||||
);
|
||||
this.onClose();
|
||||
} catch (error) {
|
||||
const errorMessage = error?.response?.data?.message;
|
||||
this.alertMessage =
|
||||
errorMessage || this.$t('INTEGRATION_APPS.ADD.API.ERROR_MESSAGE');
|
||||
} finally {
|
||||
this.showAlert(this.alertMessage);
|
||||
}
|
||||
},
|
||||
openOpenAIDoc() {
|
||||
window.open('https://www.chatwoot.com/blog/v2-17', '_blank');
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -61,11 +61,9 @@ export default {
|
||||
this.label = this.$t('AUTOMATION.ATTACHMENT.LABEL_UPLOADING');
|
||||
try {
|
||||
const file = event.target.files[0];
|
||||
const formData = new FormData();
|
||||
formData.append('attachment', file, file.name);
|
||||
const id = await this.$store.dispatch(
|
||||
'automations/uploadAttachment',
|
||||
formData
|
||||
file
|
||||
);
|
||||
this.$emit('input', [id]);
|
||||
this.uploadState = 'uploaded';
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<template>
|
||||
<button class="header-section back-button" @click.capture="goBack">
|
||||
<button
|
||||
class="header-section flex items-center text-base font-normal mr-4 ml-2 cursor-pointer text-woot-500 dark:text-woot-500"
|
||||
@click.capture="goBack"
|
||||
>
|
||||
<fluent-icon icon="chevron-left" />
|
||||
{{ buttonLabel || $t('GENERAL_SETTINGS.BACK') }}
|
||||
</button>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<div class="flex items-center text-left">
|
||||
<div class="flex items-center gap-1.5 text-left">
|
||||
<thumbnail
|
||||
:src="user.thumbnail"
|
||||
:size="size"
|
||||
@@ -7,7 +7,7 @@
|
||||
:status="user.availability_status"
|
||||
/>
|
||||
<h6
|
||||
class="my-0 mx-2 dark:text-slate-100 overflow-hidden whitespace-nowrap text-ellipsis text-capitalize"
|
||||
class="my-0 dark:text-slate-100 overflow-hidden whitespace-nowrap text-ellipsis text-capitalize"
|
||||
:class="textClass"
|
||||
>
|
||||
{{ user.name }}
|
||||
|
||||
@@ -15,6 +15,13 @@
|
||||
:search-key="variableSearchTerm"
|
||||
@click="insertVariable"
|
||||
/>
|
||||
<input
|
||||
ref="imageUpload"
|
||||
type="file"
|
||||
accept="image/png, image/jpeg, image/jpg, image/gif, image/webp"
|
||||
hidden
|
||||
@change="onFileChange"
|
||||
/>
|
||||
<div ref="editor" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -22,7 +29,7 @@
|
||||
<script>
|
||||
import {
|
||||
messageSchema,
|
||||
wootMessageWriterSetup,
|
||||
buildEditor,
|
||||
EditorView,
|
||||
MessageMarkdownTransformer,
|
||||
MessageMarkdownSerializer,
|
||||
@@ -39,6 +46,7 @@ import CannedResponse from '../conversation/CannedResponse';
|
||||
import VariableList from '../conversation/VariableList';
|
||||
|
||||
const TYPING_INDICATOR_IDLE_TIME = 4000;
|
||||
const MAXIMUM_FILE_UPLOAD_SIZE = 4; // in MB
|
||||
|
||||
import {
|
||||
hasPressedEnterAndNotCmdOrShift,
|
||||
@@ -51,14 +59,27 @@ import uiSettingsMixin from 'dashboard/mixins/uiSettings';
|
||||
import { isEditorHotKeyEnabled } from 'dashboard/mixins/uiSettings';
|
||||
import { replaceVariablesInMessage } from '@chatwoot/utils';
|
||||
import { CONVERSATION_EVENTS } from '../../../helper/AnalyticsHelper/events';
|
||||
import { checkFileSizeLimit } from 'shared/helpers/FileHelper';
|
||||
import { uploadFile } from 'dashboard/helper/uploadHelper';
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
import { findNodeToInsertImage } from 'dashboard/helper/messageEditorHelper';
|
||||
import { MESSAGE_EDITOR_MENU_OPTIONS } from 'dashboard/constants/editor';
|
||||
|
||||
const createState = (content, placeholder, plugins = []) => {
|
||||
const createState = (
|
||||
content,
|
||||
placeholder,
|
||||
plugins = [],
|
||||
methods = {},
|
||||
enabledMenuOptions
|
||||
) => {
|
||||
return EditorState.create({
|
||||
doc: new MessageMarkdownTransformer(messageSchema).parse(content),
|
||||
plugins: wootMessageWriterSetup({
|
||||
plugins: buildEditor({
|
||||
schema: messageSchema,
|
||||
placeholder,
|
||||
methods,
|
||||
plugins,
|
||||
enabledMenuOptions,
|
||||
}),
|
||||
});
|
||||
};
|
||||
@@ -66,7 +87,7 @@ const createState = (content, placeholder, plugins = []) => {
|
||||
export default {
|
||||
name: 'WootMessageEditor',
|
||||
components: { TagAgents, CannedResponse, VariableList },
|
||||
mixins: [eventListenerMixins, uiSettingsMixin],
|
||||
mixins: [eventListenerMixins, uiSettingsMixin, alertMixin],
|
||||
props: {
|
||||
value: { type: String, default: '' },
|
||||
editorId: { type: String, default: '' },
|
||||
@@ -78,6 +99,7 @@ export default {
|
||||
enableVariables: { type: Boolean, default: false },
|
||||
enableCannedResponses: { type: Boolean, default: true },
|
||||
variables: { type: Object, default: () => ({}) },
|
||||
enabledMenuOptions: { type: Array, default: () => [] },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -104,6 +126,11 @@ export default {
|
||||
this.enableCannedResponses && this.showCannedMenu && !this.isPrivate
|
||||
);
|
||||
},
|
||||
editorMenuOptions() {
|
||||
return this.enabledMenuOptions.length
|
||||
? this.enabledMenuOptions
|
||||
: MESSAGE_EDITOR_MENU_OPTIONS;
|
||||
},
|
||||
plugins() {
|
||||
if (!this.enableSuggestions) {
|
||||
return [];
|
||||
@@ -204,18 +231,18 @@ export default {
|
||||
showVariables(updatedValue) {
|
||||
this.$emit('toggle-variables-menu', !this.isPrivate && updatedValue);
|
||||
},
|
||||
value(newValue = '') {
|
||||
if (newValue !== this.contentFromEditor) {
|
||||
this.reloadState();
|
||||
value(newVal = '') {
|
||||
if (newVal !== this.contentFromEditor) {
|
||||
this.reloadState(newVal);
|
||||
}
|
||||
},
|
||||
editorId() {
|
||||
this.showCannedMenu = false;
|
||||
this.cannedSearchTerm = '';
|
||||
this.reloadState();
|
||||
this.reloadState(this.value);
|
||||
},
|
||||
isPrivate() {
|
||||
this.reloadState();
|
||||
this.reloadState(this.value);
|
||||
},
|
||||
|
||||
updateSelectionWith(newValue, oldValue) {
|
||||
@@ -238,7 +265,13 @@ export default {
|
||||
},
|
||||
},
|
||||
created() {
|
||||
this.state = createState(this.value, this.placeholder, this.plugins);
|
||||
this.state = createState(
|
||||
this.value,
|
||||
this.placeholder,
|
||||
this.plugins,
|
||||
{ onImageUpload: this.openFileBrowser },
|
||||
this.editorMenuOptions
|
||||
);
|
||||
},
|
||||
mounted() {
|
||||
this.createEditorView();
|
||||
@@ -246,8 +279,14 @@ export default {
|
||||
this.focusEditorInputField();
|
||||
},
|
||||
methods: {
|
||||
reloadState() {
|
||||
this.state = createState(this.value, this.placeholder, this.plugins);
|
||||
reloadState(content = this.value) {
|
||||
this.state = createState(
|
||||
content,
|
||||
this.placeholder,
|
||||
this.plugins,
|
||||
{ onImageUpload: this.openFileBrowser },
|
||||
this.editorMenuOptions
|
||||
);
|
||||
this.editorView.updateState(this.state);
|
||||
this.focusEditorInputField();
|
||||
},
|
||||
@@ -374,6 +413,57 @@ export default {
|
||||
tr.scrollIntoView();
|
||||
return false;
|
||||
},
|
||||
openFileBrowser() {
|
||||
this.$refs.imageUpload.click();
|
||||
},
|
||||
onFileChange() {
|
||||
const file = this.$refs.imageUpload.files[0];
|
||||
if (checkFileSizeLimit(file, MAXIMUM_FILE_UPLOAD_SIZE)) {
|
||||
this.uploadImageToStorage(file);
|
||||
} else {
|
||||
this.showAlert(
|
||||
this.$t(
|
||||
'PROFILE_SETTINGS.FORM.MESSAGE_SIGNATURE_SECTION.IMAGE_UPLOAD_SIZE_ERROR',
|
||||
{
|
||||
size: MAXIMUM_FILE_UPLOAD_SIZE,
|
||||
}
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
this.$refs.imageUpload.value = '';
|
||||
},
|
||||
async uploadImageToStorage(file) {
|
||||
try {
|
||||
const { fileUrl } = await uploadFile(file);
|
||||
if (fileUrl) {
|
||||
this.onImageInsertInEditor(fileUrl);
|
||||
}
|
||||
this.showAlert(
|
||||
this.$t(
|
||||
'PROFILE_SETTINGS.FORM.MESSAGE_SIGNATURE_SECTION.IMAGE_UPLOAD_SUCCESS'
|
||||
)
|
||||
);
|
||||
} catch (error) {
|
||||
this.showAlert(
|
||||
this.$t(
|
||||
'PROFILE_SETTINGS.FORM.MESSAGE_SIGNATURE_SECTION.IMAGE_UPLOAD_ERROR'
|
||||
)
|
||||
);
|
||||
}
|
||||
},
|
||||
onImageInsertInEditor(fileUrl) {
|
||||
const { tr } = this.editorView.state;
|
||||
|
||||
const insertData = findNodeToInsertImage(this.editorView.state, fileUrl);
|
||||
|
||||
if (insertData) {
|
||||
this.editorView.dispatch(
|
||||
tr.insert(insertData.pos, insertData.node).scrollIntoView()
|
||||
);
|
||||
this.focusEditorInputField();
|
||||
}
|
||||
},
|
||||
|
||||
emitOnChange() {
|
||||
this.editorView.updateState(this.state);
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
<script>
|
||||
import {
|
||||
fullSchema,
|
||||
wootArticleWriterSetup,
|
||||
buildEditor,
|
||||
EditorView,
|
||||
ArticleMarkdownSerializer,
|
||||
ArticleMarkdownTransformer,
|
||||
@@ -33,15 +33,17 @@ const createState = (
|
||||
content,
|
||||
placeholder,
|
||||
plugins = [],
|
||||
onImageUpload = () => {}
|
||||
methods = {},
|
||||
enabledMenuOptions
|
||||
) => {
|
||||
return EditorState.create({
|
||||
doc: new ArticleMarkdownTransformer(fullSchema).parse(content),
|
||||
plugins: wootArticleWriterSetup({
|
||||
plugins: buildEditor({
|
||||
schema: fullSchema,
|
||||
placeholder,
|
||||
methods,
|
||||
plugins,
|
||||
onImageUpload,
|
||||
enabledMenuOptions,
|
||||
}),
|
||||
});
|
||||
};
|
||||
@@ -52,6 +54,7 @@ export default {
|
||||
value: { type: String, default: '' },
|
||||
editorId: { type: String, default: '' },
|
||||
placeholder: { type: String, default: '' },
|
||||
enabledMenuOptions: { type: Array, default: () => [] },
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
@@ -83,7 +86,8 @@ export default {
|
||||
this.value,
|
||||
this.placeholder,
|
||||
this.plugins,
|
||||
this.openFileBrowser
|
||||
{ onImageUpload: this.openFileBrowser },
|
||||
this.enabledMenuOptions
|
||||
);
|
||||
},
|
||||
mounted() {
|
||||
@@ -152,7 +156,8 @@ export default {
|
||||
this.value,
|
||||
this.placeholder,
|
||||
this.plugins,
|
||||
this.openFileBrowser
|
||||
{ onImageUpload: this.openFileBrowser },
|
||||
this.enabledMenuOptions
|
||||
);
|
||||
this.editorView.updateState(this.state);
|
||||
this.focusEditorInputField();
|
||||
|
||||
+1
@@ -358,6 +358,7 @@ export default {
|
||||
applied_filters: this.appliedFilters.map(filter => ({
|
||||
key: filter.attribute_key,
|
||||
operator: filter.filter_operator,
|
||||
query_operator: filter.query_operator,
|
||||
})),
|
||||
});
|
||||
},
|
||||
|
||||
@@ -61,7 +61,7 @@ import { mapGetters } from 'vuex';
|
||||
import ContactPanel from 'dashboard/routes/dashboard/conversation/ContactPanel';
|
||||
import ConversationHeader from './ConversationHeader';
|
||||
import DashboardAppFrame from '../DashboardApp/Frame.vue';
|
||||
import EmptyState from './EmptyState';
|
||||
import EmptyState from './EmptyState/EmptyState';
|
||||
import MessagesView from './MessagesView';
|
||||
|
||||
export default {
|
||||
|
||||
@@ -8,7 +8,11 @@
|
||||
<div
|
||||
class="flex justify-center items-center mr-4 rtl:mr-0 rtl:ml-4 min-w-0"
|
||||
>
|
||||
<back-button v-if="showBackButton" :back-url="backButtonUrl" />
|
||||
<back-button
|
||||
v-if="showBackButton"
|
||||
:back-url="backButtonUrl"
|
||||
class="ltr:ml-0 rtl:mr-0 rtl:ml-4"
|
||||
/>
|
||||
<Thumbnail
|
||||
:src="currentContact.thumbnail"
|
||||
:badge="inboxBadge"
|
||||
|
||||
+21
-67
@@ -10,45 +10,40 @@
|
||||
class="clearfix"
|
||||
>
|
||||
<onboarding-view v-if="isAdmin" />
|
||||
<div v-else class="current-chat">
|
||||
<div>
|
||||
<img src="~dashboard/assets/images/inboxes.svg" alt="No Inboxes" />
|
||||
<span>
|
||||
{{ $t('CONVERSATION.NO_INBOX_AGENT') }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<empty-state-message
|
||||
v-else
|
||||
:message="$t('CONVERSATION.NO_INBOX_AGENT')"
|
||||
/>
|
||||
</div>
|
||||
<!-- Show empty state images if not loading -->
|
||||
|
||||
<div
|
||||
v-else-if="!uiFlags.isFetching && !loadingChatList"
|
||||
class="current-chat"
|
||||
class="flex flex-col items-center justify-center h-full"
|
||||
>
|
||||
<!-- No conversations available -->
|
||||
<div v-if="!allConversations.length">
|
||||
<img src="~dashboard/assets/images/chat.svg" alt="No Chat" />
|
||||
<span>
|
||||
{{ $t('CONVERSATION.NO_MESSAGE_1') }}
|
||||
<br />
|
||||
</span>
|
||||
</div>
|
||||
<!-- No conversation selected -->
|
||||
<div v-else-if="allConversations.length && !currentChat.id">
|
||||
<img src="~dashboard/assets/images/chat.svg" alt="No Chat" />
|
||||
<span>{{ conversationMissingMessage }}</span>
|
||||
</div>
|
||||
<empty-state-message
|
||||
v-if="!allConversations.length"
|
||||
:message="$t('CONVERSATION.NO_MESSAGE_1')"
|
||||
/>
|
||||
<empty-state-message
|
||||
v-else-if="allConversations.length && !currentChat.id"
|
||||
:message="conversationMissingMessage"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { mapGetters } from 'vuex';
|
||||
import adminMixin from '../../../mixins/isAdmin';
|
||||
import accountMixin from '../../../mixins/account';
|
||||
import OnboardingView from './OnboardingView';
|
||||
import adminMixin from 'dashboard/mixins/isAdmin';
|
||||
import accountMixin from 'dashboard/mixins/account';
|
||||
import OnboardingView from '../OnboardingView';
|
||||
import EmptyStateMessage from './EmptyStateMessage';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
OnboardingView,
|
||||
EmptyStateMessage,
|
||||
},
|
||||
mixins: [accountMixin, adminMixin],
|
||||
props: {
|
||||
@@ -87,51 +82,10 @@ export default {
|
||||
!this.loadingChatList &&
|
||||
this.isAdmin
|
||||
) {
|
||||
return 'inbox-empty-state';
|
||||
return 'h-full overflow-auto';
|
||||
}
|
||||
return 'columns conv-empty-state';
|
||||
return 'flex-1 min-w-0 px-0 flex flex-col items-center justify-center h-full';
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.inbox-empty-state {
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.current-chat {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
|
||||
img {
|
||||
margin: var(--space-normal);
|
||||
width: 6.25rem;
|
||||
}
|
||||
|
||||
span {
|
||||
font-size: var(--font-size-small);
|
||||
font-weight: var(--font-weight-medium);
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.conv-empty-state {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100vh;
|
||||
}
|
||||
</style>
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
<template>
|
||||
<div class="flex flex-col items-center justify-center h-full">
|
||||
<img
|
||||
class="m-4 w-32 hidden dark:block"
|
||||
src="~dashboard/assets/images/no-chat-dark.svg"
|
||||
alt="No Chat dark"
|
||||
/>
|
||||
<img
|
||||
class="m-4 w-32 block dark:hidden"
|
||||
src="~dashboard/assets/images/no-chat.svg"
|
||||
alt="No Chat"
|
||||
/>
|
||||
<span
|
||||
class="text-sm text-slate-800 dark:text-slate-200 font-medium text-center"
|
||||
>
|
||||
{{ message }}
|
||||
<br />
|
||||
</span>
|
||||
<!-- Cmd bar, keyboard shortcuts placeholder -->
|
||||
<feature-placeholder />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import FeaturePlaceholder from './FeaturePlaceholder.vue';
|
||||
export default {
|
||||
components: { FeaturePlaceholder },
|
||||
props: {
|
||||
message: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<div class="flex flex-col gap-2 mt-9">
|
||||
<div
|
||||
v-for="keyShortcut in keyShortcuts"
|
||||
:key="keyShortcut.key"
|
||||
class="flex gap-2 items-center"
|
||||
>
|
||||
<div class="flex gap-2 items-center">
|
||||
<hotkey
|
||||
custom-class="h-6 w-8 text-sm font-medium text-slate-700 dark:text-slate-100 bg-slate-100 dark:bg-slate-700 border-b-2 border-slate-300 dark:border-slate-500"
|
||||
>
|
||||
⌘
|
||||
</hotkey>
|
||||
<hotkey
|
||||
custom-class="h-6 w-8 text-sm font-medium text-slate-700 dark:text-slate-100 bg-slate-100 dark:bg-slate-700 border-b-2 border-slate-300 dark:border-slate-500"
|
||||
>
|
||||
{{ keyShortcut.key }}
|
||||
</hotkey>
|
||||
</div>
|
||||
<span
|
||||
class="text-sm text-slate-700 dark:text-slate-300 font-medium text-center"
|
||||
>
|
||||
{{ keyShortcut.description }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Hotkey from 'dashboard/components/base/Hotkey';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Hotkey,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
keyShortcuts: [
|
||||
{
|
||||
key: 'K',
|
||||
description: this.$t('CONVERSATION.EMPTY_STATE.CMD_BAR'),
|
||||
},
|
||||
{
|
||||
key: '/',
|
||||
description: this.$t('CONVERSATION.EMPTY_STATE.KEYBOARD_SHORTCUTS'),
|
||||
},
|
||||
],
|
||||
};
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -45,7 +45,7 @@
|
||||
/>
|
||||
<li v-show="unreadMessageCount != 0" class="unread--toast">
|
||||
<span>
|
||||
{{ unreadMessageCount }}
|
||||
{{ unreadMessageCount > 9 ? '9+' : unreadMessageCount }}
|
||||
{{
|
||||
unreadMessageCount > 1
|
||||
? $t('CONVERSATION.UNREAD_MESSAGES')
|
||||
@@ -314,7 +314,7 @@ export default {
|
||||
return '';
|
||||
},
|
||||
unreadMessageCount() {
|
||||
return this.currentChat.unread_count;
|
||||
return this.currentChat.unread_count || 0;
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -725,6 +725,15 @@ export default {
|
||||
this.sendMessage(messagePayload);
|
||||
});
|
||||
},
|
||||
sendMessageAnalyticsData(isPrivate) {
|
||||
// Analytics data for message signature is enabled or not in channels
|
||||
return isPrivate
|
||||
? this.$track(CONVERSATION_EVENTS.SENT_PRIVATE_NOTE)
|
||||
: this.$track(CONVERSATION_EVENTS.SENT_MESSAGE, {
|
||||
channelType: this.channelType,
|
||||
signatureEnabled: this.sendWithSignature,
|
||||
});
|
||||
},
|
||||
async onSendReply() {
|
||||
const undefinedVariables = getUndefinedVariablesInMessage({
|
||||
message: this.message,
|
||||
@@ -758,6 +767,7 @@ export default {
|
||||
bus.$emit(BUS_EVENTS.SCROLL_TO_MESSAGE);
|
||||
bus.$emit(BUS_EVENTS.MESSAGE_SENT);
|
||||
this.removeFromDraft();
|
||||
this.sendMessageAnalyticsData(messagePayload.private);
|
||||
} catch (error) {
|
||||
const errorMessage =
|
||||
error?.response?.data?.error || this.$t('CONVERSATION.MESSAGE_ERROR');
|
||||
|
||||
@@ -95,7 +95,7 @@ export default {
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mention--box {
|
||||
@apply bg-white text-sm dark:bg-slate-700 rounded-md overflow-auto absolute w-full z-[100] pt-2 px-2 pb-0 shadow-md left-0 leading-[1.2] bottom-full max-h-[12.5rem] border-t border-solid border-slate-75 dark:border-slate-800;
|
||||
@apply bg-white text-sm dark:bg-slate-700 rounded-md overflow-auto absolute w-full z-20 pt-2 px-2 pb-0 shadow-md left-0 leading-[1.2] bottom-full max-h-[12.5rem] border-t border-solid border-slate-75 dark:border-slate-800;
|
||||
|
||||
&.with-bottom-border {
|
||||
@apply border-b-[0.5rem] border-solid border-white dark:border-slate-600;
|
||||
|
||||
@@ -79,7 +79,7 @@ export default {
|
||||
|
||||
<style scoped lang="scss">
|
||||
.mention--box {
|
||||
@apply bg-white dark:bg-slate-700 rounded-md overflow-auto absolute w-full z-[100] pt-2 px-2 pb-0 shadow-md left-0 bottom-full max-h-[9.75rem] border-t border-solid border-slate-75 dark:border-slate-800;
|
||||
@apply bg-white dark:bg-slate-700 rounded-md overflow-auto absolute w-full z-20 pt-2 px-2 pb-0 shadow-md left-0 bottom-full max-h-[9.75rem] border-t border-solid border-slate-75 dark:border-slate-800;
|
||||
|
||||
.dropdown-menu__item:last-child {
|
||||
@apply pb-1;
|
||||
|
||||
@@ -4,22 +4,18 @@
|
||||
<woot-modal-header
|
||||
:header-title="$t('SIDEBAR_ITEMS.KEYBOARD_SHORTCUTS')"
|
||||
/>
|
||||
<div class="grid grid-cols-2 gap-x-5 gap-y-3 pt-0 px-8 pb-8 mt-6">
|
||||
<div class="grid grid-cols-2 gap-x-5 gap-y-3 pt-0 px-8 pb-4 mt-6">
|
||||
<div class="flex justify-between items-center min-w-[25rem]">
|
||||
<h5 class="text-sm text-slate-800 dark:text-slate-100">
|
||||
{{ $t('KEYBOARD_SHORTCUTS.TOGGLE_MODAL') }}
|
||||
</h5>
|
||||
<div class="flex items-center mb-1 ml-2">
|
||||
<p
|
||||
class="shortcut-key items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
|
||||
>
|
||||
<div class="flex items-center mb-1 ml-2 gap-2">
|
||||
<hotkey custom-class="min-h-[28px] min-w-[60px] normal-case key">
|
||||
{{ $t('KEYBOARD_SHORTCUTS.KEYS.WINDOWS_KEY_AND_COMMAND_KEY') }}
|
||||
</p>
|
||||
<p
|
||||
class="shortcut-key items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs flex justify-center min-w-[2rem] rtl:mr-0 rtl:ml-2"
|
||||
>
|
||||
</hotkey>
|
||||
<hotkey custom-class="min-h-[28px] min-w-[36px] key">
|
||||
{{ $t('KEYBOARD_SHORTCUTS.KEYS.FORWARD_SLASH_KEY') }}
|
||||
</p>
|
||||
</hotkey>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -29,34 +25,26 @@
|
||||
<h5 class="text-sm text-slate-800 dark:text-slate-100">
|
||||
{{ $t('KEYBOARD_SHORTCUTS.TITLE.OPEN_CONVERSATION') }}
|
||||
</h5>
|
||||
<div class="flex items-center mb-1 ml-2">
|
||||
<div class="flex mr-2">
|
||||
<span
|
||||
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
|
||||
>
|
||||
<div class="flex items-center mb-1 ml-2 gap-2">
|
||||
<div class="flex gap-2">
|
||||
<hotkey custom-class="min-h-[28px] min-w-[60px] normal-case key">
|
||||
{{ $t('KEYBOARD_SHORTCUTS.KEYS.ALT_OR_OPTION_KEY') }}
|
||||
</span>
|
||||
<span
|
||||
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
|
||||
>
|
||||
</hotkey>
|
||||
<hotkey custom-class="min-h-[28px] w-9 key">
|
||||
J
|
||||
</span>
|
||||
</hotkey>
|
||||
<span
|
||||
class="flex items-center font-semibold text-sm text-slate-800 dark:text-slate-100"
|
||||
>
|
||||
{{ $t('KEYBOARD_SHORTCUTS.KEYS.FORWARD_SLASH_KEY') }}
|
||||
</span>
|
||||
</div>
|
||||
<span
|
||||
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
|
||||
>
|
||||
<hotkey custom-class="min-h-[28px] min-w-[60px] normal-case key">
|
||||
{{ $t('KEYBOARD_SHORTCUTS.KEYS.ALT_OR_OPTION_KEY') }}
|
||||
</span>
|
||||
<span
|
||||
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs flex justify-center min-w-[2rem] rtl:mr-0 rtl:ml-2"
|
||||
>
|
||||
</hotkey>
|
||||
<hotkey custom-class="w-9 key">
|
||||
K
|
||||
</span>
|
||||
</hotkey>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -64,22 +52,16 @@
|
||||
<h5 class="text-sm text-slate-800 dark:text-slate-100">
|
||||
{{ $t('KEYBOARD_SHORTCUTS.TITLE.RESOLVE_AND_NEXT') }}
|
||||
</h5>
|
||||
<div class="flex items-center mb-1 ml-2">
|
||||
<span
|
||||
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
|
||||
>
|
||||
<div class="flex items-center mb-1 ml-2 gap-2">
|
||||
<hotkey custom-class="min-h-[28px] min-w-[60px] normal-case key">
|
||||
{{ $t('KEYBOARD_SHORTCUTS.KEYS.WINDOWS_KEY_AND_COMMAND_KEY') }}
|
||||
</span>
|
||||
<span
|
||||
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
|
||||
>
|
||||
</hotkey>
|
||||
<hotkey custom-class="min-h-[28px] min-w-[60px] normal-case key">
|
||||
{{ $t('KEYBOARD_SHORTCUTS.KEYS.ALT_OR_OPTION_KEY') }}
|
||||
</span>
|
||||
<span
|
||||
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs flex justify-center min-w-[2rem] rtl:mr-0 rtl:ml-2"
|
||||
>
|
||||
</hotkey>
|
||||
<hotkey custom-class="w-9 key">
|
||||
E
|
||||
</span>
|
||||
</hotkey>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -87,20 +69,22 @@
|
||||
:key="shortcutKey.id"
|
||||
class="flex justify-between items-center min-w-[25rem]"
|
||||
>
|
||||
<h5 class="text-sm text-slate-800 dark:text-slate-100">
|
||||
<h5 class="text-sm text-slate-800 min-w-[36px] dark:text-slate-100">
|
||||
{{ title(shortcutKey) }}
|
||||
</h5>
|
||||
<div class="flex items-center mb-1 ml-2">
|
||||
<span
|
||||
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs"
|
||||
<div class="flex items-center mb-1 ml-2 gap-2">
|
||||
<hotkey
|
||||
:class="{ 'min-w-[60px]': shortcutKey.firstKey !== 'Up' }"
|
||||
custom-class="min-h-[28px] normal-case key"
|
||||
>
|
||||
{{ shortcutKey.firstkey }}
|
||||
</span>
|
||||
<span
|
||||
class="items-center rounded-md mr-2 py-2 px-2.5 bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-semibold text-xs flex justify-center min-w-[2rem] rtl:mr-0 rtl:ml-2"
|
||||
{{ shortcutKey.firstKey }}
|
||||
</hotkey>
|
||||
<hotkey
|
||||
:class="{ 'normal-case': shortcutKey.secondKey === 'Down' }"
|
||||
custom-class="min-h-[28px] min-w-[36px] key"
|
||||
>
|
||||
{{ shortcutKey.secondKey }}
|
||||
</span>
|
||||
</hotkey>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -111,8 +95,12 @@
|
||||
<script>
|
||||
import { mixin as clickaway } from 'vue-clickaway';
|
||||
import { SHORTCUT_KEYS } from './constants';
|
||||
import Hotkey from 'dashboard/components/base/Hotkey';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Hotkey,
|
||||
},
|
||||
mixins: [clickaway],
|
||||
props: {
|
||||
show: {
|
||||
@@ -132,8 +120,8 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.shortcut-key {
|
||||
@apply py-2 px-2.5;
|
||||
<style scoped>
|
||||
.key {
|
||||
@apply py-2 px-2.5 font-semibold text-xs text-slate-700 dark:text-slate-100 bg-slate-75 dark:bg-slate-900 shadow border-b-2 rtl:border-l-2 ltr:border-r-2 border-slate-200 dark:border-slate-700;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -2,79 +2,79 @@ export const SHORTCUT_KEYS = [
|
||||
{
|
||||
id: 1,
|
||||
label: 'NAVIGATE_DROPDOWN',
|
||||
firstkey: 'Up',
|
||||
firstKey: 'Up',
|
||||
secondKey: 'Down',
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
label: 'RESOLVE_CONVERSATION',
|
||||
firstkey: 'Alt / ⌥',
|
||||
firstKey: 'Alt / ⌥',
|
||||
secondKey: 'E',
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
label: 'GO_TO_CONVERSATION_DASHBOARD',
|
||||
firstkey: 'Alt / ⌥',
|
||||
firstKey: 'Alt / ⌥',
|
||||
secondKey: 'C',
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
label: 'ADD_ATTACHMENT',
|
||||
firstkey: 'Alt / ⌥',
|
||||
firstKey: 'Alt / ⌥',
|
||||
secondKey: 'A',
|
||||
},
|
||||
{
|
||||
id: 5,
|
||||
label: 'GO_TO_CONTACTS_DASHBOARD',
|
||||
firstkey: 'Alt / ⌥',
|
||||
firstKey: 'Alt / ⌥',
|
||||
secondKey: 'V',
|
||||
},
|
||||
{
|
||||
id: 6,
|
||||
label: 'TOGGLE_SIDEBAR',
|
||||
firstkey: 'Alt / ⌥',
|
||||
firstKey: 'Alt / ⌥',
|
||||
secondKey: 'O',
|
||||
},
|
||||
{
|
||||
id: 7,
|
||||
label: 'GO_TO_REPORTS_SIDEBAR',
|
||||
firstkey: 'Alt / ⌥',
|
||||
firstKey: 'Alt / ⌥',
|
||||
secondKey: 'R',
|
||||
},
|
||||
{
|
||||
id: 8,
|
||||
label: 'MOVE_TO_NEXT_TAB',
|
||||
firstkey: 'Alt / ⌥',
|
||||
firstKey: 'Alt / ⌥',
|
||||
secondKey: 'N',
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
label: 'GO_TO_SETTINGS',
|
||||
firstkey: 'Alt / ⌥',
|
||||
firstKey: 'Alt / ⌥',
|
||||
secondKey: 'S',
|
||||
},
|
||||
{
|
||||
id: 10,
|
||||
label: 'SWITCH_CONVERSATION_STATUS',
|
||||
firstkey: 'Alt / ⌥',
|
||||
firstKey: 'Alt / ⌥',
|
||||
secondKey: 'B',
|
||||
},
|
||||
{
|
||||
id: 11,
|
||||
label: 'SWITCH_TO_PRIVATE_NOTE',
|
||||
firstkey: 'Alt / ⌥',
|
||||
firstKey: 'Alt / ⌥',
|
||||
secondKey: 'P',
|
||||
},
|
||||
{
|
||||
id: 13,
|
||||
label: 'SWITCH_TO_REPLY',
|
||||
firstkey: 'Alt / ⌥',
|
||||
firstKey: 'Alt / ⌥',
|
||||
secondKey: 'L',
|
||||
},
|
||||
{
|
||||
id: 14,
|
||||
label: 'TOGGLE_SNOOZE_DROPDOWN',
|
||||
firstkey: 'Alt / ⌥',
|
||||
firstKey: 'Alt / ⌥',
|
||||
secondKey: 'M',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
export const MESSAGE_EDITOR_MENU_OPTIONS = [
|
||||
'strong',
|
||||
'em',
|
||||
'link',
|
||||
'undo',
|
||||
'redo',
|
||||
'bulletList',
|
||||
'orderedList',
|
||||
'code',
|
||||
];
|
||||
|
||||
export const MESSAGE_SIGNATURE_EDITOR_MENU_OPTIONS = [
|
||||
'strong',
|
||||
'em',
|
||||
'link',
|
||||
'undo',
|
||||
'redo',
|
||||
'imageUpload',
|
||||
];
|
||||
|
||||
export const ARTICLE_EDITOR_MENU_OPTIONS = [
|
||||
'strong',
|
||||
'em',
|
||||
'link',
|
||||
'undo',
|
||||
'redo',
|
||||
'bulletList',
|
||||
'orderedList',
|
||||
'h1',
|
||||
'h2',
|
||||
'h3',
|
||||
'imageUpload',
|
||||
'code',
|
||||
];
|
||||
@@ -15,6 +15,9 @@ export const ACCOUNT_EVENTS = Object.freeze({
|
||||
ADDED_A_CUSTOM_ATTRIBUTE: 'Added a custom attribute',
|
||||
ADDED_AN_INBOX: 'Added an inbox',
|
||||
OPEN_MESSAGE_CONTEXT_MENU: 'Opened message context menu',
|
||||
OPENED_NOTIFICATIONS: 'Opened notifications',
|
||||
MARK_AS_READ_NOTIFICATIONS: 'Marked notifications as read',
|
||||
OPEN_CONVERSATION_VIA_NOTIFICATION: 'Opened conversation via notification',
|
||||
});
|
||||
|
||||
export const LABEL_EVENTS = Object.freeze({
|
||||
@@ -89,6 +92,8 @@ export const OPEN_AI_EVENTS = Object.freeze({
|
||||
SIMPLIFY: 'OpenAI: Used simplify',
|
||||
APPLY_LABEL_SUGGESTION: 'OpenAI: Apply label from suggestion',
|
||||
DISMISS_LABEL_SUGGESTION: 'OpenAI: Dismiss label suggestions',
|
||||
ADDED_AI_INTEGRATION_VIA_CTA_BUTTON:
|
||||
'OpenAI: Added AI integration via CTA button',
|
||||
DISMISS_AI_SUGGESTION: 'OpenAI: Dismiss AI suggestions',
|
||||
});
|
||||
|
||||
|
||||
@@ -30,6 +30,10 @@ const translationKeys = {
|
||||
'accountuser:create': `AUDIT_LOGS.ACCOUNT_USER.ADD`,
|
||||
'accountuser:update:self': `AUDIT_LOGS.ACCOUNT_USER.EDIT.SELF`,
|
||||
'accountuser:update:other': `AUDIT_LOGS.ACCOUNT_USER.EDIT.OTHER`,
|
||||
'inboxmember:create': `AUDIT_LOGS.INBOX_MEMBER.ADD`,
|
||||
'inboxmember:destroy': `AUDIT_LOGS.INBOX_MEMBER.REMOVE`,
|
||||
'teammember:create': `AUDIT_LOGS.TEAM_MEMBER.ADD`,
|
||||
'teammember:destroy': `AUDIT_LOGS.TEAM_MEMBER.REMOVE`,
|
||||
'account:update': `AUDIT_LOGS.ACCOUNT.EDIT`,
|
||||
};
|
||||
|
||||
@@ -102,6 +106,58 @@ function handleAccountUserUpdate(auditLogItem, translationPayload, agentList) {
|
||||
return translationPayload;
|
||||
}
|
||||
|
||||
function setUserInPayload(auditLogItem, translationPayload, agentList) {
|
||||
const userIdChange = auditLogItem.audited_changes.user_id;
|
||||
if (userIdChange && userIdChange !== undefined) {
|
||||
translationPayload.user = getAgentName(userIdChange, agentList);
|
||||
}
|
||||
return translationPayload;
|
||||
}
|
||||
|
||||
function setTeamIdInPayload(auditLogItem, translationPayload) {
|
||||
if (auditLogItem.audited_changes.team_id) {
|
||||
translationPayload.team_id = auditLogItem.audited_changes.team_id;
|
||||
}
|
||||
return translationPayload;
|
||||
}
|
||||
|
||||
function setInboxIdInPayload(auditLogItem, translationPayload) {
|
||||
if (auditLogItem.audited_changes.inbox_id) {
|
||||
translationPayload.inbox_id = auditLogItem.audited_changes.inbox_id;
|
||||
}
|
||||
return translationPayload;
|
||||
}
|
||||
|
||||
function handleInboxTeamMember(auditLogItem, translationPayload, agentList) {
|
||||
if (auditLogItem.audited_changes) {
|
||||
translationPayload = setUserInPayload(
|
||||
auditLogItem,
|
||||
translationPayload,
|
||||
agentList
|
||||
);
|
||||
translationPayload = setTeamIdInPayload(auditLogItem, translationPayload);
|
||||
translationPayload = setInboxIdInPayload(auditLogItem, translationPayload);
|
||||
}
|
||||
return translationPayload;
|
||||
}
|
||||
|
||||
function handleAccountUser(
|
||||
auditLogItem,
|
||||
translationPayload,
|
||||
agentList,
|
||||
action
|
||||
) {
|
||||
if (action === 'create') {
|
||||
return handleAccountUserCreate(auditLogItem, translationPayload, agentList);
|
||||
}
|
||||
|
||||
if (action === 'update') {
|
||||
return handleAccountUserUpdate(auditLogItem, translationPayload, agentList);
|
||||
}
|
||||
|
||||
return translationPayload;
|
||||
}
|
||||
|
||||
export function generateTranslationPayload(auditLogItem, agentList) {
|
||||
let translationPayload = {
|
||||
agentName: getAgentName(auditLogItem.user_id, agentList),
|
||||
@@ -112,21 +168,20 @@ export function generateTranslationPayload(auditLogItem, agentList) {
|
||||
const action = auditLogItem.action.toLowerCase();
|
||||
|
||||
if (auditableType === 'accountuser') {
|
||||
if (action === 'create') {
|
||||
translationPayload = handleAccountUserCreate(
|
||||
auditLogItem,
|
||||
translationPayload,
|
||||
agentList
|
||||
);
|
||||
}
|
||||
translationPayload = handleAccountUser(
|
||||
auditLogItem,
|
||||
translationPayload,
|
||||
agentList,
|
||||
action
|
||||
);
|
||||
}
|
||||
|
||||
if (action === 'update') {
|
||||
translationPayload = handleAccountUserUpdate(
|
||||
auditLogItem,
|
||||
translationPayload,
|
||||
agentList
|
||||
);
|
||||
}
|
||||
if (auditableType === 'inboxmember' || auditableType === 'teammember') {
|
||||
translationPayload = handleInboxTeamMember(
|
||||
auditLogItem,
|
||||
translationPayload,
|
||||
agentList
|
||||
);
|
||||
}
|
||||
|
||||
return translationPayload;
|
||||
|
||||
@@ -120,9 +120,18 @@ export const generateConditionOptions = (options, key = 'id') => {
|
||||
});
|
||||
};
|
||||
|
||||
// Add the "None" option to the agent list
|
||||
export const agentList = agents => [
|
||||
{
|
||||
id: 'nil',
|
||||
name: 'None',
|
||||
},
|
||||
...(agents || []),
|
||||
];
|
||||
|
||||
export const getActionOptions = ({ agents, teams, labels, type }) => {
|
||||
const actionsMap = {
|
||||
assign_agent: agents,
|
||||
assign_agent: agentList(agents),
|
||||
assign_team: teams,
|
||||
send_email_to_team: teams,
|
||||
add_label: generateConditionOptions(labels, 'title'),
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
/**
|
||||
* Determines the appropriate node and position to insert an image in the editor.
|
||||
*
|
||||
* Based on the current editor state and the provided image URL, this function finds out the correct node (either
|
||||
* a standalone image node or an image wrapped in a paragraph) and its respective position in the editor.
|
||||
*
|
||||
* 1. If the current node is a paragraph and doesn't contain an image or text, the image is inserted directly into it.
|
||||
* 2. If the current node isn't a paragraph or it's a paragraph containing text, the image will be wrapped
|
||||
* in a new paragraph and then inserted.
|
||||
* 3. If the current node is a paragraph containing an image, the new image will be inserted directly into it.
|
||||
*
|
||||
* @param {Object} editorState - The current state of the editor. It provides necessary details like selection, schema, etc.
|
||||
* @param {string} fileUrl - The URL of the image to be inserted into the editor.
|
||||
* @returns {Object|null} An object containing details about the node to be inserted and its position. It returns null if no image node can be created.
|
||||
* @property {Node} node - The ProseMirror node to be inserted (either an image node or a paragraph containing the image).
|
||||
* @property {number} pos - The position where the new node should be inserted in the editor.
|
||||
*/
|
||||
|
||||
export const findNodeToInsertImage = (editorState, fileUrl) => {
|
||||
const { selection, schema } = editorState;
|
||||
const { nodes } = schema;
|
||||
const currentNode = selection.$from.node();
|
||||
const {
|
||||
type: { name: typeName },
|
||||
content: { size, content },
|
||||
} = currentNode;
|
||||
|
||||
const imageNode = nodes.image.create({ src: fileUrl });
|
||||
|
||||
if (!imageNode) return null;
|
||||
|
||||
const isInParagraph = typeName === 'paragraph';
|
||||
const needsNewLine =
|
||||
!content.some(n => n.type.name === 'image') && size !== 0 ? 1 : 0;
|
||||
|
||||
return {
|
||||
node: isInParagraph ? imageNode : nodes.paragraph.create({}, imageNode),
|
||||
pos: selection.from + needsNewLine,
|
||||
};
|
||||
};
|
||||
@@ -49,3 +49,38 @@ export const validateLoggedInRoutes = (to, user, roleWiseRoutes) => {
|
||||
// Proceed to the route if none of the above conditions are met
|
||||
return null;
|
||||
};
|
||||
|
||||
export const isAConversationRoute = routeName =>
|
||||
[
|
||||
'inbox_conversation',
|
||||
'conversation_through_mentions',
|
||||
'conversation_through_unattended',
|
||||
'conversation_through_inbox',
|
||||
'conversations_through_label',
|
||||
'conversations_through_team',
|
||||
'conversations_through_folders',
|
||||
'conversation_through_participating',
|
||||
].includes(routeName);
|
||||
|
||||
export const getConversationDashboardRoute = routeName => {
|
||||
switch (routeName) {
|
||||
case 'inbox_conversation':
|
||||
return 'home';
|
||||
case 'conversation_through_mentions':
|
||||
return 'conversation_mentions';
|
||||
case 'conversation_through_unattended':
|
||||
return 'conversation_unattended';
|
||||
case 'conversations_through_label':
|
||||
return 'label_conversations';
|
||||
case 'conversations_through_team':
|
||||
return 'team_conversations';
|
||||
case 'conversations_through_folders':
|
||||
return 'folder_conversations';
|
||||
case 'conversation_through_participating':
|
||||
return 'conversation_participating';
|
||||
case 'conversation_through_inbox':
|
||||
return 'inbox_dashboard';
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -98,6 +98,48 @@ describe('Helper functions', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle InboxMember or TeamMember', () => {
|
||||
const auditLogItemInboxMember = {
|
||||
auditable_type: 'InboxMember',
|
||||
action: 'create',
|
||||
audited_changes: {
|
||||
user_id: 2,
|
||||
},
|
||||
user_id: 1,
|
||||
auditable_id: 789,
|
||||
};
|
||||
|
||||
const payloadInboxMember = generateTranslationPayload(
|
||||
auditLogItemInboxMember,
|
||||
agentList
|
||||
);
|
||||
expect(payloadInboxMember).toEqual({
|
||||
agentName: 'Agent 1',
|
||||
id: 789,
|
||||
user: 'Agent 2',
|
||||
});
|
||||
|
||||
const auditLogItemTeamMember = {
|
||||
auditable_type: 'TeamMember',
|
||||
action: 'create',
|
||||
audited_changes: {
|
||||
user_id: 3,
|
||||
},
|
||||
user_id: 1,
|
||||
auditable_id: 789,
|
||||
};
|
||||
|
||||
const payloadTeamMember = generateTranslationPayload(
|
||||
auditLogItemTeamMember,
|
||||
agentList
|
||||
);
|
||||
expect(payloadTeamMember).toEqual({
|
||||
agentName: 'Agent 1',
|
||||
id: 789,
|
||||
user: 'Agent 3',
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle generic case like Team create', () => {
|
||||
const auditLogItem = {
|
||||
auditable_type: 'Team',
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
import { findNodeToInsertImage } from '../messageEditorHelper';
|
||||
|
||||
describe('findNodeToInsertImage', () => {
|
||||
let mockEditorState;
|
||||
|
||||
beforeEach(() => {
|
||||
mockEditorState = {
|
||||
selection: {
|
||||
$from: {
|
||||
node: jest.fn(() => ({})),
|
||||
},
|
||||
from: 0,
|
||||
},
|
||||
schema: {
|
||||
nodes: {
|
||||
image: {
|
||||
create: jest.fn(attrs => ({ type: { name: 'image' }, attrs })),
|
||||
},
|
||||
paragraph: {
|
||||
create: jest.fn((_, node) => ({
|
||||
type: { name: 'paragraph' },
|
||||
content: [node],
|
||||
})),
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it('should insert image directly into an empty paragraph', () => {
|
||||
const mockNode = {
|
||||
type: { name: 'paragraph' },
|
||||
content: { size: 0, content: [] },
|
||||
};
|
||||
mockEditorState.selection.$from.node.mockReturnValueOnce(mockNode);
|
||||
|
||||
const result = findNodeToInsertImage(mockEditorState, 'image-url');
|
||||
expect(result).toEqual({
|
||||
node: { type: { name: 'image' }, attrs: { src: 'image-url' } },
|
||||
pos: 0,
|
||||
});
|
||||
});
|
||||
|
||||
it('should insert image directly into a paragraph without an image but with other content', () => {
|
||||
const mockNode = {
|
||||
type: { name: 'paragraph' },
|
||||
content: {
|
||||
size: 1,
|
||||
content: [
|
||||
{
|
||||
type: { name: 'text' },
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
mockEditorState.selection.$from.node.mockReturnValueOnce(mockNode);
|
||||
mockEditorState.selection.from = 1;
|
||||
|
||||
const result = findNodeToInsertImage(mockEditorState, 'image-url');
|
||||
expect(result).toEqual({
|
||||
node: { type: { name: 'image' }, attrs: { src: 'image-url' } },
|
||||
pos: 2, // Because it should insert after the text, on a new line.
|
||||
});
|
||||
});
|
||||
|
||||
it("should wrap image in a new paragraph when the current node isn't a paragraph", () => {
|
||||
const mockNode = {
|
||||
type: { name: 'not-a-paragraph' },
|
||||
content: { size: 0, content: [] },
|
||||
};
|
||||
mockEditorState.selection.$from.node.mockReturnValueOnce(mockNode);
|
||||
|
||||
const result = findNodeToInsertImage(mockEditorState, 'image-url');
|
||||
expect(result.node.type.name).toBe('paragraph');
|
||||
expect(result.node.content[0].type.name).toBe('image');
|
||||
expect(result.node.content[0].attrs.src).toBe('image-url');
|
||||
expect(result.pos).toBe(0);
|
||||
});
|
||||
|
||||
it('should insert a new image directly into the paragraph that already contains an image', () => {
|
||||
const mockNode = {
|
||||
type: { name: 'paragraph' },
|
||||
content: {
|
||||
size: 1,
|
||||
content: [
|
||||
{
|
||||
type: { name: 'image', attrs: { src: 'existing-image-url' } },
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
mockEditorState.selection.$from.node.mockReturnValueOnce(mockNode);
|
||||
mockEditorState.selection.from = 1;
|
||||
|
||||
const result = findNodeToInsertImage(mockEditorState, 'image-url');
|
||||
expect(result.node.type.name).toBe('image');
|
||||
expect(result.node.attrs.src).toBe('image-url');
|
||||
expect(result.pos).toBe(1);
|
||||
});
|
||||
});
|
||||
@@ -1,6 +1,8 @@
|
||||
import {
|
||||
getConversationDashboardRoute,
|
||||
getCurrentAccount,
|
||||
getUserRole,
|
||||
isAConversationRoute,
|
||||
routeIsAccessibleFor,
|
||||
validateLoggedInRoutes,
|
||||
} from '../routeHelpers';
|
||||
@@ -94,3 +96,41 @@ describe('#validateLoggedInRoutes', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('isAConversationRoute', () => {
|
||||
it('returns true if conversation route name is provided', () => {
|
||||
expect(isAConversationRoute('inbox_conversation')).toBe(true);
|
||||
expect(isAConversationRoute('conversation_through_inbox')).toBe(true);
|
||||
expect(isAConversationRoute('conversations_through_label')).toBe(true);
|
||||
expect(isAConversationRoute('conversations_through_team')).toBe(true);
|
||||
expect(isAConversationRoute('dashboard')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getConversationDashboardRoute', () => {
|
||||
it('returns dashboard route for conversation', () => {
|
||||
expect(getConversationDashboardRoute('inbox_conversation')).toEqual('home');
|
||||
expect(
|
||||
getConversationDashboardRoute('conversation_through_mentions')
|
||||
).toEqual('conversation_mentions');
|
||||
expect(
|
||||
getConversationDashboardRoute('conversation_through_unattended')
|
||||
).toEqual('conversation_unattended');
|
||||
expect(
|
||||
getConversationDashboardRoute('conversations_through_label')
|
||||
).toEqual('label_conversations');
|
||||
expect(getConversationDashboardRoute('conversations_through_team')).toEqual(
|
||||
'team_conversations'
|
||||
);
|
||||
expect(
|
||||
getConversationDashboardRoute('conversations_through_folders')
|
||||
).toEqual('folder_conversations');
|
||||
expect(
|
||||
getConversationDashboardRoute('conversation_through_participating')
|
||||
).toEqual('conversation_participating');
|
||||
expect(getConversationDashboardRoute('conversation_through_inbox')).toEqual(
|
||||
'inbox_dashboard'
|
||||
);
|
||||
expect(getConversationDashboardRoute('non_existent_route')).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
import { uploadFile } from '../uploadHelper';
|
||||
import axios from 'axios';
|
||||
|
||||
// Mocking axios using jest-mock-axios
|
||||
global.axios = axios;
|
||||
jest.mock('axios');
|
||||
|
||||
describe('#Upload Helpers', () => {
|
||||
afterEach(() => {
|
||||
// Cleaning up the mock after each test
|
||||
axios.post.mockReset();
|
||||
});
|
||||
|
||||
it('should send a POST request with correct data', async () => {
|
||||
const mockFile = new File(['dummy content'], 'example.png', {
|
||||
type: 'image/png',
|
||||
});
|
||||
const mockResponse = {
|
||||
data: {
|
||||
file_url: 'https://example.com/fileUrl',
|
||||
blob_key: 'blobKey123',
|
||||
blob_id: 'blobId456',
|
||||
},
|
||||
};
|
||||
|
||||
axios.post.mockResolvedValueOnce(mockResponse);
|
||||
|
||||
const result = await uploadFile(mockFile);
|
||||
|
||||
expect(axios.post).toHaveBeenCalledWith(
|
||||
'/api/v1/upload',
|
||||
expect.any(FormData),
|
||||
{ headers: { 'Content-Type': 'multipart/form-data' } }
|
||||
);
|
||||
|
||||
expect(result).toEqual({
|
||||
fileUrl: 'https://example.com/fileUrl',
|
||||
blobKey: 'blobKey123',
|
||||
blobId: 'blobId456',
|
||||
});
|
||||
});
|
||||
|
||||
it('should handle errors', async () => {
|
||||
const mockFile = new File(['dummy content'], 'example.png', {
|
||||
type: 'image/png',
|
||||
});
|
||||
const mockError = new Error('Failed to upload');
|
||||
|
||||
axios.post.mockRejectedValueOnce(mockError);
|
||||
|
||||
await expect(uploadFile(mockFile)).rejects.toThrow('Failed to upload');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,41 @@
|
||||
/* global axios */
|
||||
|
||||
/**
|
||||
* Constants and Configuration
|
||||
*/
|
||||
|
||||
// Version for the API endpoint.
|
||||
const API_VERSION = 'v1';
|
||||
|
||||
// Default headers to be used in the axios request.
|
||||
const HEADERS = {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
};
|
||||
|
||||
/**
|
||||
* Uploads a file to the server.
|
||||
*
|
||||
* This function sends a POST request to a given API endpoint and uploads the specified file.
|
||||
* The function uses FormData to wrap the file and axios to send the request.
|
||||
*
|
||||
* @param {File} file - The file to be uploaded. It should be a File object (typically coming from a file input element).
|
||||
* @returns {Promise} A promise that resolves with the server's response when the upload is successful, or rejects if there's an error.
|
||||
*/
|
||||
export async function uploadFile(file) {
|
||||
// Create a new FormData instance.
|
||||
let formData = new FormData();
|
||||
|
||||
// Append the file to the FormData instance under the key 'attachment'.
|
||||
formData.append('attachment', file);
|
||||
|
||||
// Use axios to send a POST request to the upload endpoint.
|
||||
const { data } = await axios.post(`/api/${API_VERSION}/upload`, formData, {
|
||||
headers: HEADERS,
|
||||
});
|
||||
|
||||
return {
|
||||
fileUrl: data.file_url,
|
||||
blobKey: data.blob_key,
|
||||
blobId: data.blob_id,
|
||||
};
|
||||
}
|
||||
@@ -26,6 +26,7 @@ import pt_BR from './locale/pt_BR';
|
||||
import ro from './locale/ro';
|
||||
import ru from './locale/ru';
|
||||
import sk from './locale/sk';
|
||||
import sr from './locale/sr';
|
||||
import sv from './locale/sv';
|
||||
import ta from './locale/ta';
|
||||
import th from './locale/th';
|
||||
@@ -66,6 +67,7 @@ export default {
|
||||
ro,
|
||||
ru,
|
||||
sk,
|
||||
sr,
|
||||
sv,
|
||||
ta,
|
||||
th,
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
{
|
||||
"FILTER": {
|
||||
"TITLE": "Filter Conversations",
|
||||
"SUBTITLE": "Add filters below and hit 'Apply filters' to filter conversations.",
|
||||
"EDIT_CUSTOM_FILTER": "Edit Folder",
|
||||
"CUSTOM_VIEWS_SUBTITLE": "Add or remove filters and update your folder.",
|
||||
"ADD_NEW_FILTER": "Add Filter",
|
||||
"FILTER_DELETE_ERROR": "You should have atleast one filter to save",
|
||||
"SUBMIT_BUTTON_LABEL": "Apply filters",
|
||||
"UPDATE_BUTTON_LABEL": "Update folder",
|
||||
"CANCEL_BUTTON_LABEL": "Cancel",
|
||||
"CLEAR_BUTTON_LABEL": "Clear Filters",
|
||||
"EMPTY_VALUE_ERROR": "Value is required",
|
||||
"FOLDER_LABEL": "Folder Name",
|
||||
"FOLDER_QUERY_LABEL": "Folder Query",
|
||||
"TOOLTIP_LABEL": "Filter conversations",
|
||||
"QUERY_DROPDOWN_LABELS": {
|
||||
"AND": "AND",
|
||||
"OR": "OR"
|
||||
},
|
||||
"OPERATOR_LABELS": {
|
||||
"equal_to": "Equal to",
|
||||
"not_equal_to": "Not equal to",
|
||||
"contains": "Contains",
|
||||
"does_not_contain": "Does not contain",
|
||||
"is_present": "Is present",
|
||||
"is_not_present": "Is not present",
|
||||
"is_greater_than": "Is greater than",
|
||||
"is_less_than": "Is lesser than",
|
||||
"days_before": "Is x days before",
|
||||
"starts_with": "Starts with"
|
||||
},
|
||||
"ATTRIBUTE_LABELS": {
|
||||
"TRUE": "True",
|
||||
"FALSE": "False"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"STATUS": "Status",
|
||||
"ASSIGNEE_NAME": "Assignee Name",
|
||||
"INBOX_NAME": "Inbox Name",
|
||||
"TEAM_NAME": "Team Name",
|
||||
"CONVERSATION_IDENTIFIER": "Conversation Identifier",
|
||||
"CAMPAIGN_NAME": "Campaign Name",
|
||||
"LABELS": "Labels",
|
||||
"BROWSER_LANGUAGE": "Browser Language",
|
||||
"PRIORITY": "Priority",
|
||||
"COUNTRY_NAME": "Country Name",
|
||||
"REFERER_LINK": "Referer link",
|
||||
"CUSTOM_ATTRIBUTE_LIST": "List",
|
||||
"CUSTOM_ATTRIBUTE_TEXT": "Text",
|
||||
"CUSTOM_ATTRIBUTE_NUMBER": "Number",
|
||||
"CUSTOM_ATTRIBUTE_LINK": "Link",
|
||||
"CUSTOM_ATTRIBUTE_CHECKBOX": "Checkbox",
|
||||
"CREATED_AT": "Created At",
|
||||
"LAST_ACTIVITY": "Last Activity"
|
||||
},
|
||||
"GROUPS": {
|
||||
"STANDARD_FILTERS": "Standard Filters",
|
||||
"ADDITIONAL_FILTERS": "Additional Filters",
|
||||
"CUSTOM_ATTRIBUTES": "Custom Attributes"
|
||||
},
|
||||
"CUSTOM_VIEWS": {
|
||||
"ADD": {
|
||||
"TITLE": "Do you want to save this filter?",
|
||||
"LABEL": "Name this filter",
|
||||
"PLACEHOLDER": "Enter a name for this filter",
|
||||
"ERROR_MESSAGE": "Name is required",
|
||||
"SAVE_BUTTON": "Save filter",
|
||||
"CANCEL_BUTTON": "Cancel",
|
||||
"API_FOLDERS": {
|
||||
"SUCCESS_MESSAGE": "Folder created successfully",
|
||||
"ERROR_MESSAGE": "Error while creating folder"
|
||||
},
|
||||
"API_SEGMENTS": {
|
||||
"SUCCESS_MESSAGE": "Segment created successfully",
|
||||
"ERROR_MESSAGE": "Error while creating segment"
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"EDIT_BUTTON": "Edit folder"
|
||||
},
|
||||
"DELETE": {
|
||||
"DELETE_BUTTON": "Delete filter",
|
||||
"MODAL": {
|
||||
"CONFIRM": {
|
||||
"TITLE": "Confirm Deletion",
|
||||
"MESSAGE": "Are you sure to delete the filter ",
|
||||
"YES": "Yes, Delete",
|
||||
"NO": "No, Keep it"
|
||||
}
|
||||
},
|
||||
"API_FOLDERS": {
|
||||
"SUCCESS_MESSAGE": "Folder deleted successfully",
|
||||
"ERROR_MESSAGE": "Error while deleting folder"
|
||||
},
|
||||
"API_SEGMENTS": {
|
||||
"SUCCESS_MESSAGE": "Segment deleted successfully",
|
||||
"ERROR_MESSAGE": "Error while deleting segment"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
{
|
||||
"AGENT_BOTS": {
|
||||
"HEADER": "Bots",
|
||||
"LOADING_EDITOR": "Loading Editor...",
|
||||
"HEADER_BTN_TXT": "Add Bot Configuration",
|
||||
"SIDEBAR_TXT": "<p><b>Agent Bots</b> <p>Agent bots allows you to automate the conversations</p>",
|
||||
"CSML_BOT_EDITOR": {
|
||||
"NAME": {
|
||||
"LABEL": "Bot Name",
|
||||
"PLACEHOLDER": "Give your bot a name",
|
||||
"ERROR": "Bot name is required"
|
||||
},
|
||||
"DESCRIPTION": {
|
||||
"LABEL": "Bot Description",
|
||||
"PLACEHOLDER": "What does this bot do?"
|
||||
},
|
||||
"BOT_CONFIG": {
|
||||
"ERROR": "Please enter your CSML bot configuration above",
|
||||
"API_ERROR": "Your CSML configuration is invalid, please fix it and try again."
|
||||
},
|
||||
"SUBMIT": "Validate and save"
|
||||
},
|
||||
"BOT_CONFIGURATION": {
|
||||
"TITLE": "Select an agent bot",
|
||||
"DESC": "You can set an agent bot from the list to this inbox. The bot can initially handle the conversation and transfer it to an agent when needed.",
|
||||
"SUBMIT": "Update",
|
||||
"DISCONNECT": "Disconnect Bot",
|
||||
"SUCCESS_MESSAGE": "Successfully updated the agent bot",
|
||||
"DISCONNECTED_SUCCESS_MESSAGE": "Successfully disconnected the agent bot",
|
||||
"ERROR_MESSAGE": "Could not update the agent bot, please try again later",
|
||||
"DISCONNECTED_ERROR_MESSAGE": "Could not disconnect the agent bot, please try again later",
|
||||
"SELECT_PLACEHOLDER": "Select Bot"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Configure new bot",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Bot added successfully",
|
||||
"ERROR_MESSAGE": "Could not add bot, Please try again later"
|
||||
}
|
||||
},
|
||||
"LIST": {
|
||||
"404": "No Bots found, you can create a bot by clicking the 'Configure new bot' Button ↗",
|
||||
"LOADING": "Fetching Bots...",
|
||||
"TYPE": "Bot Type"
|
||||
},
|
||||
"DELETE": {
|
||||
"BUTTON_TEXT": "Delete",
|
||||
"TITLE": "Delete Bot",
|
||||
"SUBMIT": "Delete",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel",
|
||||
"DESCRIPTION": "Are you sure you want to delete this bot? This action is irreversible",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Bot deleted successfully",
|
||||
"ERROR_MESSAGE": "Could not able to delete bot, Please try again later"
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"BUTTON_TEXT": "Edit",
|
||||
"LOADING": "Fetching Bots...",
|
||||
"TITLE": "Edit Bot",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Bot updated successfully",
|
||||
"ERROR_MESSAGE": "Could not update bot, Please try again later"
|
||||
}
|
||||
},
|
||||
"TYPES": {
|
||||
"WEBHOOK": "Webhook Bot",
|
||||
"CSML": "CSML Bot"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
{
|
||||
"AGENT_MGMT": {
|
||||
"HEADER": "Agents",
|
||||
"HEADER_BTN_TXT": "Add Agent",
|
||||
"LOADING": "Fetching Agent List",
|
||||
"SIDEBAR_TXT": "<p><b>Agents</b></p> <p> An <b>Agent</b> is a member of your Customer Support team. </p><p> Agents will be able to view and reply to messages from your users. The list shows all agents currently in your account. </p><p> Click on <b>Add Agent</b> to add a new agent. Agent you add will receive an email with a confirmation link to activate their account, after which they can access Chatwoot and respond to messages. </p><p> Access to Chatwoot's features are based on following roles. </p><p> <b>Agent</b> - Agents with this role can only access inboxes, reports and conversations. They can assign conversations to other agents or themselves and resolve conversations.</p><p> <b>Administrator</b> - Administrator will have access to all Chatwoot features enabled for your account, including settings, along with all of a normal agents' privileges.</p>",
|
||||
"AGENT_TYPES": {
|
||||
"ADMINISTRATOR": "Administrator",
|
||||
"AGENT": "Agent"
|
||||
},
|
||||
"LIST": {
|
||||
"404": "There are no agents associated to this account",
|
||||
"TITLE": "Manage agents in your team",
|
||||
"DESC": "You can add/remove agents to/in your team.",
|
||||
"NAME": "Name",
|
||||
"EMAIL": "EMAIL",
|
||||
"STATUS": "Status",
|
||||
"ACTIONS": "Actions",
|
||||
"VERIFIED": "Verified",
|
||||
"VERIFICATION_PENDING": "Verification Pending"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Add agent to your team",
|
||||
"DESC": "You can add people who will be able to handle support for your inboxes.",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel",
|
||||
"FORM": {
|
||||
"NAME": {
|
||||
"LABEL": "Agent Name",
|
||||
"PLACEHOLDER": "Please enter a name of the agent"
|
||||
},
|
||||
"AGENT_TYPE": {
|
||||
"LABEL": "Role",
|
||||
"PLACEHOLDER": "Please select a role",
|
||||
"ERROR": "Role is required"
|
||||
},
|
||||
"EMAIL": {
|
||||
"LABEL": "Email Address",
|
||||
"PLACEHOLDER": "Please enter an email address of the agent"
|
||||
},
|
||||
"SUBMIT": "Add Agent"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Agent added successfully",
|
||||
"EXIST_MESSAGE": "Agent email already in use, Please try another email address",
|
||||
"ERROR_MESSAGE": "Could not connect to Woot Server, Please try again later"
|
||||
}
|
||||
},
|
||||
"DELETE": {
|
||||
"BUTTON_TEXT": "Delete",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Agent deleted successfully",
|
||||
"ERROR_MESSAGE": "Could not connect to Woot Server, Please try again later"
|
||||
},
|
||||
"CONFIRM": {
|
||||
"TITLE": "Confirm Deletion",
|
||||
"MESSAGE": "Are you sure to delete ",
|
||||
"YES": "Yes, Delete ",
|
||||
"NO": "No, Keep "
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Edit agent",
|
||||
"FORM": {
|
||||
"NAME": {
|
||||
"LABEL": "Agent Name",
|
||||
"PLACEHOLDER": "Please enter a name of the agent"
|
||||
},
|
||||
"AGENT_TYPE": {
|
||||
"LABEL": "Role",
|
||||
"PLACEHOLDER": "Please select a role",
|
||||
"ERROR": "Role is required"
|
||||
},
|
||||
"EMAIL": {
|
||||
"LABEL": "Email Address",
|
||||
"PLACEHOLDER": "Please enter an email address of the agent"
|
||||
},
|
||||
"AGENT_AVAILABILITY": {
|
||||
"LABEL": "Availability",
|
||||
"PLACEHOLDER": "Please select an availability status",
|
||||
"ERROR": "Availability is required"
|
||||
},
|
||||
"SUBMIT": "Edit Agent"
|
||||
},
|
||||
"BUTTON_TEXT": "Edit",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Agent updated successfully",
|
||||
"ERROR_MESSAGE": "Could not connect to Woot Server, Please try again later"
|
||||
},
|
||||
"PASSWORD_RESET": {
|
||||
"ADMIN_RESET_BUTTON": "Reset Password",
|
||||
"ADMIN_SUCCESS_MESSAGE": "An email with reset password instructions has been sent to the agent",
|
||||
"SUCCESS_MESSAGE": "Agent password reset successfully",
|
||||
"ERROR_MESSAGE": "Could not connect to Woot Server, Please try again later"
|
||||
}
|
||||
},
|
||||
"SEARCH": {
|
||||
"NO_RESULTS": "No results found."
|
||||
},
|
||||
"MULTI_SELECTOR": {
|
||||
"PLACEHOLDER": "None",
|
||||
"TITLE": {
|
||||
"AGENT": "Select agent",
|
||||
"TEAM": "Select team"
|
||||
},
|
||||
"SEARCH": {
|
||||
"NO_RESULTS": {
|
||||
"AGENT": "No agents found",
|
||||
"TEAM": "No teams found"
|
||||
},
|
||||
"PLACEHOLDER": {
|
||||
"AGENT": "Search agents",
|
||||
"TEAM": "Search teams",
|
||||
"INPUT": "Search for agents"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
{
|
||||
"ATTRIBUTES_MGMT": {
|
||||
"HEADER": "Custom Attributes",
|
||||
"HEADER_BTN_TXT": "Add Custom Attribute",
|
||||
"LOADING": "Fetching custom attributes",
|
||||
"SIDEBAR_TXT": "<p><b>Custom Attributes</b> <p>A custom attribute tracks facts about your contacts/conversation — like the subscription plan, or when they ordered the first item etc. <br /><br />For creating a Custom Attribute, just click on the <b>Add Custom Attribute.</b> You can also edit or delete an existing Custom Attribute by clicking on the Edit or Delete button.</p>",
|
||||
"ADD": {
|
||||
"TITLE": "Add Custom Attribute",
|
||||
"SUBMIT": "Create",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel",
|
||||
"FORM": {
|
||||
"NAME": {
|
||||
"LABEL": "Display Name",
|
||||
"PLACEHOLDER": "Enter custom attribute display name",
|
||||
"ERROR": "Name is required"
|
||||
},
|
||||
"DESC": {
|
||||
"LABEL": "Description",
|
||||
"PLACEHOLDER": "Enter custom attribute description",
|
||||
"ERROR": "Description is required"
|
||||
},
|
||||
"MODEL": {
|
||||
"LABEL": "Applies to",
|
||||
"PLACEHOLDER": "Please select one",
|
||||
"ERROR": "Model is required"
|
||||
},
|
||||
"TYPE": {
|
||||
"LABEL": "Type",
|
||||
"PLACEHOLDER": "Please select a type",
|
||||
"ERROR": "Type is required",
|
||||
"LIST": {
|
||||
"LABEL": "List Values",
|
||||
"PLACEHOLDER": "Please enter value and press enter key",
|
||||
"ERROR": "Must have at least one value"
|
||||
}
|
||||
},
|
||||
"KEY": {
|
||||
"LABEL": "Key",
|
||||
"PLACEHOLDER": "Enter custom attribute key",
|
||||
"ERROR": "Key is required",
|
||||
"IN_VALID": "Invalid key"
|
||||
}
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Custom Attribute added successfully!",
|
||||
"ERROR_MESSAGE": "Could not create a Custom Attribute. Please try again later."
|
||||
}
|
||||
},
|
||||
"DELETE": {
|
||||
"BUTTON_TEXT": "Delete",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Custom Attribute deleted successfully.",
|
||||
"ERROR_MESSAGE": "Couldn't delete the custom attribute. Try again."
|
||||
},
|
||||
"CONFIRM": {
|
||||
"TITLE": "Are you sure want to delete - %{attributeName}",
|
||||
"PLACE_HOLDER": "Please type {attributeName} to confirm",
|
||||
"MESSAGE": "Deleting will remove the custom attribute",
|
||||
"YES": "Delete ",
|
||||
"NO": "Cancel"
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Edit Custom Attribute",
|
||||
"UPDATE_BUTTON_TEXT": "Update",
|
||||
"TYPE": {
|
||||
"LIST": {
|
||||
"LABEL": "List Values",
|
||||
"PLACEHOLDER": "Please enter values and press enter key"
|
||||
}
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Custom Attribute updated successfully",
|
||||
"ERROR_MESSAGE": "There was an error updating custom attribute, please try again"
|
||||
}
|
||||
},
|
||||
"TABS": {
|
||||
"HEADER": "Custom Attributes",
|
||||
"CONVERSATION": "Conversation",
|
||||
"CONTACT": "Contact"
|
||||
},
|
||||
"LIST": {
|
||||
"TABLE_HEADER": [
|
||||
"Name",
|
||||
"Description",
|
||||
"Type",
|
||||
"Key"
|
||||
],
|
||||
"BUTTONS": {
|
||||
"EDIT": "Edit",
|
||||
"DELETE": "Delete"
|
||||
},
|
||||
"EMPTY_RESULT": {
|
||||
"404": "There are no custom attributes created",
|
||||
"NOT_FOUND": "There are no custom attributes configured"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"AUDIT_LOGS": {
|
||||
"HEADER": "Audit Logs",
|
||||
"HEADER_BTN_TXT": "Add Audit Logs",
|
||||
"LOADING": "Fetching Audit Logs",
|
||||
"SEARCH_404": "There are no items matching this query",
|
||||
"SIDEBAR_TXT": "<p><b>Audit Logs</b> </p><p> Audit Logs are trails for events and actions in a Chatwoot System. </p>",
|
||||
"LIST": {
|
||||
"404": "There are no Audit Logs available in this account.",
|
||||
"TITLE": "Manage Audit Logs",
|
||||
"DESC": "Audit Logs are trails for events and actions in a Chatwoot System.",
|
||||
"TABLE_HEADER": [
|
||||
"Activity",
|
||||
"Time",
|
||||
"IP Address"
|
||||
]
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "AuditLogs retrieved successfully",
|
||||
"ERROR_MESSAGE": "Could not connect to Woot Server, Please try again later"
|
||||
},
|
||||
"DEFAULT_USER": "System",
|
||||
"AUTOMATION_RULE": {
|
||||
"ADD": "%{agentName} created a new automation rule (#%{id})",
|
||||
"EDIT": "%{agentName} updated an automation rule (#%{id})",
|
||||
"DELETE": "%{agentName} deleted an automation rule (#%{id})"
|
||||
},
|
||||
"ACCOUNT_USER": {
|
||||
"ADD": "%{agentName} invited %{invitee} to the account as an %{role}",
|
||||
"EDIT": {
|
||||
"SELF": "%{agentName} changed their %{attributes} to %{values}",
|
||||
"OTHER": "%{agentName} changed %{attributes} of %{user} to %{values}"
|
||||
}
|
||||
},
|
||||
"INBOX": {
|
||||
"ADD": "%{agentName} created a new inbox (#%{id})",
|
||||
"EDIT": "%{agentName} updated an inbox (#%{id})",
|
||||
"DELETE": "%{agentName} deleted an inbox (#%{id})"
|
||||
},
|
||||
"WEBHOOK": {
|
||||
"ADD": "%{agentName} created a new webhook (#%{id})",
|
||||
"EDIT": "%{agentName} updated a webhook (#%{id})",
|
||||
"DELETE": "%{agentName} deleted a webhook (#%{id})"
|
||||
},
|
||||
"USER_ACTION": {
|
||||
"SIGN_IN": "%{agentName} signed in",
|
||||
"SIGN_OUT": "%{agentName} signed out"
|
||||
},
|
||||
"TEAM": {
|
||||
"ADD": "%{agentName} created a new team (#%{id})",
|
||||
"EDIT": "%{agentName} updated a team (#%{id})",
|
||||
"DELETE": "%{agentName} deleted a team (#%{id})"
|
||||
},
|
||||
"MACRO": {
|
||||
"ADD": "%{agentName} created a new macro (#%{id})",
|
||||
"EDIT": "%{agentName} updated a macro (#%{id})",
|
||||
"DELETE": "%{agentName} deleted a macro (#%{id})"
|
||||
},
|
||||
"INBOX_MEMBER": {
|
||||
"ADD": "%{agentName} added %{user} to the inbox(#%{inbox_id})",
|
||||
"REMOVE": "%{agentName} removed %{user} from the inbox(#%{inbox_id})"
|
||||
},
|
||||
"TEAM_MEMBER": {
|
||||
"ADD": "%{agentName} added %{user} to the team(#%{team_id})",
|
||||
"REMOVE": "%{agentName} removed %{user} from the team(#%{team_id})"
|
||||
},
|
||||
"ACCOUNT": {
|
||||
"EDIT": "%{agentName} updated the account configuration (#%{id})"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,118 @@
|
||||
{
|
||||
"AUTOMATION": {
|
||||
"HEADER": "Automations",
|
||||
"HEADER_BTN_TXT": "Add Automation Rule",
|
||||
"LOADING": "Fetching automation rules",
|
||||
"SIDEBAR_TXT": "<p><b>Automation Rules</b> <p>Automation can replace and automate existing processes that require manual effort. You can do many things with automation, including adding labels and assigning conversation to the best agent. So the team focuses on what they do best and spends more little time on manual tasks.</p>",
|
||||
"ADD": {
|
||||
"TITLE": "Add Automation Rule",
|
||||
"SUBMIT": "Create",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel",
|
||||
"FORM": {
|
||||
"NAME": {
|
||||
"LABEL": "Rule Name",
|
||||
"PLACEHOLDER": "Enter rule name",
|
||||
"ERROR": "Name is required"
|
||||
},
|
||||
"DESC": {
|
||||
"LABEL": "Description",
|
||||
"PLACEHOLDER": "Enter rule description",
|
||||
"ERROR": "Description is required"
|
||||
},
|
||||
"EVENT": {
|
||||
"LABEL": "Event",
|
||||
"PLACEHOLDER": "Please select one",
|
||||
"ERROR": "Event is required"
|
||||
},
|
||||
"CONDITIONS": {
|
||||
"LABEL": "Conditions"
|
||||
},
|
||||
"ACTIONS": {
|
||||
"LABEL": "Actions"
|
||||
}
|
||||
},
|
||||
"CONDITION_BUTTON_LABEL": "Add Condition",
|
||||
"ACTION_BUTTON_LABEL": "Add Action",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Automation rule added successfully",
|
||||
"ERROR_MESSAGE": "Could not able to create a automation rule, Please try again later"
|
||||
}
|
||||
},
|
||||
"LIST": {
|
||||
"TABLE_HEADER": [
|
||||
"Name",
|
||||
"Description",
|
||||
"Active",
|
||||
"Created on"
|
||||
],
|
||||
"404": "No automation rules found"
|
||||
},
|
||||
"DELETE": {
|
||||
"TITLE": "Delete Automation Rule",
|
||||
"SUBMIT": "Delete",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel",
|
||||
"CONFIRM": {
|
||||
"TITLE": "Confirm Deletion",
|
||||
"MESSAGE": "Are you sure to delete ",
|
||||
"YES": "Yes, Delete ",
|
||||
"NO": "No, Keep "
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Automation rule deleted successfully",
|
||||
"ERROR_MESSAGE": "Could not able to delete a automation rule, Please try again later"
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Edit Automation Rule",
|
||||
"SUBMIT": "Update",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Automation rule updated successfully",
|
||||
"ERROR_MESSAGE": "Could not update automation rule, Please try again later"
|
||||
}
|
||||
},
|
||||
"CLONE": {
|
||||
"TOOLTIP": "Clone",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Automation cloned successfully",
|
||||
"ERROR_MESSAGE": "Could not clone automation rule, Please try again later"
|
||||
}
|
||||
},
|
||||
"FORM": {
|
||||
"EDIT": "Edit",
|
||||
"CREATE": "Create",
|
||||
"DELETE": "Delete",
|
||||
"CANCEL": "Cancel",
|
||||
"RESET_MESSAGE": "Changing event type will reset the conditions and events you have added below"
|
||||
},
|
||||
"CONDITION": {
|
||||
"DELETE_MESSAGE": "You need to have atleast one condition to save",
|
||||
"CONTACT_CUSTOM_ATTR_LABEL": "Contact Custom Attributes",
|
||||
"CONVERSATION_CUSTOM_ATTR_LABEL": "Conversation Custom Attributes"
|
||||
},
|
||||
"ACTION": {
|
||||
"DELETE_MESSAGE": "You need to have atleast one action to save",
|
||||
"TEAM_MESSAGE_INPUT_PLACEHOLDER": "Enter your message here",
|
||||
"TEAM_DROPDOWN_PLACEHOLDER": "Select teams"
|
||||
},
|
||||
"TOGGLE": {
|
||||
"ACTIVATION_TITLE": "Activate Automation Rule",
|
||||
"DEACTIVATION_TITLE": "Deactivate Automation Rule",
|
||||
"ACTIVATION_DESCRIPTION": "This action will activate the automation rule '{automationName}'. Are you sure you want to proceed?",
|
||||
"DEACTIVATION_DESCRIPTION": "This action will deactivate the automation rule '{automationName}'. Are you sure you want to proceed?",
|
||||
"ACTIVATION_SUCCESFUL": "Automation Rule Activated Successfully",
|
||||
"DEACTIVATION_SUCCESFUL": "Automation Rule Deactivated Successfully",
|
||||
"ACTIVATION_ERROR": "Could not Activate Automation, Please try again later",
|
||||
"DEACTIVATION_ERROR": "Could not Deactivate Automation, Please try again later",
|
||||
"CONFIRMATION_LABEL": "Yes",
|
||||
"CANCEL_LABEL": "No"
|
||||
},
|
||||
"ATTACHMENT": {
|
||||
"UPLOAD_ERROR": "Could not upload attachment, Please try again",
|
||||
"LABEL_IDLE": "Upload Attachment",
|
||||
"LABEL_UPLOADING": "Uploading...",
|
||||
"LABEL_UPLOADED": "Successfully Uploaded",
|
||||
"LABEL_UPLOAD_FAILED": "Upload Failed"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"BULK_ACTION": {
|
||||
"CONVERSATIONS_SELECTED": "%{conversationCount} conversations selected",
|
||||
"AGENT_SELECT_LABEL": "Select Agent",
|
||||
"ASSIGN_CONFIRMATION_LABEL": "Are you sure to assign %{conversationCount} %{conversationLabel} to",
|
||||
"UNASSIGN_CONFIRMATION_LABEL": "Are you sure to unassign %{conversationCount} %{conversationLabel}?",
|
||||
"GO_BACK_LABEL": "Go back",
|
||||
"ASSIGN_LABEL": "Assign",
|
||||
"YES": "Yes",
|
||||
"ASSIGN_AGENT_TOOLTIP": "Assign Agent",
|
||||
"ASSIGN_TEAM_TOOLTIP": "Assign team",
|
||||
"ASSIGN_SUCCESFUL": "Conversations assigned successfully",
|
||||
"ASSIGN_FAILED": "Failed to assign conversations, please try again",
|
||||
"RESOLVE_SUCCESFUL": "Conversations resolved successfully",
|
||||
"RESOLVE_FAILED": "Failed to resolve conversations, please try again",
|
||||
"ALL_CONVERSATIONS_SELECTED_ALERT": "Conversations visible on this page are only selected.",
|
||||
"AGENT_LIST_LOADING": "Loading Agents",
|
||||
"UPDATE": {
|
||||
"CHANGE_STATUS": "Change status",
|
||||
"SNOOZE_UNTIL_NEXT_REPLY": "Snooze until next reply",
|
||||
"UPDATE_SUCCESFUL": "Conversation status updated successfully.",
|
||||
"UPDATE_FAILED": "Failed to update conversations, please try again"
|
||||
},
|
||||
"LABELS": {
|
||||
"ASSIGN_LABELS": "Assign Labels",
|
||||
"NO_LABELS_FOUND": "No labels found for",
|
||||
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
||||
"ASSIGN_SUCCESFUL": "Labels assigned successfully",
|
||||
"ASSIGN_FAILED": "Failed to assign labels, please try again"
|
||||
},
|
||||
"TEAMS": {
|
||||
"TEAM_SELECT_LABEL": "Select Team",
|
||||
"NONE": "None",
|
||||
"NO_TEAMS_AVAILABLE": "There are no teams added to this account yet.",
|
||||
"ASSIGN_SELECTED_TEAMS": "Assign selected team",
|
||||
"ASSIGN_SUCCESFUL": "Teams assiged successfully",
|
||||
"ASSIGN_FAILED": "Failed to assign team, please try again"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
{
|
||||
"CAMPAIGN": {
|
||||
"HEADER": "Campaigns",
|
||||
"SIDEBAR_TXT": "Proactive messages allow the customer to send outbound messages to their contacts which would trigger more conversations. Click on <b>Add Campaign</b> to create a new campaign. You can also edit or delete an existing campaign by clicking on the Edit or Delete button.",
|
||||
"HEADER_BTN_TXT": {
|
||||
"ONE_OFF": "Create a one off campaign",
|
||||
"ONGOING": "Create a ongoing campaign"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Create a campaign",
|
||||
"DESC": "Proactive messages allow the customer to send outbound messages to their contacts which would trigger more conversations.",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel",
|
||||
"CREATE_BUTTON_TEXT": "Create",
|
||||
"FORM": {
|
||||
"TITLE": {
|
||||
"LABEL": "Title",
|
||||
"PLACEHOLDER": "Please enter the title of campaign",
|
||||
"ERROR": "Title is required"
|
||||
},
|
||||
"SCHEDULED_AT": {
|
||||
"LABEL": "Scheduled time",
|
||||
"PLACEHOLDER": "Please select the time",
|
||||
"CONFIRM": "Confirm",
|
||||
"ERROR": "Scheduled time is required"
|
||||
},
|
||||
"AUDIENCE": {
|
||||
"LABEL": "Audience",
|
||||
"PLACEHOLDER": "Select the customer labels",
|
||||
"ERROR": "Audience is required"
|
||||
},
|
||||
"INBOX": {
|
||||
"LABEL": "Select Inbox",
|
||||
"PLACEHOLDER": "Select Inbox",
|
||||
"ERROR": "Inbox is required"
|
||||
},
|
||||
"MESSAGE": {
|
||||
"LABEL": "Message",
|
||||
"PLACEHOLDER": "Please enter the message of campaign",
|
||||
"ERROR": "Message is required"
|
||||
},
|
||||
"SENT_BY": {
|
||||
"LABEL": "Sent by",
|
||||
"PLACEHOLDER": "Please select the the content of campaign",
|
||||
"ERROR": "Sender is required"
|
||||
},
|
||||
"END_POINT": {
|
||||
"LABEL": "URL",
|
||||
"PLACEHOLDER": "Please enter the URL",
|
||||
"ERROR": "Please enter a valid URL"
|
||||
},
|
||||
"TIME_ON_PAGE": {
|
||||
"LABEL": "Time on page(Seconds)",
|
||||
"PLACEHOLDER": "Please enter the time",
|
||||
"ERROR": "Time on page is required"
|
||||
},
|
||||
"ENABLED": "Enable campaign",
|
||||
"TRIGGER_ONLY_BUSINESS_HOURS": "Trigger only during business hours",
|
||||
"SUBMIT": "Add Campaign"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Campaign created successfully",
|
||||
"ERROR_MESSAGE": "There was an error. Please try again."
|
||||
}
|
||||
},
|
||||
"DELETE": {
|
||||
"BUTTON_TEXT": "Delete",
|
||||
"CONFIRM": {
|
||||
"TITLE": "Confirm Deletion",
|
||||
"MESSAGE": "Are you sure to delete?",
|
||||
"YES": "Yes, Delete ",
|
||||
"NO": "No, Keep "
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Campaign deleted successfully",
|
||||
"ERROR_MESSAGE": "Could not delete the campaign. Please try again later."
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Edit campaign",
|
||||
"UPDATE_BUTTON_TEXT": "Update",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Campaign updated successfully",
|
||||
"ERROR_MESSAGE": "There was an error, please try again"
|
||||
}
|
||||
},
|
||||
"LIST": {
|
||||
"LOADING_MESSAGE": "Loading campaigns...",
|
||||
"404": "There are no campaigns created for this inbox.",
|
||||
"TABLE_HEADER": {
|
||||
"TITLE": "Title",
|
||||
"MESSAGE": "Message",
|
||||
"INBOX": "Inbox",
|
||||
"STATUS": "Status",
|
||||
"SENDER": "Sender",
|
||||
"URL": "URL",
|
||||
"SCHEDULED_AT": "Scheduled time",
|
||||
"TIME_ON_PAGE": "Time(Seconds)",
|
||||
"CREATED_AT": "Created at"
|
||||
},
|
||||
"BUTTONS": {
|
||||
"ADD": "Add",
|
||||
"EDIT": "Edit",
|
||||
"DELETE": "Delete"
|
||||
},
|
||||
"STATUS": {
|
||||
"ENABLED": "Enabled",
|
||||
"DISABLED": "Disabled",
|
||||
"COMPLETED": "Completed",
|
||||
"ACTIVE": "Active"
|
||||
},
|
||||
"SENDER": {
|
||||
"BOT": "Bot"
|
||||
}
|
||||
},
|
||||
"ONE_OFF": {
|
||||
"HEADER": "One off campaigns",
|
||||
"404": "There are no one off campaigns created",
|
||||
"INBOXES_NOT_FOUND": "Please create an sms inbox and start adding campaigns"
|
||||
},
|
||||
"ONGOING": {
|
||||
"HEADER": "Ongoing campaigns",
|
||||
"404": "There are no ongoing campaigns created",
|
||||
"INBOXES_NOT_FOUND": "Please create an website inbox and start adding campaigns"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
{
|
||||
"CANNED_MGMT": {
|
||||
"HEADER": "Canned Responses",
|
||||
"HEADER_BTN_TXT": "Add Canned Response",
|
||||
"LOADING": "Fetching Canned Responses",
|
||||
"SEARCH_404": "There are no items matching this query",
|
||||
"SIDEBAR_TXT": "<p><b>Canned Responses</b> </p><p> Canned Responses are saved reply templates which can be used to quickly send out a reply to a conversation. </p><p> For creating a Canned Response, just click on the <b>Add Canned Response</b>. You can also edit or delete an existing Canned Response by clicking on the Edit or Delete button </p><p> Canned responses are used with the help of <b>Short Codes</b>. Agents can access canned responses while on a chat by typing <b>'/'</b> followed by the short code. </p>",
|
||||
"LIST": {
|
||||
"404": "There are no canned responses available in this account.",
|
||||
"TITLE": "Manage canned responses",
|
||||
"DESC": "Canned Responses are predefined reply templates which can be used to quickly send out replies to tickets.",
|
||||
"TABLE_HEADER": [
|
||||
"Short Code",
|
||||
"Content",
|
||||
"Actions"
|
||||
]
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Add Canned Response",
|
||||
"DESC": "Canned Responses are saved reply templates which can be used to quickly send out reply to conversation.",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel",
|
||||
"FORM": {
|
||||
"SHORT_CODE": {
|
||||
"LABEL": "Short Code",
|
||||
"PLACEHOLDER": "Please enter a short code",
|
||||
"ERROR": "Short Code is required"
|
||||
},
|
||||
"CONTENT": {
|
||||
"LABEL": "Content",
|
||||
"PLACEHOLDER": "Please enter a content",
|
||||
"ERROR": "Content is required"
|
||||
},
|
||||
"SUBMIT": "Submit"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Canned Response added successfully",
|
||||
"ERROR_MESSAGE": "Could not create canned response. Please try again later."
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Edit Canned Response",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel",
|
||||
"FORM": {
|
||||
"SHORT_CODE": {
|
||||
"LABEL": "Short Code",
|
||||
"PLACEHOLDER": "Please enter a shortcode",
|
||||
"ERROR": "Short Code is required"
|
||||
},
|
||||
"CONTENT": {
|
||||
"LABEL": "Content",
|
||||
"PLACEHOLDER": "Please enter a content",
|
||||
"ERROR": "Content is required"
|
||||
},
|
||||
"SUBMIT": "Submit"
|
||||
},
|
||||
"BUTTON_TEXT": "Edit",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Canned Response updated successfully",
|
||||
"ERROR_MESSAGE": "Could not update canned response. Please try again later."
|
||||
}
|
||||
},
|
||||
"DELETE": {
|
||||
"BUTTON_TEXT": "Delete",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Canned response deleted successfully",
|
||||
"ERROR_MESSAGE": "Could not delete canned response. Please try again later."
|
||||
},
|
||||
"CONFIRM": {
|
||||
"TITLE": "Confirm Deletion",
|
||||
"MESSAGE": "Are you sure to delete ",
|
||||
"YES": "Yes, Delete ",
|
||||
"NO": "No, Keep "
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
{
|
||||
"CHAT_LIST": {
|
||||
"LOADING": "Fetching conversations",
|
||||
"LOAD_MORE_CONVERSATIONS": "Load more conversations",
|
||||
"EOF": "All conversations loaded 🎉",
|
||||
"LIST": {
|
||||
"404": "There are no active conversations in this group."
|
||||
},
|
||||
"TAB_HEADING": "Conversations",
|
||||
"MENTION_HEADING": "Mentions",
|
||||
"UNATTENDED_HEADING": "Unattended",
|
||||
"SEARCH": {
|
||||
"INPUT": "Search for People, Chats, Saved Replies .."
|
||||
},
|
||||
"FILTER_ALL": "All",
|
||||
"ASSIGNEE_TYPE_TABS": {
|
||||
"me": "Mine",
|
||||
"unassigned": "Unassigned",
|
||||
"all": "All"
|
||||
},
|
||||
"CHAT_STATUS_FILTER_ITEMS": {
|
||||
"open": {
|
||||
"TEXT": "Open"
|
||||
},
|
||||
"resolved": {
|
||||
"TEXT": "Resolved"
|
||||
},
|
||||
"pending": {
|
||||
"TEXT": "Pending"
|
||||
},
|
||||
"snoozed": {
|
||||
"TEXT": "Snoozed"
|
||||
},
|
||||
"all": {
|
||||
"TEXT": "All"
|
||||
}
|
||||
},
|
||||
"VIEW_FILTER": "View",
|
||||
"SORT_TOOLTIP_LABEL": "Sort conversations",
|
||||
"CHAT_SORT": {
|
||||
"STATUS": "Status",
|
||||
"ORDER_BY": "Order by"
|
||||
},
|
||||
"CHAT_SORT_FILTER_ITEMS": {
|
||||
"latest": {
|
||||
"TEXT": "Last activity"
|
||||
},
|
||||
"sort_on_created_at": {
|
||||
"TEXT": "Created at"
|
||||
},
|
||||
"sort_on_priority": {
|
||||
"TEXT": "Priority"
|
||||
},
|
||||
"sort_on_waiting_since": {
|
||||
"TEXT": "Pending Response"
|
||||
}
|
||||
},
|
||||
"ATTACHMENTS": {
|
||||
"image": {
|
||||
"CONTENT": "Picture message"
|
||||
},
|
||||
"audio": {
|
||||
"CONTENT": "Audio message"
|
||||
},
|
||||
"video": {
|
||||
"CONTENT": "Video message"
|
||||
},
|
||||
"file": {
|
||||
"CONTENT": "File Attachment"
|
||||
},
|
||||
"location": {
|
||||
"CONTENT": "Location"
|
||||
},
|
||||
"fallback": {
|
||||
"CONTENT": "has shared a url"
|
||||
}
|
||||
},
|
||||
"CHAT_SORT_BY_FILTER": {
|
||||
"TITLE": "Sort conversation",
|
||||
"DROPDOWN_TITLE": "Sort by",
|
||||
"ITEMS": {
|
||||
"LATEST": {
|
||||
"NAME": "Last activity at",
|
||||
"LABEL": "Last activity"
|
||||
},
|
||||
"CREATED_AT": {
|
||||
"NAME": "Created at",
|
||||
"LABEL": "Created at"
|
||||
},
|
||||
"LAST_USER_MESSAGE_AT": {
|
||||
"NAME": "Last user message at",
|
||||
"LABEL": "Last message"
|
||||
}
|
||||
}
|
||||
},
|
||||
"RECEIVED_VIA_EMAIL": "Received via email",
|
||||
"VIEW_TWEET_IN_TWITTER": "View tweet in Twitter",
|
||||
"REPLY_TO_TWEET": "Reply to this tweet",
|
||||
"LINK_TO_STORY": "Go to instagram story",
|
||||
"SENT": "Sent successfully",
|
||||
"READ": "Read successfully",
|
||||
"DELIVERED": "Delivered successfully",
|
||||
"NO_MESSAGES": "No Messages",
|
||||
"NO_CONTENT": "No content available",
|
||||
"HIDE_QUOTED_TEXT": "Hide Quoted Text",
|
||||
"SHOW_QUOTED_TEXT": "Show Quoted Text",
|
||||
"MESSAGE_READ": "Read"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,371 @@
|
||||
{
|
||||
"CONTACT_PANEL": {
|
||||
"NOT_AVAILABLE": "Not Available",
|
||||
"EMAIL_ADDRESS": "Email Address",
|
||||
"PHONE_NUMBER": "Phone number",
|
||||
"IDENTIFIER": "Identifier",
|
||||
"COPY_SUCCESSFUL": "Copied to clipboard successfully",
|
||||
"COMPANY": "Company",
|
||||
"LOCATION": "Location",
|
||||
"BROWSER_LANGUAGE": "Browser Language",
|
||||
"CONVERSATION_TITLE": "Conversation Details",
|
||||
"VIEW_PROFILE": "View Profile",
|
||||
"BROWSER": "Browser",
|
||||
"OS": "Operating System",
|
||||
"INITIATED_FROM": "Initiated from",
|
||||
"INITIATED_AT": "Initiated at",
|
||||
"IP_ADDRESS": "IP Address",
|
||||
"CREATED_AT_LABEL": "Created",
|
||||
"NEW_MESSAGE": "New message",
|
||||
"CONVERSATIONS": {
|
||||
"NO_RECORDS_FOUND": "There are no previous conversations associated to this contact.",
|
||||
"TITLE": "Previous Conversations"
|
||||
},
|
||||
"LABELS": {
|
||||
"CONTACT": {
|
||||
"TITLE": "Contact Labels",
|
||||
"ERROR": "Couldn't update labels"
|
||||
},
|
||||
"CONVERSATION": {
|
||||
"TITLE": "Conversation Labels",
|
||||
"ADD_BUTTON": "Add Labels"
|
||||
},
|
||||
"LABEL_SELECT": {
|
||||
"TITLE": "Add Labels",
|
||||
"PLACEHOLDER": "Search labels",
|
||||
"NO_RESULT": "No labels found",
|
||||
"CREATE_LABEL": "Create new label"
|
||||
}
|
||||
},
|
||||
"MERGE_CONTACT": "Merge contact",
|
||||
"CONTACT_ACTIONS": "Contact actions",
|
||||
"MUTE_CONTACT": "Mute Conversation",
|
||||
"UNMUTE_CONTACT": "Unmute Conversation",
|
||||
"MUTED_SUCCESS": "This conversation is muted for 6 hours",
|
||||
"UNMUTED_SUCCESS": "This conversation is unmuted",
|
||||
"SEND_TRANSCRIPT": "Send Transcript",
|
||||
"EDIT_LABEL": "Edit",
|
||||
"SIDEBAR_SECTIONS": {
|
||||
"CUSTOM_ATTRIBUTES": "Custom Attributes",
|
||||
"CONTACT_LABELS": "Contact Labels",
|
||||
"PREVIOUS_CONVERSATIONS": "Previous Conversations"
|
||||
}
|
||||
},
|
||||
"EDIT_CONTACT": {
|
||||
"BUTTON_LABEL": "Edit Contact",
|
||||
"TITLE": "Edit contact",
|
||||
"DESC": "Edit contact details"
|
||||
},
|
||||
"CREATE_CONTACT": {
|
||||
"BUTTON_LABEL": "New Contact",
|
||||
"TITLE": "Create new contact",
|
||||
"DESC": "Add basic information details about the contact."
|
||||
},
|
||||
"IMPORT_CONTACTS": {
|
||||
"BUTTON_LABEL": "Import",
|
||||
"TITLE": "Import Contacts",
|
||||
"DESC": "Import contacts through a CSV file.",
|
||||
"DOWNLOAD_LABEL": "Download a sample csv.",
|
||||
"FORM": {
|
||||
"LABEL": "CSV File",
|
||||
"SUBMIT": "Import",
|
||||
"CANCEL": "Cancel"
|
||||
},
|
||||
"SUCCESS_MESSAGE": "You will be notified via email when the import is complete.",
|
||||
"ERROR_MESSAGE": "There was an error, please try again"
|
||||
},
|
||||
"EXPORT_CONTACTS": {
|
||||
"BUTTON_LABEL": "Export",
|
||||
"TITLE": "Export Contacts",
|
||||
"DESC": "Export contacts to a CSV file.",
|
||||
"SUCCESS_MESSAGE": "Export is in progress. You will be notified on email when the export file is ready to download.",
|
||||
"ERROR_MESSAGE": "There was an error, please try again"
|
||||
},
|
||||
"DELETE_NOTE": {
|
||||
"CONFIRM": {
|
||||
"TITLE": "Confirm Deletion",
|
||||
"MESSAGE": "Are you want sure to delete this note?",
|
||||
"YES": "Yes, Delete it",
|
||||
"NO": "No, Keep it"
|
||||
}
|
||||
},
|
||||
"DELETE_CONTACT": {
|
||||
"BUTTON_LABEL": "Delete Contact",
|
||||
"TITLE": "Delete contact",
|
||||
"DESC": "Delete contact details",
|
||||
"CONFIRM": {
|
||||
"TITLE": "Confirm Deletion",
|
||||
"MESSAGE": "Are you sure to delete ",
|
||||
"YES": "Yes, Delete",
|
||||
"NO": "No, Keep"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Contact deleted successfully",
|
||||
"ERROR_MESSAGE": "Could not delete contact. Please try again later."
|
||||
}
|
||||
},
|
||||
"CONTACT_FORM": {
|
||||
"FORM": {
|
||||
"SUBMIT": "Submit",
|
||||
"CANCEL": "Cancel",
|
||||
"AVATAR": {
|
||||
"LABEL": "Contact Avatar"
|
||||
},
|
||||
"NAME": {
|
||||
"PLACEHOLDER": "Enter the full name of the contact",
|
||||
"LABEL": "Full Name"
|
||||
},
|
||||
"BIO": {
|
||||
"PLACEHOLDER": "Enter the bio of the contact",
|
||||
"LABEL": "Bio"
|
||||
},
|
||||
"EMAIL_ADDRESS": {
|
||||
"PLACEHOLDER": "Enter the email address of the contact",
|
||||
"LABEL": "Email Address",
|
||||
"DUPLICATE": "This email address is in use for another contact.",
|
||||
"ERROR": "Please enter a valid email address."
|
||||
},
|
||||
"PHONE_NUMBER": {
|
||||
"PLACEHOLDER": "Enter the phone number of the contact",
|
||||
"LABEL": "Phone Number",
|
||||
"HELP": "Phone number should be of E.164 format eg: +1415555555 [+][country code][area code][local phone number]. You can select the dial code from the dropdown.",
|
||||
"ERROR": "Phone number should be either empty or of E.164 format",
|
||||
"DIAL_CODE_ERROR": "Please select a dial code from the list",
|
||||
"DUPLICATE": "This phone number is in use for another contact."
|
||||
},
|
||||
"LOCATION": {
|
||||
"PLACEHOLDER": "Enter the location of the contact",
|
||||
"LABEL": "Location"
|
||||
},
|
||||
"COMPANY_NAME": {
|
||||
"PLACEHOLDER": "Enter the company name",
|
||||
"LABEL": "Company Name"
|
||||
},
|
||||
"COUNTRY": {
|
||||
"PLACEHOLDER": "Enter the country name",
|
||||
"LABEL": "Country Name",
|
||||
"SELECT_PLACEHOLDER": "Select",
|
||||
"REMOVE": "Remove",
|
||||
"SELECT_COUNTRY": "Select Country"
|
||||
},
|
||||
"CITY": {
|
||||
"PLACEHOLDER": "Enter the city name",
|
||||
"LABEL": "City Name"
|
||||
},
|
||||
"SOCIAL_PROFILES": {
|
||||
"FACEBOOK": {
|
||||
"PLACEHOLDER": "Enter the Facebook username",
|
||||
"LABEL": "Facebook"
|
||||
},
|
||||
"TWITTER": {
|
||||
"PLACEHOLDER": "Enter the Twitter username",
|
||||
"LABEL": "Twitter"
|
||||
},
|
||||
"LINKEDIN": {
|
||||
"PLACEHOLDER": "Enter the LinkedIn username",
|
||||
"LABEL": "LinkedIn"
|
||||
},
|
||||
"GITHUB": {
|
||||
"PLACEHOLDER": "Enter the Github username",
|
||||
"LABEL": "Github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"DELETE_AVATAR": {
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Contact avatar deleted successfully",
|
||||
"ERROR_MESSAGE": "Could not delete the contact avatar. Please try again later."
|
||||
}
|
||||
},
|
||||
"SUCCESS_MESSAGE": "Contact saved successfully",
|
||||
"ERROR_MESSAGE": "There was an error, please try again"
|
||||
},
|
||||
"NEW_CONVERSATION": {
|
||||
"BUTTON_LABEL": "Start conversation",
|
||||
"TITLE": "New conversation",
|
||||
"DESC": "Start a new conversation by sending a new message.",
|
||||
"NO_INBOX": "Couldn't find an inbox to initiate a new conversation with this contact.",
|
||||
"FORM": {
|
||||
"TO": {
|
||||
"LABEL": "To"
|
||||
},
|
||||
"INBOX": {
|
||||
"LABEL": "Via Inbox",
|
||||
"PLACEHOLDER": "Choose source inbox",
|
||||
"ERROR": "Select an inbox"
|
||||
},
|
||||
"SUBJECT": {
|
||||
"LABEL": "Subject",
|
||||
"PLACEHOLDER": "Subject",
|
||||
"ERROR": "Subject can't be empty"
|
||||
},
|
||||
"MESSAGE": {
|
||||
"LABEL": "Message",
|
||||
"PLACEHOLDER": "Write your message here",
|
||||
"ERROR": "Message can't be empty"
|
||||
},
|
||||
"SUBMIT": "Send message",
|
||||
"CANCEL": "Cancel",
|
||||
"SUCCESS_MESSAGE": "Message sent!",
|
||||
"GO_TO_CONVERSATION": "View",
|
||||
"ERROR_MESSAGE": "Couldn't send! try again"
|
||||
}
|
||||
},
|
||||
"CONTACTS_PAGE": {
|
||||
"HEADER": "Contacts",
|
||||
"FIELDS": "Contact fields",
|
||||
"SEARCH_BUTTON": "Search",
|
||||
"SEARCH_INPUT_PLACEHOLDER": "Search for contacts",
|
||||
"FILTER_CONTACTS": "Filter",
|
||||
"FILTER_CONTACTS_SAVE": "Save filter",
|
||||
"FILTER_CONTACTS_DELETE": "Delete filter",
|
||||
"FILTER_CONTACTS_EDIT": "Edit segment",
|
||||
"LIST": {
|
||||
"LOADING_MESSAGE": "Loading contacts...",
|
||||
"404": "No contacts matches your search 🔍",
|
||||
"NO_CONTACTS": "There are no available contacts",
|
||||
"TABLE_HEADER": {
|
||||
"NAME": "Name",
|
||||
"PHONE_NUMBER": "Phone Number",
|
||||
"CONVERSATIONS": "Conversations",
|
||||
"LAST_ACTIVITY": "Last Activity",
|
||||
"CREATED_AT": "Created At",
|
||||
"COUNTRY": "Country",
|
||||
"CITY": "City",
|
||||
"SOCIAL_PROFILES": "Social Profiles",
|
||||
"COMPANY": "Company",
|
||||
"EMAIL_ADDRESS": "Email Address"
|
||||
},
|
||||
"VIEW_DETAILS": "View details"
|
||||
}
|
||||
},
|
||||
"CONTACT_PROFILE": {
|
||||
"BACK_BUTTON": "Contacts",
|
||||
"LOADING": "Loading contact profile..."
|
||||
},
|
||||
"REMINDER": {
|
||||
"ADD_BUTTON": {
|
||||
"BUTTON": "Add",
|
||||
"TITLE": "Shift + Enter to create a task"
|
||||
},
|
||||
"FOOTER": {
|
||||
"DUE_DATE": "Due date",
|
||||
"LABEL_TITLE": "Set type"
|
||||
}
|
||||
},
|
||||
"NOTES": {
|
||||
"FETCHING_NOTES": "Fetching notes...",
|
||||
"NOT_AVAILABLE": "There are no notes created for this contact",
|
||||
"HEADER": {
|
||||
"TITLE": "Notes"
|
||||
},
|
||||
"LIST": {
|
||||
"LABEL": "added a note"
|
||||
},
|
||||
"ADD": {
|
||||
"BUTTON": "Add",
|
||||
"PLACEHOLDER": "Add a note",
|
||||
"TITLE": "Shift + Enter to create a note"
|
||||
},
|
||||
"CONTENT_HEADER": {
|
||||
"DELETE": "Delete note"
|
||||
}
|
||||
},
|
||||
"EVENTS": {
|
||||
"HEADER": {
|
||||
"TITLE": "Activities"
|
||||
},
|
||||
"BUTTON": {
|
||||
"PILL_BUTTON_NOTES": "notes",
|
||||
"PILL_BUTTON_EVENTS": "events",
|
||||
"PILL_BUTTON_CONVO": "conversations"
|
||||
}
|
||||
},
|
||||
"CUSTOM_ATTRIBUTES": {
|
||||
"ADD_BUTTON_TEXT": "Add attributes",
|
||||
"BUTTON": "Add custom attribute",
|
||||
"NOT_AVAILABLE": "There are no custom attributes available for this contact.",
|
||||
"COPY_SUCCESSFUL": "Copied to clipboard successfully",
|
||||
"ACTIONS": {
|
||||
"COPY": "Copy attribute",
|
||||
"DELETE": "Delete attribute",
|
||||
"EDIT": "Edit attribute"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Create custom attribute",
|
||||
"DESC": "Add custom information to this contact."
|
||||
},
|
||||
"FORM": {
|
||||
"CREATE": "Add attribute",
|
||||
"CANCEL": "Cancel",
|
||||
"NAME": {
|
||||
"LABEL": "Custom attribute name",
|
||||
"PLACEHOLDER": "Eg: shopify id",
|
||||
"ERROR": "Invalid custom attribute name"
|
||||
},
|
||||
"VALUE": {
|
||||
"LABEL": "Attribute value",
|
||||
"PLACEHOLDER": "Eg: 11901 "
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Create new attribute ",
|
||||
"SUCCESS": "Attribute added successfully",
|
||||
"ERROR": "Unable to add attribute. Please try again later"
|
||||
},
|
||||
"UPDATE": {
|
||||
"SUCCESS": "Attribute updated successfully",
|
||||
"ERROR": "Unable to update attribute. Please try again later"
|
||||
},
|
||||
"DELETE": {
|
||||
"SUCCESS": "Attribute deleted successfully",
|
||||
"ERROR": "Unable to delete attribute. Please try again later"
|
||||
},
|
||||
"ATTRIBUTE_SELECT": {
|
||||
"TITLE": "Add attributes",
|
||||
"PLACEHOLDER": "Search attributes",
|
||||
"NO_RESULT": "No attributes found"
|
||||
},
|
||||
"ATTRIBUTE_TYPE": {
|
||||
"LIST": {
|
||||
"PLACEHOLDER": "Select value",
|
||||
"SEARCH_INPUT_PLACEHOLDER": "Search value",
|
||||
"NO_RESULT": "No result found"
|
||||
}
|
||||
}
|
||||
},
|
||||
"VALIDATIONS": {
|
||||
"REQUIRED": "Valid value is required",
|
||||
"INVALID_URL": "Invalid URL"
|
||||
}
|
||||
},
|
||||
"MERGE_CONTACTS": {
|
||||
"TITLE": "Merge contacts",
|
||||
"DESCRIPTION": "Merge contacts to combine two profiles into one, including all attributes and conversations. In case of conflict, the Primary contact’s attributes will take precedence.",
|
||||
"PRIMARY": {
|
||||
"TITLE": "Primary contact",
|
||||
"HELP_LABEL": "To be kept"
|
||||
},
|
||||
"CHILD": {
|
||||
"TITLE": "Contact to merge",
|
||||
"PLACEHOLDER": "Search for a contact",
|
||||
"HELP_LABEL": "To be deleted"
|
||||
},
|
||||
"SUMMARY": {
|
||||
"TITLE": "Summary",
|
||||
"DELETE_WARNING": "Contact of <strong>%{childContactName}</strong> will be deleted.",
|
||||
"ATTRIBUTE_WARNING": "Contact details of <strong>%{childContactName}</strong> will be copied to <strong>%{primaryContactName}</strong>."
|
||||
},
|
||||
"SEARCH": {
|
||||
"ERROR": "ERROR_MESSAGE"
|
||||
},
|
||||
"FORM": {
|
||||
"SUBMIT": " Merge contacts",
|
||||
"CANCEL": "Cancel",
|
||||
"CHILD_CONTACT": {
|
||||
"ERROR": "Select a child contact to merge"
|
||||
},
|
||||
"SUCCESS_MESSAGE": "Contact merged successfully",
|
||||
"ERROR_MESSAGE": "Could not merge contacts, try again!"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
{
|
||||
"CONTACTS_FILTER": {
|
||||
"TITLE": "Filter Contacts",
|
||||
"SUBTITLE": "Add filters below and hit 'Submit' to filter contacts.",
|
||||
"EDIT_CUSTOM_SEGMENT": "Edit Segment",
|
||||
"CUSTOM_VIEWS_SUBTITLE": "Add or remove filters and update your segment.",
|
||||
"ADD_NEW_FILTER": "Add Filter",
|
||||
"CLEAR_ALL_FILTERS": "Clear All Filters",
|
||||
"FILTER_DELETE_ERROR": "You should have atleast one filter to save",
|
||||
"SUBMIT_BUTTON_LABEL": "Submit",
|
||||
"UPDATE_BUTTON_LABEL": "Update Segment",
|
||||
"CANCEL_BUTTON_LABEL": "Cancel",
|
||||
"CLEAR_BUTTON_LABEL": "Clear Filters",
|
||||
"EMPTY_VALUE_ERROR": "Value is required",
|
||||
"SEGMENT_LABEL": "Segment Name",
|
||||
"SEGMENT_QUERY_LABEL": "Segment Query",
|
||||
"TOOLTIP_LABEL": "Filter contacts",
|
||||
"QUERY_DROPDOWN_LABELS": {
|
||||
"AND": "AND",
|
||||
"OR": "OR"
|
||||
},
|
||||
"OPERATOR_LABELS": {
|
||||
"equal_to": "Equal to",
|
||||
"not_equal_to": "Not equal to",
|
||||
"contains": "Contains",
|
||||
"does_not_contain": "Does not contain",
|
||||
"is_present": "Is present",
|
||||
"is_not_present": "Is not present",
|
||||
"is_greater_than": "Is greater than",
|
||||
"is_lesser_than": "Is lesser than",
|
||||
"days_before": "Is x days before"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"NAME": "Name",
|
||||
"EMAIL": "Email",
|
||||
"PHONE_NUMBER": "Phone number",
|
||||
"IDENTIFIER": "Identifier",
|
||||
"CITY": "City",
|
||||
"COUNTRY": "Country",
|
||||
"CUSTOM_ATTRIBUTE_LIST": "List",
|
||||
"CUSTOM_ATTRIBUTE_TEXT": "Text",
|
||||
"CUSTOM_ATTRIBUTE_NUMBER": "Number",
|
||||
"CUSTOM_ATTRIBUTE_LINK": "Link",
|
||||
"CUSTOM_ATTRIBUTE_CHECKBOX": "Checkbox",
|
||||
"CREATED_AT": "Created At",
|
||||
"LAST_ACTIVITY": "Last Activity",
|
||||
"REFERER_LINK": "Referrer link"
|
||||
},
|
||||
"GROUPS": {
|
||||
"STANDARD_FILTERS": "Standard Filters",
|
||||
"ADDITIONAL_FILTERS": "Additional Filters",
|
||||
"CUSTOM_ATTRIBUTES": "Custom Attributes"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,320 @@
|
||||
{
|
||||
"CONVERSATION": {
|
||||
"SELECT_A_CONVERSATION": "Please select a conversation from left pane",
|
||||
"CSAT_REPLY_MESSAGE": "Please rate the conversation",
|
||||
"404": "Sorry, we cannot find the conversation. Please try again",
|
||||
"SWITCH_VIEW_LAYOUT": "Switch the layout",
|
||||
"DASHBOARD_APP_TAB_MESSAGES": "Messages",
|
||||
"UNVERIFIED_SESSION": "The identity of this user is not verified",
|
||||
"NO_MESSAGE_1": "Uh oh! Looks like there are no messages from customers in your inbox.",
|
||||
"NO_MESSAGE_2": " to send a message to your page!",
|
||||
"NO_INBOX_1": "Hola! Looks like you haven't added any inboxes yet.",
|
||||
"NO_INBOX_2": " to get started",
|
||||
"NO_INBOX_AGENT": "Uh Oh! Looks like you are not part of any inbox. Please contact your administrator",
|
||||
"SEARCH_MESSAGES": "Search for messages in conversations",
|
||||
"EMPTY_STATE": {
|
||||
"CMD_BAR": "to open command menu",
|
||||
"KEYBOARD_SHORTCUTS": "to view keyboard shortcuts"
|
||||
},
|
||||
"SEARCH": {
|
||||
"TITLE": "Search messages",
|
||||
"RESULT_TITLE": "Search Results",
|
||||
"LOADING_MESSAGE": "Crunching data...",
|
||||
"PLACEHOLDER": "Type any text to search messages",
|
||||
"NO_MATCHING_RESULTS": "No results found."
|
||||
},
|
||||
"UNREAD_MESSAGES": "Unread Messages",
|
||||
"UNREAD_MESSAGE": "Unread Message",
|
||||
"CLICK_HERE": "Click here",
|
||||
"LOADING_INBOXES": "Loading inboxes",
|
||||
"LOADING_CONVERSATIONS": "Loading Conversations",
|
||||
"CANNOT_REPLY": "You cannot reply due to",
|
||||
"24_HOURS_WINDOW": "24 hour message window restriction",
|
||||
"NOT_ASSIGNED_TO_YOU": "This conversation is not assigned to you. Would you like to assign this conversation to yourself?",
|
||||
"ASSIGN_TO_ME": "Assign to me",
|
||||
"TWILIO_WHATSAPP_CAN_REPLY": "You can only reply to this conversation using a template message due to",
|
||||
"TWILIO_WHATSAPP_24_HOURS_WINDOW": "24 hour message window restriction",
|
||||
"SELECT_A_TWEET_TO_REPLY": "Please select a tweet to reply to.",
|
||||
"REPLYING_TO": "You are replying to:",
|
||||
"REMOVE_SELECTION": "Remove Selection",
|
||||
"DOWNLOAD": "Download",
|
||||
"UNKNOWN_FILE_TYPE": "Unknown File",
|
||||
"SAVE_CONTACT": "Save",
|
||||
"UPLOADING_ATTACHMENTS": "Uploading attachments...",
|
||||
"REPLIED_TO_STORY": "Replied to your story",
|
||||
"SUCCESS_DELETE_MESSAGE": "Message deleted successfully",
|
||||
"FAIL_DELETE_MESSSAGE": "Couldn't delete message! Try again",
|
||||
"NO_RESPONSE": "No response",
|
||||
"RATING_TITLE": "Rating",
|
||||
"FEEDBACK_TITLE": "Feedback",
|
||||
"CARD": {
|
||||
"SHOW_LABELS": "Show labels",
|
||||
"HIDE_LABELS": "Hide labels"
|
||||
},
|
||||
"HEADER": {
|
||||
"RESOLVE_ACTION": "Resolve",
|
||||
"REOPEN_ACTION": "Reopen",
|
||||
"OPEN_ACTION": "Open",
|
||||
"OPEN": "More",
|
||||
"CLOSE": "Close",
|
||||
"DETAILS": "details",
|
||||
"SNOOZED_UNTIL": "Snoozed until",
|
||||
"SNOOZED_UNTIL_TOMORROW": "Snoozed until tomorrow",
|
||||
"SNOOZED_UNTIL_NEXT_WEEK": "Snoozed until next week",
|
||||
"SNOOZED_UNTIL_NEXT_REPLY": "Snoozed until next reply"
|
||||
},
|
||||
"RESOLVE_DROPDOWN": {
|
||||
"MARK_PENDING": "Mark as pending",
|
||||
"SNOOZE_UNTIL": "Snooze",
|
||||
"SNOOZE": {
|
||||
"TITLE": "Snooze until",
|
||||
"NEXT_REPLY": "Next reply",
|
||||
"TOMORROW": "Tomorrow",
|
||||
"NEXT_WEEK": "Next week"
|
||||
}
|
||||
},
|
||||
"CUSTOM_SNOOZE": {
|
||||
"TITLE": "Snooze until",
|
||||
"APPLY": "Snooze",
|
||||
"CANCEL": "Cancel"
|
||||
},
|
||||
"PRIORITY": {
|
||||
"TITLE": "Priority",
|
||||
"OPTIONS": {
|
||||
"NONE": "None",
|
||||
"URGENT": "Urgent",
|
||||
"HIGH": "High",
|
||||
"MEDIUM": "Medium",
|
||||
"LOW": "Low"
|
||||
},
|
||||
"CHANGE_PRIORITY": {
|
||||
"SELECT_PLACEHOLDER": "None",
|
||||
"INPUT_PLACEHOLDER": "Select priority",
|
||||
"NO_RESULTS": "No results found",
|
||||
"SUCCESSFUL": "Changed priority of conversation id %{conversationId} to %{priority}",
|
||||
"FAILED": "Couldn't change priority. Please try again."
|
||||
}
|
||||
},
|
||||
"CARD_CONTEXT_MENU": {
|
||||
"PENDING": "Mark as pending",
|
||||
"RESOLVED": "Mark as resolved",
|
||||
"MARK_AS_UNREAD": "Mark as unread",
|
||||
"REOPEN": "Reopen conversation",
|
||||
"SNOOZE": {
|
||||
"TITLE": "Snooze",
|
||||
"NEXT_REPLY": "Until next reply",
|
||||
"TOMORROW": "Until tomorrow",
|
||||
"NEXT_WEEK": "Until next week"
|
||||
},
|
||||
"ASSIGN_AGENT": "Assign agent",
|
||||
"ASSIGN_LABEL": "Assign label",
|
||||
"AGENTS_LOADING": "Loading agents...",
|
||||
"ASSIGN_TEAM": "Assign team",
|
||||
"API": {
|
||||
"AGENT_ASSIGNMENT": {
|
||||
"SUCCESFUL": "Conversation id %{conversationId} assigned to \"%{agentName}\"",
|
||||
"FAILED": "Couldn't assign agent. Please try again."
|
||||
},
|
||||
"LABEL_ASSIGNMENT": {
|
||||
"SUCCESFUL": "Assigned label #%{labelName} to conversation id %{conversationId}",
|
||||
"FAILED": "Couldn't assign label. Please try again."
|
||||
},
|
||||
"TEAM_ASSIGNMENT": {
|
||||
"SUCCESFUL": "Assigned team \"%{team}\" to conversation id %{conversationId}",
|
||||
"FAILED": "Couldn't assign team. Please try again."
|
||||
}
|
||||
}
|
||||
},
|
||||
"FOOTER": {
|
||||
"MESSAGE_SIGN_TOOLTIP": "Message signature",
|
||||
"ENABLE_SIGN_TOOLTIP": "Enable signature",
|
||||
"DISABLE_SIGN_TOOLTIP": "Disable signature",
|
||||
"MSG_INPUT": "Shift + enter for new line. Start with '/' to select a Canned Response.",
|
||||
"PRIVATE_MSG_INPUT": "Shift + enter for new line. This will be visible only to Agents",
|
||||
"MESSAGE_SIGNATURE_NOT_CONFIGURED": "Message signature is not configured, please configure it in profile settings.",
|
||||
"CLICK_HERE": "Click here to update"
|
||||
},
|
||||
"REPLYBOX": {
|
||||
"REPLY": "Reply",
|
||||
"PRIVATE_NOTE": "Private Note",
|
||||
"SEND": "Send",
|
||||
"CREATE": "Add Note",
|
||||
"TWEET": "Tweet",
|
||||
"TIP_FORMAT_ICON": "Show rich text editor",
|
||||
"TIP_EMOJI_ICON": "Show emoji selector",
|
||||
"TIP_ATTACH_ICON": "Attach files",
|
||||
"TIP_AUDIORECORDER_ICON": "Record audio",
|
||||
"TIP_AUDIORECORDER_PERMISSION": "Allow access to audio",
|
||||
"TIP_AUDIORECORDER_ERROR": "Could not open the audio",
|
||||
"DRAG_DROP": "Drag and drop here to attach",
|
||||
"START_AUDIO_RECORDING": "Start audio recording",
|
||||
"STOP_AUDIO_RECORDING": "Stop audio recording",
|
||||
"": "",
|
||||
"EMAIL_HEAD": {
|
||||
"TO": "TO",
|
||||
"ADD_BCC": "Add bcc",
|
||||
"CC": {
|
||||
"LABEL": "CC",
|
||||
"PLACEHOLDER": "Emails separated by commas",
|
||||
"ERROR": "Please enter valid email addresses"
|
||||
},
|
||||
"BCC": {
|
||||
"LABEL": "BCC",
|
||||
"PLACEHOLDER": "Emails separated by commas",
|
||||
"ERROR": "Please enter valid email addresses"
|
||||
}
|
||||
},
|
||||
"UNDEFINED_VARIABLES": {
|
||||
"TITLE": "Undefined variables",
|
||||
"MESSAGE": "You have {undefinedVariablesCount} undefined variables in your message: {undefinedVariables}. Would you like to send the message anyway?",
|
||||
"CONFIRM": {
|
||||
"YES": "Send",
|
||||
"CANCEL": "Cancel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"VISIBLE_TO_AGENTS": "Private Note: Only visible to you and your team",
|
||||
"CHANGE_STATUS": "Conversation status changed",
|
||||
"CHANGE_STATUS_FAILED": "Conversation status change failed",
|
||||
"CHANGE_AGENT": "Conversation Assignee changed",
|
||||
"CHANGE_AGENT_FAILED": "Assignee change failed",
|
||||
"ASSIGN_LABEL_SUCCESFUL": "Label assigned successfully",
|
||||
"ASSIGN_LABEL_FAILED": "Label assignment failed",
|
||||
"CHANGE_TEAM": "Conversation team changed",
|
||||
"FILE_SIZE_LIMIT": "File exceeds the {MAXIMUM_SUPPORTED_FILE_UPLOAD_SIZE} MB attachment limit",
|
||||
"MESSAGE_ERROR": "Unable to send this message, please try again later",
|
||||
"SENT_BY": "Sent by:",
|
||||
"BOT": "Bot",
|
||||
"SEND_FAILED": "Couldn't send message! Try again",
|
||||
"TRY_AGAIN": "retry",
|
||||
"ASSIGNMENT": {
|
||||
"SELECT_AGENT": "Select Agent",
|
||||
"REMOVE": "Remove",
|
||||
"ASSIGN": "Assign"
|
||||
},
|
||||
"CONTEXT_MENU": {
|
||||
"COPY": "Copy",
|
||||
"DELETE": "Delete",
|
||||
"CREATE_A_CANNED_RESPONSE": "Add to canned responses",
|
||||
"TRANSLATE": "Translate",
|
||||
"COPY_PERMALINK": "Copy link to the message",
|
||||
"LINK_COPIED": "Message URL copied to the clipboard",
|
||||
"DELETE_CONFIRMATION": {
|
||||
"TITLE": "Are you sure you want to delete this message?",
|
||||
"MESSAGE": "You cannot undo this action",
|
||||
"DELETE": "Delete",
|
||||
"CANCEL": "Cancel"
|
||||
}
|
||||
}
|
||||
},
|
||||
"EMAIL_TRANSCRIPT": {
|
||||
"TITLE": "Send conversation transcript",
|
||||
"DESC": "Send a copy of the conversation transcript to the specified email address",
|
||||
"SUBMIT": "Submit",
|
||||
"CANCEL": "Cancel",
|
||||
"SEND_EMAIL_SUCCESS": "The chat transcript was sent successfully",
|
||||
"SEND_EMAIL_ERROR": "There was an error, please try again",
|
||||
"FORM": {
|
||||
"SEND_TO_CONTACT": "Send the transcript to the customer",
|
||||
"SEND_TO_AGENT": "Send the transcript to the assigned agent",
|
||||
"SEND_TO_OTHER_EMAIL_ADDRESS": "Send the transcript to another email address",
|
||||
"EMAIL": {
|
||||
"PLACEHOLDER": "Enter an email address",
|
||||
"ERROR": "Please enter a valid email address"
|
||||
}
|
||||
}
|
||||
},
|
||||
"ONBOARDING": {
|
||||
"TITLE": "Hey 👋, Welcome to %{installationName}!",
|
||||
"DESCRIPTION": "Thanks for signing up. We want you to get the most out of %{installationName}. Here are a few things you can do in %{installationName} to make the experience delightful.",
|
||||
"READ_LATEST_UPDATES": "Read our latest updates",
|
||||
"ALL_CONVERSATION": {
|
||||
"TITLE": "All your conversations in one place",
|
||||
"DESCRIPTION": "View all the conversations from your customers in one single dashboard. You can filter the conversations by the incoming channel, label and status."
|
||||
},
|
||||
"TEAM_MEMBERS": {
|
||||
"TITLE": "Invite your team members",
|
||||
"DESCRIPTION": "Since you are getting ready to talk to your customer, bring in your teammates to assist you. You can invite your teammates by adding their email addresses to the agent list.",
|
||||
"NEW_LINK": "Click here to invite a team member"
|
||||
},
|
||||
"INBOXES": {
|
||||
"TITLE": "Connect Inboxes",
|
||||
"DESCRIPTION": "Connect various channels through which your customers would be talking to you. It can be a website live-chat, your Facebook page or even your WhatsApp number.",
|
||||
"NEW_LINK": "Click here to create an inbox"
|
||||
},
|
||||
"LABELS": {
|
||||
"TITLE": "Organize conversations with labels",
|
||||
"DESCRIPTION": "Labels provide an easier way to categorize your conversation. Create some labels like #support-enquiry, #billing-question etc., so that you can use them in a conversation later.",
|
||||
"NEW_LINK": "Click here to create tags"
|
||||
}
|
||||
},
|
||||
"CONVERSATION_SIDEBAR": {
|
||||
"ASSIGNEE_LABEL": "Assigned Agent",
|
||||
"SELF_ASSIGN": "Assign to me",
|
||||
"TEAM_LABEL": "Assigned Team",
|
||||
"SELECT": {
|
||||
"PLACEHOLDER": "None"
|
||||
},
|
||||
"ACCORDION": {
|
||||
"CONTACT_DETAILS": "Contact Details",
|
||||
"CONVERSATION_ACTIONS": "Conversation Actions",
|
||||
"CONVERSATION_LABELS": "Conversation Labels",
|
||||
"CONVERSATION_INFO": "Conversation Information",
|
||||
"CONTACT_ATTRIBUTES": "Contact Attributes",
|
||||
"PREVIOUS_CONVERSATION": "Previous Conversations",
|
||||
"MACROS": "Macros"
|
||||
}
|
||||
},
|
||||
"CONVERSATION_CUSTOM_ATTRIBUTES": {
|
||||
"ADD_BUTTON_TEXT": "Create attribute",
|
||||
"UPDATE": {
|
||||
"SUCCESS": "Attribute updated successfully",
|
||||
"ERROR": "Unable to update attribute. Please try again later"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Add",
|
||||
"SUCCESS": "Attribute added successfully",
|
||||
"ERROR": "Unable to add attribute. Please try again later"
|
||||
},
|
||||
"DELETE": {
|
||||
"SUCCESS": "Attribute deleted successfully",
|
||||
"ERROR": "Unable to delete attribute. Please try again later"
|
||||
},
|
||||
"ATTRIBUTE_SELECT": {
|
||||
"TITLE": "Add attributes",
|
||||
"PLACEHOLDER": "Search attributes",
|
||||
"NO_RESULT": "No attributes found"
|
||||
}
|
||||
},
|
||||
"EMAIL_HEADER": {
|
||||
"FROM": "From",
|
||||
"TO": "To",
|
||||
"BCC": "Bcc",
|
||||
"CC": "Cc",
|
||||
"SUBJECT": "Subject"
|
||||
},
|
||||
"CONVERSATION_PARTICIPANTS": {
|
||||
"SIDEBAR_MENU_TITLE": "Participating",
|
||||
"SIDEBAR_TITLE": "Conversation participants",
|
||||
"NO_RECORDS_FOUND": "No results found",
|
||||
"ADD_PARTICIPANTS": "Select participants",
|
||||
"REMANING_PARTICIPANTS_TEXT": "+%{count} others",
|
||||
"REMANING_PARTICIPANT_TEXT": "+%{count} other",
|
||||
"TOTAL_PARTICIPANTS_TEXT": "%{count} people are participating.",
|
||||
"TOTAL_PARTICIPANT_TEXT": "%{count} person is participating.",
|
||||
"NO_PARTICIPANTS_TEXT": "No one is participating!.",
|
||||
"WATCH_CONVERSATION": "Join conversation",
|
||||
"YOU_ARE_WATCHING": "You are participating",
|
||||
"API": {
|
||||
"ERROR_MESSAGE": "Could not update, try again!",
|
||||
"SUCCESS_MESSAGE": "Participants updated!"
|
||||
}
|
||||
},
|
||||
"TRANSLATE_MODAL": {
|
||||
"TITLE": "View translated content",
|
||||
"DESC": "You can view the translated content in each langauge.",
|
||||
"ORIGINAL_CONTENT": "Original Content",
|
||||
"TRANSLATED_CONTENT": "Translated Content",
|
||||
"NO_TRANSLATIONS_AVAILABLE": "No translations are available for this content"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"CSAT": {
|
||||
"TITLE": "Rate your conversation",
|
||||
"PLACEHOLDER": "Tell us more...",
|
||||
"RATINGS": {
|
||||
"POOR": "😞 Poor",
|
||||
"FAIR": "😑 Fair",
|
||||
"AVERAGE": "😐 Average",
|
||||
"GOOD": "😀 Good",
|
||||
"EXCELLENT": "😍 Excellent"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"EMOJI": {
|
||||
"PLACEHOLDER": "Search emojis",
|
||||
"NOT_FOUND": "No emoji match your search"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
{
|
||||
"GENERAL_SETTINGS": {
|
||||
"TITLE": "Account settings",
|
||||
"SUBMIT": "Update settings",
|
||||
"BACK": "Back",
|
||||
"DISMISS": "Dismiss",
|
||||
"UPDATE": {
|
||||
"ERROR": "Could not update settings, try again!",
|
||||
"SUCCESS": "Successfully updated account settings"
|
||||
},
|
||||
"FORM": {
|
||||
"ERROR": "Please fix form errors",
|
||||
"GENERAL_SECTION": {
|
||||
"TITLE": "General settings",
|
||||
"NOTE": ""
|
||||
},
|
||||
"ACCOUNT_ID": {
|
||||
"TITLE": "Account ID",
|
||||
"NOTE": "This ID is required if you are building an API based integration"
|
||||
},
|
||||
"NAME": {
|
||||
"LABEL": "Account name",
|
||||
"PLACEHOLDER": "Your account name",
|
||||
"ERROR": "Please enter a valid account name"
|
||||
},
|
||||
"LANGUAGE": {
|
||||
"LABEL": "Site language",
|
||||
"PLACEHOLDER": "Your account name",
|
||||
"ERROR": ""
|
||||
},
|
||||
"DOMAIN": {
|
||||
"LABEL": "Incoming Email Domain",
|
||||
"PLACEHOLDER": "The domain where you will receive the emails",
|
||||
"ERROR": ""
|
||||
},
|
||||
"SUPPORT_EMAIL": {
|
||||
"LABEL": "Support Email",
|
||||
"PLACEHOLDER": "Your company's support email",
|
||||
"ERROR": ""
|
||||
},
|
||||
"AUTO_RESOLVE_DURATION": {
|
||||
"LABEL": "Number of days after a ticket should auto resolve if there is no activity",
|
||||
"PLACEHOLDER": "30",
|
||||
"ERROR": "Please enter a valid auto resolve duration (minimum 1 day and maximum 999 days)"
|
||||
},
|
||||
"FEATURES": {
|
||||
"INBOUND_EMAIL_ENABLED": "Conversation continuity with emails is enabled for your account.",
|
||||
"CUSTOM_EMAIL_DOMAIN_ENABLED": "You can receive emails in your custom domain now."
|
||||
}
|
||||
},
|
||||
"UPDATE_CHATWOOT": "An update %{latestChatwootVersion} for Chatwoot is available. Please update your instance.",
|
||||
"LEARN_MORE": "Learn more",
|
||||
"PAYMENT_PENDING": "Your payment is pending. Please update your payment information to continue using Chatwoot",
|
||||
"LIMITS_UPGRADE": "Your account has exceeded the usage limits, please upgrade your plan to continue using Chatwoot",
|
||||
"OPEN_BILLING": "Open billing"
|
||||
},
|
||||
"FORMS": {
|
||||
"MULTISELECT": {
|
||||
"ENTER_TO_SELECT": "Press enter to select",
|
||||
"ENTER_TO_REMOVE": "Press enter to remove",
|
||||
"SELECT_ONE": "Select one",
|
||||
"SELECT": "Select"
|
||||
}
|
||||
},
|
||||
"NOTIFICATIONS_PAGE": {
|
||||
"HEADER": "Notifications",
|
||||
"MARK_ALL_DONE": "Mark All Done",
|
||||
"DELETE_TITLE": "deleted",
|
||||
"UNREAD_NOTIFICATION": {
|
||||
"TITLE": "Unread Notifications",
|
||||
"ALL_NOTIFICATIONS": "View all notifications",
|
||||
"LOADING_UNREAD_MESSAGE": "Loading unread notifications...",
|
||||
"EMPTY_MESSAGE": "You have no unread notifications"
|
||||
},
|
||||
"LIST": {
|
||||
"LOADING_MESSAGE": "Loading notifications...",
|
||||
"404": "No Notifications",
|
||||
"TABLE_HEADER": [
|
||||
"Name",
|
||||
"Phone Number",
|
||||
"Conversations",
|
||||
"Last Contacted"
|
||||
]
|
||||
},
|
||||
"TYPE_LABEL": {
|
||||
"conversation_creation": "New conversation",
|
||||
"conversation_assignment": "Conversation Assigned",
|
||||
"assigned_conversation_new_message": "New Message",
|
||||
"participating_conversation_new_message": "New Message",
|
||||
"conversation_mention": "Mention"
|
||||
}
|
||||
},
|
||||
"NETWORK": {
|
||||
"NOTIFICATION": {
|
||||
"TEXT": "Disconnected from Chatwoot"
|
||||
},
|
||||
"BUTTON": {
|
||||
"REFRESH": "Refresh"
|
||||
}
|
||||
},
|
||||
"COMMAND_BAR": {
|
||||
"SEARCH_PLACEHOLDER": "Search or jump to",
|
||||
"SECTIONS": {
|
||||
"GENERAL": "General",
|
||||
"REPORTS": "Reports",
|
||||
"CONVERSATION": "Conversation",
|
||||
"CHANGE_ASSIGNEE": "Change Assignee",
|
||||
"CHANGE_PRIORITY": "Change Priority",
|
||||
"CHANGE_TEAM": "Change Team",
|
||||
"SNOOZE_CONVERSATION": "Snooze Conversation",
|
||||
"ADD_LABEL": "Add label to the conversation",
|
||||
"REMOVE_LABEL": "Remove label from the conversation",
|
||||
"SETTINGS": "Settings",
|
||||
"AI_ASSIST": "AI Assist",
|
||||
"APPEARANCE": "Appearance"
|
||||
},
|
||||
"COMMANDS": {
|
||||
"GO_TO_CONVERSATION_DASHBOARD": "Go to Conversation Dashboard",
|
||||
"GO_TO_CONTACTS_DASHBOARD": "Go to Contacts Dashboard",
|
||||
"GO_TO_REPORTS_OVERVIEW": "Go to Reports Overview",
|
||||
"GO_TO_CONVERSATION_REPORTS": "Go to Conversation Reports",
|
||||
"GO_TO_AGENT_REPORTS": "Go to Agent Reports",
|
||||
"GO_TO_LABEL_REPORTS": "Go to Label Reports",
|
||||
"GO_TO_INBOX_REPORTS": "Go to Inbox Reports",
|
||||
"GO_TO_TEAM_REPORTS": "Go to Team Reports",
|
||||
"GO_TO_SETTINGS_AGENTS": "Go to Agent Settings",
|
||||
"GO_TO_SETTINGS_TEAMS": "Go to Team Settings",
|
||||
"GO_TO_SETTINGS_INBOXES": "Go to Inbox Settings",
|
||||
"GO_TO_SETTINGS_LABELS": "Go to Label Settings",
|
||||
"GO_TO_SETTINGS_CANNED_RESPONSES": "Go to Canned Response Settings",
|
||||
"GO_TO_SETTINGS_APPLICATIONS": "Go to Application Settings",
|
||||
"GO_TO_SETTINGS_ACCOUNT": "Go to Account Settings",
|
||||
"GO_TO_SETTINGS_PROFILE": "Go to Profile Settings",
|
||||
"GO_TO_NOTIFICATIONS": "Go to Notifications",
|
||||
"ADD_LABELS_TO_CONVERSATION": "Add label to the conversation",
|
||||
"ASSIGN_AN_AGENT": "Assign an agent",
|
||||
"AI_ASSIST": "AI Assist",
|
||||
"ASSIGN_PRIORITY": "Assign priority",
|
||||
"ASSIGN_A_TEAM": "Assign a team",
|
||||
"MUTE_CONVERSATION": "Mute conversation",
|
||||
"UNMUTE_CONVERSATION": "Unmute conversation",
|
||||
"REMOVE_LABEL_FROM_CONVERSATION": "Remove label from the conversation",
|
||||
"REOPEN_CONVERSATION": "Reopen conversation",
|
||||
"RESOLVE_CONVERSATION": "Resolve conversation",
|
||||
"SEND_TRANSCRIPT": "Send an email transcript",
|
||||
"SNOOZE_CONVERSATION": "Snooze Conversation",
|
||||
"UNTIL_NEXT_REPLY": "Until next reply",
|
||||
"UNTIL_NEXT_WEEK": "Until next week",
|
||||
"UNTIL_TOMORROW": "Until tomorrow",
|
||||
"UNTIL_NEXT_MONTH": "Until next month",
|
||||
"AN_HOUR_FROM_NOW": "Until an hour from now",
|
||||
"CUSTOM": "Custom...",
|
||||
"CHANGE_APPEARANCE": "Change Appearance",
|
||||
"LIGHT_MODE": "Light",
|
||||
"DARK_MODE": "Dark",
|
||||
"SYSTEM_MODE": "System"
|
||||
}
|
||||
},
|
||||
"DASHBOARD_APPS": {
|
||||
"LOADING_MESSAGE": "Loading Dashboard App..."
|
||||
},
|
||||
"COMMON": {
|
||||
"OR": "Or",
|
||||
"CLICK_HERE": "click here"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,430 @@
|
||||
{
|
||||
"HELP_CENTER": {
|
||||
"HEADER": {
|
||||
"FILTER": "Filter by",
|
||||
"SORT": "Sort by",
|
||||
"SETTINGS_BUTTON": "Settings",
|
||||
"NEW_BUTTON": "New Article",
|
||||
"DROPDOWN_OPTIONS": {
|
||||
"PUBLISHED": "Published",
|
||||
"DRAFT": "Draft",
|
||||
"ARCHIVED": "Archived"
|
||||
},
|
||||
"TITLES": {
|
||||
"ALL_ARTICLES": "All Articles",
|
||||
"MINE": "My Articles",
|
||||
"DRAFT": "Draft Articles",
|
||||
"ARCHIVED": "Archived Articles"
|
||||
}
|
||||
},
|
||||
"EDIT_HEADER": {
|
||||
"ALL_ARTICLES": "All Articles",
|
||||
"PUBLISH_BUTTON": "Publish",
|
||||
"MOVE_TO_ARCHIVE_BUTTON": "Move to archived",
|
||||
"PREVIEW": "Preview",
|
||||
"ADD_TRANSLATION": "Add translation",
|
||||
"OPEN_SIDEBAR": "Open sidebar",
|
||||
"CLOSE_SIDEBAR": "Close sidebar",
|
||||
"SAVING": "Saving...",
|
||||
"SAVED": "Saved"
|
||||
},
|
||||
"ARTICLE_EDITOR": {
|
||||
"IMAGE_UPLOAD": {
|
||||
"TITLE": "Upload image",
|
||||
"UPLOADING": "Uploading...",
|
||||
"SUCCESS": "Image uploaded successfully",
|
||||
"ERROR": "Error while uploading image",
|
||||
"ERROR_FILE_SIZE": "Image size should be less than {size}MB",
|
||||
"ERROR_FILE_FORMAT": "Image format should be jpg, jpeg or png",
|
||||
"ERROR_FILE_DIMENSIONS": "Image dimensions should be less than 2000 x 2000"
|
||||
}
|
||||
},
|
||||
"ARTICLE_SETTINGS": {
|
||||
"TITLE": "Article Settings",
|
||||
"FORM": {
|
||||
"CATEGORY": {
|
||||
"LABEL": "Category",
|
||||
"TITLE": "Select category",
|
||||
"PLACEHOLDER": "Select category",
|
||||
"NO_RESULT": "No category found",
|
||||
"SEARCH_PLACEHOLDER": "Search category"
|
||||
},
|
||||
"AUTHOR": {
|
||||
"LABEL": "Author",
|
||||
"TITLE": "Select author",
|
||||
"PLACEHOLDER": "Select author",
|
||||
"NO_RESULT": "No authors found",
|
||||
"SEARCH_PLACEHOLDER": "Search author"
|
||||
},
|
||||
"META_TITLE": {
|
||||
"LABEL": "Meta title",
|
||||
"PLACEHOLDER": "Add a meta title"
|
||||
},
|
||||
"META_DESCRIPTION": {
|
||||
"LABEL": "Meta description",
|
||||
"PLACEHOLDER": "Add your meta description for better SEO results..."
|
||||
},
|
||||
"META_TAGS": {
|
||||
"LABEL": "Meta tags",
|
||||
"PLACEHOLDER": "Add meta tags separated by comma..."
|
||||
}
|
||||
},
|
||||
"BUTTONS": {
|
||||
"ARCHIVE": "Archive article",
|
||||
"DELETE": "Delete article"
|
||||
}
|
||||
},
|
||||
"ARTICLE_SEARCH_RESULT": {
|
||||
"UNCATEGORIZED": "Uncategorized",
|
||||
"INSERT_ARTICLE": "Insert",
|
||||
"NO_RESULT": "No articles found",
|
||||
"COPY_LINK": "Copy article link to clipboard",
|
||||
"OPEN_LINK": "Open article in new tab",
|
||||
"PREVIEW_LINK": "Preview article"
|
||||
},
|
||||
"PORTAL": {
|
||||
"HEADER": "Portals",
|
||||
"DEFAULT": "Default",
|
||||
"NEW_BUTTON": "New Portal",
|
||||
"ACTIVE_BADGE": "active",
|
||||
"CHOOSE_LOCALE_LABEL": "Choose a locale",
|
||||
"LOADING_MESSAGE": "Loading portals...",
|
||||
"ARTICLES_LABEL": "articles",
|
||||
"NO_PORTALS_MESSAGE": "There are no available portals",
|
||||
"ADD_NEW_LOCALE": "Add a new locale",
|
||||
"POPOVER": {
|
||||
"TITLE": "Portals",
|
||||
"PORTAL_SETTINGS": "Portal settings",
|
||||
"SUBTITLE": "You have multiple portals and can have different locales for each portal.",
|
||||
"CANCEL_BUTTON_LABEL": "Cancel",
|
||||
"CHOOSE_LOCALE_BUTTON": "Choose Locale"
|
||||
},
|
||||
"PORTAL_SETTINGS": {
|
||||
"LIST_ITEM": {
|
||||
"HEADER": {
|
||||
"COUNT_LABEL": "articles",
|
||||
"ADD": "Add locale",
|
||||
"VISIT": "Visit site",
|
||||
"SETTINGS": "Settings",
|
||||
"DELETE": "Delete"
|
||||
},
|
||||
"PORTAL_CONFIG": {
|
||||
"TITLE": "Portal Configurations",
|
||||
"ITEMS": {
|
||||
"NAME": "Name",
|
||||
"DOMAIN": "Custom domain",
|
||||
"SLUG": "Slug",
|
||||
"TITLE": "Portal title",
|
||||
"THEME": "Theme color",
|
||||
"SUB_TEXT": "Portal sub text"
|
||||
}
|
||||
},
|
||||
"AVAILABLE_LOCALES": {
|
||||
"TITLE": "Available locales",
|
||||
"TABLE": {
|
||||
"NAME": "Locale name",
|
||||
"CODE": "Locale code",
|
||||
"ARTICLE_COUNT": "No. of articles",
|
||||
"CATEGORIES": "No. of categories",
|
||||
"SWAP": "Swap",
|
||||
"DELETE": "Delete",
|
||||
"DEFAULT_LOCALE": "Default"
|
||||
}
|
||||
}
|
||||
},
|
||||
"DELETE_PORTAL": {
|
||||
"TITLE": "Delete portal",
|
||||
"MESSAGE": "Are you sure you want to delete this portal",
|
||||
"YES": "Yes, delete portal",
|
||||
"NO": "No, keep portal",
|
||||
"API": {
|
||||
"DELETE_SUCCESS": "Portal deleted successfully",
|
||||
"DELETE_ERROR": "Error while deleting portal"
|
||||
}
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"HEADER_TEXT": "Edit portal",
|
||||
"TABS": {
|
||||
"BASIC_SETTINGS": {
|
||||
"TITLE": "Basic information"
|
||||
},
|
||||
"CUSTOMIZATION_SETTINGS": {
|
||||
"TITLE": "Portal customization"
|
||||
},
|
||||
"CATEGORY_SETTINGS": {
|
||||
"TITLE": "Categories"
|
||||
},
|
||||
"LOCALE_SETTINGS": {
|
||||
"TITLE": "Locales"
|
||||
}
|
||||
},
|
||||
"CATEGORIES": {
|
||||
"TITLE": "Categories in",
|
||||
"NEW_CATEGORY": "New category",
|
||||
"TABLE": {
|
||||
"NAME": "Name",
|
||||
"DESCRIPTION": "Description",
|
||||
"LOCALE": "Locale",
|
||||
"ARTICLE_COUNT": "No. of articles",
|
||||
"ACTION_BUTTON": {
|
||||
"EDIT": "Edit category",
|
||||
"DELETE": "Delete category"
|
||||
},
|
||||
"EMPTY_TEXT": "No categories found"
|
||||
}
|
||||
},
|
||||
"EDIT_BASIC_INFO": {
|
||||
"BUTTON_TEXT": "Update basic settings"
|
||||
}
|
||||
},
|
||||
"ADD": {
|
||||
"CREATE_FLOW": [
|
||||
{
|
||||
"title": "Help center information",
|
||||
"route": "new_portal_information",
|
||||
"body": "Basic information about portal",
|
||||
"CREATE_BASIC_SETTING_BUTTON": "Create portal basic settings"
|
||||
},
|
||||
{
|
||||
"title": "Help center customization",
|
||||
"route": "portal_customization",
|
||||
"body": "Customize portal",
|
||||
"UPDATE_PORTAL_BUTTON": "Update portal settings"
|
||||
},
|
||||
{
|
||||
"title": "Voila! 🎉",
|
||||
"route": "portal_finish",
|
||||
"body": "You're all set!",
|
||||
"FINISH": "Finish"
|
||||
}
|
||||
],
|
||||
"CREATE_FLOW_PAGE": {
|
||||
"BACK_BUTTON": "Back",
|
||||
"BASIC_SETTINGS_PAGE": {
|
||||
"HEADER": "Create Portal",
|
||||
"TITLE": "Help center information",
|
||||
"CREATE_BASIC_SETTING_BUTTON": "Create portal basic settings"
|
||||
},
|
||||
"CUSTOMIZATION_PAGE": {
|
||||
"HEADER": "Portal customisation",
|
||||
"TITLE": "Help center customization",
|
||||
"UPDATE_PORTAL_BUTTON": "Update portal settings"
|
||||
},
|
||||
"FINISH_PAGE": {
|
||||
"TITLE": "Voila!🎉 You're all set up!",
|
||||
"MESSAGE": "You can now see this created portal on your all portals page.",
|
||||
"FINISH": "Go to all portals page"
|
||||
}
|
||||
},
|
||||
"LOGO": {
|
||||
"LABEL": "Logo",
|
||||
"UPLOAD_BUTTON": "Upload logo",
|
||||
"HELP_TEXT": "This logo will be displayed on the portal header."
|
||||
},
|
||||
"NAME": {
|
||||
"LABEL": "Name",
|
||||
"PLACEHOLDER": "Portal name",
|
||||
"HELP_TEXT": "The name will be used in the public facing portal internally.",
|
||||
"ERROR": "Name is required"
|
||||
},
|
||||
"SLUG": {
|
||||
"LABEL": "Slug",
|
||||
"PLACEHOLDER": "Portal slug for urls",
|
||||
"ERROR": "Slug is required"
|
||||
},
|
||||
"DOMAIN": {
|
||||
"LABEL": "Custom Domain",
|
||||
"PLACEHOLDER": "Portal custom domain",
|
||||
"HELP_TEXT": "Add only If you want to use a custom domain for your portals. Eg: %{exampleURL}",
|
||||
"ERROR": "Enter a valid domain URL"
|
||||
},
|
||||
"HOME_PAGE_LINK": {
|
||||
"LABEL": "Home Page Link",
|
||||
"PLACEHOLDER": "Portal home page link",
|
||||
"HELP_TEXT": "The link used to return from the portal to the home page. Eg: %{exampleURL}",
|
||||
"ERROR": "Enter a valid home page URL"
|
||||
},
|
||||
"THEME_COLOR": {
|
||||
"LABEL": "Portal theme color",
|
||||
"HELP_TEXT": "This color will show as the theme color for the portal."
|
||||
},
|
||||
"PAGE_TITLE": {
|
||||
"LABEL": "Page Title",
|
||||
"PLACEHOLDER": "Portal page title",
|
||||
"HELP_TEXT": "The page title will be used in the public facing portal.",
|
||||
"ERROR": "Page title is required"
|
||||
},
|
||||
"HEADER_TEXT": {
|
||||
"LABEL": "Header Text",
|
||||
"PLACEHOLDER": "Portal header text",
|
||||
"HELP_TEXT": "The Portal header text will be used in the public facing portal.",
|
||||
"ERROR": "Portal header text is required"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE_FOR_BASIC": "Portal created successfully.",
|
||||
"ERROR_MESSAGE_FOR_BASIC": "Couldn't create the portal. Try again.",
|
||||
"SUCCESS_MESSAGE_FOR_UPDATE": "Portal updated successfully.",
|
||||
"ERROR_MESSAGE_FOR_UPDATE": "Couldn't update the portal. Try again."
|
||||
}
|
||||
},
|
||||
"ADD_LOCALE": {
|
||||
"TITLE": "Add a new locale",
|
||||
"SUB_TITLE": "This adds a new locale to your available translation list.",
|
||||
"PORTAL": "Portal",
|
||||
"LOCALE": {
|
||||
"LABEL": "Locale",
|
||||
"PLACEHOLDER": "Choose a locale",
|
||||
"ERROR": "Locale is required"
|
||||
},
|
||||
"BUTTONS": {
|
||||
"CREATE": "Create locale",
|
||||
"CANCEL": "Cancel"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Locale added successfully",
|
||||
"ERROR_MESSAGE": "Unable to add locale. Try again."
|
||||
}
|
||||
},
|
||||
"CHANGE_DEFAULT_LOCALE": {
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Default locale updated successfully",
|
||||
"ERROR_MESSAGE": "Unable to update default locale. Try again."
|
||||
}
|
||||
},
|
||||
"DELETE_LOCALE": {
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Locale removed from portal successfully",
|
||||
"ERROR_MESSAGE": "Unable to remove locale from portal. Try again."
|
||||
}
|
||||
}
|
||||
},
|
||||
"TABLE": {
|
||||
"LOADING_MESSAGE": "Loading articles...",
|
||||
"404": "No articles matches your search 🔍",
|
||||
"NO_ARTICLES": "There are no available articles",
|
||||
"HEADERS": {
|
||||
"TITLE": "Title",
|
||||
"CATEGORY": "Category",
|
||||
"READ_COUNT": "Read count",
|
||||
"STATUS": "Status",
|
||||
"LAST_EDITED": "Last edited"
|
||||
},
|
||||
"COLUMNS": {
|
||||
"BY": "by"
|
||||
}
|
||||
},
|
||||
"EDIT_ARTICLE": {
|
||||
"LOADING": "Loading article...",
|
||||
"TITLE_PLACEHOLDER": "Article title goes here",
|
||||
"CONTENT_PLACEHOLDER": "Write your article here",
|
||||
"API": {
|
||||
"ERROR": "Error while saving article"
|
||||
}
|
||||
},
|
||||
"PUBLISH_ARTICLE": {
|
||||
"API": {
|
||||
"ERROR": "Error while publishing article",
|
||||
"SUCCESS": "Article published successfully"
|
||||
}
|
||||
},
|
||||
"ARCHIVE_ARTICLE": {
|
||||
"API": {
|
||||
"ERROR": "Error while archiving article",
|
||||
"SUCCESS": "Article archived successfully"
|
||||
}
|
||||
},
|
||||
"DELETE_ARTICLE": {
|
||||
"MODAL": {
|
||||
"CONFIRM": {
|
||||
"TITLE": "Confirm Deletion",
|
||||
"MESSAGE": "Are you sure to delete the article?",
|
||||
"YES": "Yes, Delete",
|
||||
"NO": "No, Keep it"
|
||||
}
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Article deleted successfully",
|
||||
"ERROR_MESSAGE": "Error while deleting article"
|
||||
}
|
||||
},
|
||||
"CREATE_ARTICLE": {
|
||||
"ERROR_MESSAGE": "Please add the article heading and content then only you can update the settings"
|
||||
},
|
||||
"SIDEBAR": {
|
||||
"SEARCH": {
|
||||
"PLACEHOLDER": "Search for articles"
|
||||
}
|
||||
},
|
||||
"CATEGORY": {
|
||||
"ADD": {
|
||||
"TITLE": "Create a category",
|
||||
"SUB_TITLE": "The category will be used in the public facing portal to categorize articles.",
|
||||
"PORTAL": "Portal",
|
||||
"LOCALE": "Locale",
|
||||
"NAME": {
|
||||
"LABEL": "Name",
|
||||
"PLACEHOLDER": "Category name",
|
||||
"HELP_TEXT": "The category name will be used in the public facing portal to categorize articles.",
|
||||
"ERROR": "Name is required"
|
||||
},
|
||||
"SLUG": {
|
||||
"LABEL": "Slug",
|
||||
"PLACEHOLDER": "Category slug for urls",
|
||||
"HELP_TEXT": "app.chatwoot.com/hc/my-portal/en-US/categories/my-slug",
|
||||
"ERROR": "Slug is required"
|
||||
},
|
||||
"DESCRIPTION": {
|
||||
"LABEL": "Description",
|
||||
"PLACEHOLDER": "Give a short description about the category.",
|
||||
"ERROR": "Description is required"
|
||||
},
|
||||
"BUTTONS": {
|
||||
"CREATE": "Create category",
|
||||
"CANCEL": "Cancel"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Category created successfully",
|
||||
"ERROR_MESSAGE": "Unable to create category"
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Edit a category",
|
||||
"SUB_TITLE": "Editing a category will update the category in the public facing portal.",
|
||||
"PORTAL": "Portal",
|
||||
"LOCALE": "Locale",
|
||||
"NAME": {
|
||||
"LABEL": "Name",
|
||||
"PLACEHOLDER": "Category name",
|
||||
"HELP_TEXT": "The category name will be used in the public facing portal to categorize articles.",
|
||||
"ERROR": "Name is required"
|
||||
},
|
||||
"SLUG": {
|
||||
"LABEL": "Slug",
|
||||
"PLACEHOLDER": "Category slug for urls",
|
||||
"HELP_TEXT": "app.chatwoot.com/hc/my-portal/en-US/categories/my-slug",
|
||||
"ERROR": "Slug is required"
|
||||
},
|
||||
"DESCRIPTION": {
|
||||
"LABEL": "Description",
|
||||
"PLACEHOLDER": "Give a short description about the category.",
|
||||
"ERROR": "Description is required"
|
||||
},
|
||||
"BUTTONS": {
|
||||
"CREATE": "Update category",
|
||||
"CANCEL": "Cancel"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Category updated successfully",
|
||||
"ERROR_MESSAGE": "Unable to update category"
|
||||
}
|
||||
},
|
||||
"DELETE": {
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Category deleted successfully",
|
||||
"ERROR_MESSAGE": "Unable to delete category"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,737 @@
|
||||
{
|
||||
"INBOX_MGMT": {
|
||||
"HEADER": "Inboxes",
|
||||
"SIDEBAR_TXT": "<p><b>Inbox</b></p> <p> When you connect a website or a facebook Page to Chatwoot, it is called an <b>Inbox</b>. You can have unlimited inboxes in your Chatwoot account. </p><p> Click on <b>Add Inbox</b> to connect a website or a Facebook Page. </p><p> In the Dashboard, you can see all the conversations from all your inboxes in a single place and respond to them under the `Conversations` tab. </p><p> You can also see conversations specific to an inbox by clicking on the inbox name on the left pane of the dashboard. </p>",
|
||||
"LIST": {
|
||||
"404": "There are no inboxes attached to this account."
|
||||
},
|
||||
"CREATE_FLOW": [
|
||||
{
|
||||
"title": "Choose Channel",
|
||||
"route": "settings_inbox_new",
|
||||
"body": "Choose the provider you want to integrate with Chatwoot."
|
||||
},
|
||||
{
|
||||
"title": "Create Inbox",
|
||||
"route": "settings_inboxes_page_channel",
|
||||
"body": "Authenticate your account and create an inbox."
|
||||
},
|
||||
{
|
||||
"title": "Add Agents",
|
||||
"route": "settings_inboxes_add_agents",
|
||||
"body": "Add agents to the created inbox."
|
||||
},
|
||||
{
|
||||
"title": "Voila!",
|
||||
"route": "settings_inbox_finish",
|
||||
"body": "You are all set to go!"
|
||||
}
|
||||
],
|
||||
"ADD": {
|
||||
"CHANNEL_NAME": {
|
||||
"LABEL": "Inbox Name",
|
||||
"PLACEHOLDER": "Enter your inbox name (eg: Acme Inc)",
|
||||
"ERROR": "Please enter a valid inbox name"
|
||||
},
|
||||
"WEBSITE_NAME": {
|
||||
"LABEL": "Website Name",
|
||||
"PLACEHOLDER": "Enter your website name (eg: Acme Inc)"
|
||||
},
|
||||
"FB": {
|
||||
"HELP": "PS: By signing in, we only get access to your Page's messages. Your private messages can never be accessed by Chatwoot.",
|
||||
"CHOOSE_PAGE": "Choose Page",
|
||||
"CHOOSE_PLACEHOLDER": "Select a page from the list",
|
||||
"INBOX_NAME": "Inbox Name",
|
||||
"ADD_NAME": "Add a name for your inbox",
|
||||
"PICK_NAME": "Pick A Name Your Inbox",
|
||||
"PICK_A_VALUE": "Pick a value"
|
||||
},
|
||||
"TWITTER": {
|
||||
"HELP": "To add your Twitter profile as a channel, you need to authenticate your Twitter Profile by clicking on 'Sign in with Twitter' ",
|
||||
"ERROR_MESSAGE": "There was an error connecting to Twitter, please try again",
|
||||
"TWEETS": {
|
||||
"ENABLE": "Create conversations from mentioned Tweets"
|
||||
}
|
||||
},
|
||||
"WEBSITE_CHANNEL": {
|
||||
"TITLE": "Website channel",
|
||||
"DESC": "Create a channel for your website and start supporting your customers via our website widget.",
|
||||
"LOADING_MESSAGE": "Creating Website Support Channel",
|
||||
"CHANNEL_AVATAR": {
|
||||
"LABEL": "Channel Avatar"
|
||||
},
|
||||
"CHANNEL_WEBHOOK_URL": {
|
||||
"LABEL": "Webhook URL",
|
||||
"PLACEHOLDER": "Enter your Webhook URL",
|
||||
"ERROR": "Please enter a valid URL"
|
||||
},
|
||||
"CHANNEL_DOMAIN": {
|
||||
"LABEL": "Website Domain",
|
||||
"PLACEHOLDER": "Enter your website domain (eg: acme.com)"
|
||||
},
|
||||
"CHANNEL_WELCOME_TITLE": {
|
||||
"LABEL": "Welcome Heading",
|
||||
"PLACEHOLDER": "Hi there !"
|
||||
},
|
||||
"CHANNEL_WELCOME_TAGLINE": {
|
||||
"LABEL": "Welcome Tagline",
|
||||
"PLACEHOLDER": "We make it simple to connect with us. Ask us anything, or share your feedback."
|
||||
},
|
||||
"CHANNEL_GREETING_MESSAGE": {
|
||||
"LABEL": "Channel greeting message",
|
||||
"PLACEHOLDER": "Acme Inc typically replies in a few hours."
|
||||
},
|
||||
"CHANNEL_GREETING_TOGGLE": {
|
||||
"LABEL": "Enable channel greeting",
|
||||
"HELP_TEXT": "Auto-send greeting messages when customers start a conversation and send their first message.",
|
||||
"ENABLED": "Enabled",
|
||||
"DISABLED": "Disabled"
|
||||
},
|
||||
"REPLY_TIME": {
|
||||
"TITLE": "Set Reply time",
|
||||
"IN_A_FEW_MINUTES": "In a few minutes",
|
||||
"IN_A_FEW_HOURS": "In a few hours",
|
||||
"IN_A_DAY": "In a day",
|
||||
"HELP_TEXT": "This reply time will be displayed on the live chat widget"
|
||||
},
|
||||
"WIDGET_COLOR": {
|
||||
"LABEL": "Widget Color",
|
||||
"PLACEHOLDER": "Update the widget color used in widget"
|
||||
},
|
||||
"SUBMIT_BUTTON": "Create inbox",
|
||||
"API": {
|
||||
"ERROR_MESSAGE": "We were not able to create a website channel, please try again"
|
||||
}
|
||||
},
|
||||
"TWILIO": {
|
||||
"TITLE": "Twilio SMS/WhatsApp Channel",
|
||||
"DESC": "Integrate Twilio and start supporting your customers via SMS or WhatsApp.",
|
||||
"ACCOUNT_SID": {
|
||||
"LABEL": "Account SID",
|
||||
"PLACEHOLDER": "Please enter your Twilio Account SID",
|
||||
"ERROR": "This field is required"
|
||||
},
|
||||
"API_KEY": {
|
||||
"USE_API_KEY": "Use API Key Authentication",
|
||||
"LABEL": "API Key SID",
|
||||
"PLACEHOLDER": "Please enter your API Key SID",
|
||||
"ERROR": "This field is required"
|
||||
},
|
||||
"API_KEY_SECRET": {
|
||||
"LABEL": "API Key Secret",
|
||||
"PLACEHOLDER": "Please enter your API Key Secret",
|
||||
"ERROR": "This field is required"
|
||||
},
|
||||
"MESSAGING_SERVICE_SID": {
|
||||
"LABEL": "Messaging Service SID",
|
||||
"PLACEHOLDER": "Please enter your Twilio Messaging Service SID",
|
||||
"ERROR": "This field is required",
|
||||
"USE_MESSAGING_SERVICE": "Use a Twilio Messaging Service"
|
||||
},
|
||||
"CHANNEL_TYPE": {
|
||||
"LABEL": "Channel Type",
|
||||
"ERROR": "Please select your Channel Type"
|
||||
},
|
||||
"AUTH_TOKEN": {
|
||||
"LABEL": "Auth Token",
|
||||
"PLACEHOLDER": "Please enter your Twilio Auth Token",
|
||||
"ERROR": "This field is required"
|
||||
},
|
||||
"CHANNEL_NAME": {
|
||||
"LABEL": "Inbox Name",
|
||||
"PLACEHOLDER": "Please enter a inbox name",
|
||||
"ERROR": "This field is required"
|
||||
},
|
||||
"PHONE_NUMBER": {
|
||||
"LABEL": "Phone number",
|
||||
"PLACEHOLDER": "Please enter the phone number from which message will be sent.",
|
||||
"ERROR": "Please provide a valid phone number that starts with a `+` sign and does not contain any spaces."
|
||||
},
|
||||
"API_CALLBACK": {
|
||||
"TITLE": "Callback URL",
|
||||
"SUBTITLE": "You have to configure the message callback URL in Twilio with the URL mentioned here."
|
||||
},
|
||||
"SUBMIT_BUTTON": "Create Twilio Channel",
|
||||
"API": {
|
||||
"ERROR_MESSAGE": "We were not able to authenticate Twilio credentials, please try again"
|
||||
}
|
||||
},
|
||||
"SMS": {
|
||||
"TITLE": "SMS Channel",
|
||||
"DESC": "Start supporting your customers via SMS.",
|
||||
"PROVIDERS": {
|
||||
"LABEL": "API Provider",
|
||||
"TWILIO": "Twilio",
|
||||
"BANDWIDTH": "Bandwidth"
|
||||
},
|
||||
"API": {
|
||||
"ERROR_MESSAGE": "We were not able to save the SMS channel"
|
||||
},
|
||||
"BANDWIDTH": {
|
||||
"ACCOUNT_ID": {
|
||||
"LABEL": "Account ID",
|
||||
"PLACEHOLDER": "Please enter your Bandwidth Account ID",
|
||||
"ERROR": "This field is required"
|
||||
},
|
||||
"API_KEY": {
|
||||
"LABEL": "API Key",
|
||||
"PLACEHOLDER": "Please enter your Bandwith API Key",
|
||||
"ERROR": "This field is required"
|
||||
},
|
||||
"API_SECRET": {
|
||||
"LABEL": "API Secret",
|
||||
"PLACEHOLDER": "Please enter your Bandwith API Secret",
|
||||
"ERROR": "This field is required"
|
||||
},
|
||||
"APPLICATION_ID": {
|
||||
"LABEL": "Application ID",
|
||||
"PLACEHOLDER": "Please enter your Bandwidth Application ID",
|
||||
"ERROR": "This field is required"
|
||||
},
|
||||
"INBOX_NAME": {
|
||||
"LABEL": "Inbox Name",
|
||||
"PLACEHOLDER": "Please enter a inbox name",
|
||||
"ERROR": "This field is required"
|
||||
},
|
||||
"PHONE_NUMBER": {
|
||||
"LABEL": "Phone number",
|
||||
"PLACEHOLDER": "Please enter the phone number from which message will be sent.",
|
||||
"ERROR": "Please provide a valid phone number that starts with a `+` sign and does not contain any spaces."
|
||||
},
|
||||
"SUBMIT_BUTTON": "Create Bandwidth Channel",
|
||||
"API": {
|
||||
"ERROR_MESSAGE": "We were not able to authenticate Bandwidth credentials, please try again"
|
||||
},
|
||||
"API_CALLBACK": {
|
||||
"TITLE": "Callback URL",
|
||||
"SUBTITLE": "You have to configure the message callback URL in Bandwidth with the URL mentioned here."
|
||||
}
|
||||
}
|
||||
},
|
||||
"WHATSAPP": {
|
||||
"TITLE": "WhatsApp Channel",
|
||||
"DESC": "Start supporting your customers via WhatsApp.",
|
||||
"PROVIDERS": {
|
||||
"LABEL": "API Provider",
|
||||
"TWILIO": "Twilio",
|
||||
"WHATSAPP_CLOUD": "WhatsApp Cloud",
|
||||
"360_DIALOG": "360Dialog"
|
||||
},
|
||||
"INBOX_NAME": {
|
||||
"LABEL": "Inbox Name",
|
||||
"PLACEHOLDER": "Please enter an inbox name",
|
||||
"ERROR": "This field is required"
|
||||
},
|
||||
"PHONE_NUMBER": {
|
||||
"LABEL": "Phone number",
|
||||
"PLACEHOLDER": "Please enter the phone number from which message will be sent.",
|
||||
"ERROR": "Please provide a valid phone number that starts with a `+` sign and does not contain any spaces."
|
||||
},
|
||||
"PHONE_NUMBER_ID": {
|
||||
"LABEL": "Phone number ID",
|
||||
"PLACEHOLDER": "Please enter the Phone number ID obtained from Facebook developer dashboard.",
|
||||
"ERROR": "Please enter a valid value."
|
||||
},
|
||||
"BUSINESS_ACCOUNT_ID": {
|
||||
"LABEL": "Business Account ID",
|
||||
"PLACEHOLDER": "Please enter the Business Account ID obtained from Facebook developer dashboard.",
|
||||
"ERROR": "Please enter a valid value."
|
||||
},
|
||||
"WEBHOOK_VERIFY_TOKEN": {
|
||||
"LABEL": "Webhook Verify Token",
|
||||
"PLACEHOLDER": "Enter a verify token which you want to configure for facebook webhooks.",
|
||||
"ERROR": "Please enter a valid value."
|
||||
},
|
||||
"API_KEY": {
|
||||
"LABEL": "API key",
|
||||
"SUBTITLE": "Configure the WhatsApp API key.",
|
||||
"PLACEHOLDER": "API key",
|
||||
"ERROR": "Please enter a valid value."
|
||||
},
|
||||
"API_CALLBACK": {
|
||||
"TITLE": "Callback URL",
|
||||
"SUBTITLE": "You have to configure the webhook URL and the verification token in the Facebook Developer portal with the values shown below.",
|
||||
"WEBHOOK_URL": "Webhook URL",
|
||||
"WEBHOOK_VERIFICATION_TOKEN": "Webhook Verification Token"
|
||||
},
|
||||
"SUBMIT_BUTTON": "Create WhatsApp Channel",
|
||||
"API": {
|
||||
"ERROR_MESSAGE": "We were not able to save the WhatsApp channel"
|
||||
}
|
||||
},
|
||||
"API_CHANNEL": {
|
||||
"TITLE": "API Channel",
|
||||
"DESC": "Integrate with API channel and start supporting your customers.",
|
||||
"CHANNEL_NAME": {
|
||||
"LABEL": "Channel Name",
|
||||
"PLACEHOLDER": "Please enter a channel name",
|
||||
"ERROR": "This field is required"
|
||||
},
|
||||
"WEBHOOK_URL": {
|
||||
"LABEL": "Webhook URL",
|
||||
"SUBTITLE": "Configure the URL where you want to recieve callbacks on events.",
|
||||
"PLACEHOLDER": "Webhook URL"
|
||||
},
|
||||
"SUBMIT_BUTTON": "Create API Channel",
|
||||
"API": {
|
||||
"ERROR_MESSAGE": "We were not able to save the api channel"
|
||||
}
|
||||
},
|
||||
"EMAIL_CHANNEL": {
|
||||
"TITLE": "Email Channel",
|
||||
"DESC": "Integrate you email inbox.",
|
||||
"CHANNEL_NAME": {
|
||||
"LABEL": "Channel Name",
|
||||
"PLACEHOLDER": "Please enter a channel name",
|
||||
"ERROR": "This field is required"
|
||||
},
|
||||
"EMAIL": {
|
||||
"LABEL": "Email",
|
||||
"SUBTITLE": "Provide the email address where your customers send support requests.",
|
||||
"PLACEHOLDER": "Email"
|
||||
},
|
||||
"SUBMIT_BUTTON": "Create Email Channel",
|
||||
"API": {
|
||||
"ERROR_MESSAGE": "We were not able to save the email channel"
|
||||
},
|
||||
"FINISH_MESSAGE": "Start forwarding your emails to the following email address."
|
||||
},
|
||||
"LINE_CHANNEL": {
|
||||
"TITLE": "LINE Channel",
|
||||
"DESC": "Integrate with LINE channel and start supporting your customers.",
|
||||
"CHANNEL_NAME": {
|
||||
"LABEL": "Channel Name",
|
||||
"PLACEHOLDER": "Please enter a channel name",
|
||||
"ERROR": "This field is required"
|
||||
},
|
||||
"LINE_CHANNEL_ID": {
|
||||
"LABEL": "LINE Channel ID",
|
||||
"PLACEHOLDER": "LINE Channel ID"
|
||||
},
|
||||
"LINE_CHANNEL_SECRET": {
|
||||
"LABEL": "LINE Channel Secret",
|
||||
"PLACEHOLDER": "LINE Channel Secret"
|
||||
},
|
||||
"LINE_CHANNEL_TOKEN": {
|
||||
"LABEL": "LINE Channel Token",
|
||||
"PLACEHOLDER": "LINE Channel Token"
|
||||
},
|
||||
"SUBMIT_BUTTON": "Create LINE Channel",
|
||||
"API": {
|
||||
"ERROR_MESSAGE": "We were not able to save the LINE channel"
|
||||
},
|
||||
"API_CALLBACK": {
|
||||
"TITLE": "Callback URL",
|
||||
"SUBTITLE": "You have to configure the webhook URL in LINE application with the URL mentioned here."
|
||||
}
|
||||
},
|
||||
"TELEGRAM_CHANNEL": {
|
||||
"TITLE": "Telegram Channel",
|
||||
"DESC": "Integrate with Telegram channel and start supporting your customers.",
|
||||
"BOT_TOKEN": {
|
||||
"LABEL": "Bot Token",
|
||||
"SUBTITLE": "Configure the bot token you have obtained from Telegram BotFather.",
|
||||
"PLACEHOLDER": "Bot Token"
|
||||
},
|
||||
"SUBMIT_BUTTON": "Create Telegram Channel",
|
||||
"API": {
|
||||
"ERROR_MESSAGE": "We were not able to save the telegram channel"
|
||||
}
|
||||
},
|
||||
"AUTH": {
|
||||
"TITLE": "Choose a channel",
|
||||
"DESC": "Chatwoot supports live-chat widgets, Facebook Messenger, WhatsApp, Emails, etc., as channels. If you want to build a custom channel, you can create it using the API channel. To get started, choose one of the channels below."
|
||||
},
|
||||
"AGENTS": {
|
||||
"TITLE": "Agents",
|
||||
"DESC": "Here you can add agents to manage your newly created inbox. Only these selected agents will have access to your inbox. Agents which are not part of this inbox will not be able to see or respond to messages in this inbox when they login. <br> <b>PS:</b> As an administrator, if you need access to all inboxes, you should add yourself as agent to all inboxes that you create.",
|
||||
"VALIDATION_ERROR": "Add atleast one agent to your new Inbox",
|
||||
"PICK_AGENTS": "Pick agents for the inbox"
|
||||
},
|
||||
"DETAILS": {
|
||||
"TITLE": "Inbox Details",
|
||||
"DESC": "From the dropdown below, select the Facebook Page you want to connect to Chatwoot. You can also give a custom name to your inbox for better identification."
|
||||
},
|
||||
"FINISH": {
|
||||
"TITLE": "Nailed It!",
|
||||
"DESC": "You have successfully finished integrating your Facebook Page with Chatwoot. Next time a customer messages your Page, the conversation will automatically appear on your inbox.<br>We are also providing you with a widget script that you can easily add to your website. Once this is live on your website, customers can message you right from your website without the help of any external tool and the conversation will appear right here, on Chatwoot.<br>Cool, huh? Well, we sure try to be :)"
|
||||
},
|
||||
"EMAIL_PROVIDER": {
|
||||
"TITLE": "Select your email provider",
|
||||
"DESCRIPTION": "Select an email provider from the list below. If you don't see your email provider in the list, you can select the other provider option and provide the IMAP and SMTP Credentials."
|
||||
},
|
||||
"MICROSOFT": {
|
||||
"TITLE": "Microsoft Email",
|
||||
"DESCRIPTION": "Click on the Sign in with Microsoft button to get started. You will redirected to the email sign in page. Once you accept the requested permissions, you would be redirected back to the inbox creation step.",
|
||||
"EMAIL_PLACEHOLDER": "Enter email address",
|
||||
"HELP": "To add your Microsoft account as a channel, you need to authenticate your Microsoft account by clicking on 'Sign in with Microsoft' ",
|
||||
"ERROR_MESSAGE": "There was an error connecting to Microsoft, please try again"
|
||||
}
|
||||
},
|
||||
"DETAILS": {
|
||||
"LOADING_FB": "Authenticating you with Facebook...",
|
||||
"ERROR_FB_AUTH": "Something went wrong, Please refresh page...",
|
||||
"CREATING_CHANNEL": "Creating your Inbox...",
|
||||
"TITLE": "Configure Inbox Details",
|
||||
"DESC": ""
|
||||
},
|
||||
"AGENTS": {
|
||||
"BUTTON_TEXT": "Add agents",
|
||||
"ADD_AGENTS": "Adding Agents to your Inbox..."
|
||||
},
|
||||
"FINISH": {
|
||||
"TITLE": "Your Inbox is ready!",
|
||||
"MESSAGE": "You can now engage with your customers through your new Channel. Happy supporting",
|
||||
"BUTTON_TEXT": "Take me there",
|
||||
"MORE_SETTINGS": "More settings",
|
||||
"WEBSITE_SUCCESS": "You have successfully finished creating a website channel. Copy the code shown below and paste it on your website. Next time a customer use the live chat, the conversation will automatically appear on your inbox."
|
||||
},
|
||||
"REAUTH": "Reauthorize",
|
||||
"VIEW": "View",
|
||||
"EDIT": {
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Inbox settings updated successfully",
|
||||
"AUTO_ASSIGNMENT_SUCCESS_MESSAGE": "Auto assignment updated successfully",
|
||||
"ERROR_MESSAGE": "We couldn't update inbox settings. Please try again later."
|
||||
},
|
||||
"EMAIL_COLLECT_BOX": {
|
||||
"ENABLED": "Enabled",
|
||||
"DISABLED": "Disabled"
|
||||
},
|
||||
"ENABLE_CSAT": {
|
||||
"ENABLED": "Enabled",
|
||||
"DISABLED": "Disabled"
|
||||
},
|
||||
"SENDER_NAME_SECTION": {
|
||||
"TITLE": "Sender name",
|
||||
"SUB_TEXT": "Select the name shown to the your customer when they receive emails from your agents.",
|
||||
"FOR_EG": "For eg:",
|
||||
"FRIENDLY": {
|
||||
"TITLE": "Friendly",
|
||||
"FROM": "from",
|
||||
"SUBTITLE": "Add the name of the agent who sent the reply in the sender name to make it friendly."
|
||||
},
|
||||
"PROFESSIONAL": {
|
||||
"TITLE": "Professional",
|
||||
"SUBTITLE": "Use only the configured business name as the sender name in the email header."
|
||||
},
|
||||
"BUSINESS_NAME": {
|
||||
"BUTTON_TEXT": "+ Configure your business name",
|
||||
"PLACEHOLDER": "Enter your business name",
|
||||
"SAVE_BUTTON_TEXT": "Save"
|
||||
}
|
||||
},
|
||||
"ALLOW_MESSAGES_AFTER_RESOLVED": {
|
||||
"ENABLED": "Enabled",
|
||||
"DISABLED": "Disabled"
|
||||
},
|
||||
"ENABLE_CONTINUITY_VIA_EMAIL": {
|
||||
"ENABLED": "Enabled",
|
||||
"DISABLED": "Disabled"
|
||||
},
|
||||
"LOCK_TO_SINGLE_CONVERSATION": {
|
||||
"ENABLED": "Enabled",
|
||||
"DISABLED": "Disabled"
|
||||
},
|
||||
"ENABLE_HMAC": {
|
||||
"LABEL": "Enable"
|
||||
}
|
||||
},
|
||||
"DELETE": {
|
||||
"BUTTON_TEXT": "Delete",
|
||||
"AVATAR_DELETE_BUTTON_TEXT": "Delete Avatar",
|
||||
"CONFIRM": {
|
||||
"TITLE": "Confirm Deletion",
|
||||
"MESSAGE": "Are you sure to delete ",
|
||||
"PLACE_HOLDER": "Please type {inboxName} to confirm",
|
||||
"YES": "Yes, Delete ",
|
||||
"NO": "No, Keep "
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Inbox deleted successfully",
|
||||
"ERROR_MESSAGE": "Could not delete inbox. Please try again later.",
|
||||
"AVATAR_SUCCESS_MESSAGE": "Inbox avatar deleted successfully",
|
||||
"AVATAR_ERROR_MESSAGE": "Could not delete the inbox avatar. Please try again later."
|
||||
}
|
||||
},
|
||||
"TABS": {
|
||||
"SETTINGS": "Settings",
|
||||
"COLLABORATORS": "Collaborators",
|
||||
"CONFIGURATION": "Configuration",
|
||||
"CAMPAIGN": "Campaigns",
|
||||
"PRE_CHAT_FORM": "Pre Chat Form",
|
||||
"BUSINESS_HOURS": "Business Hours",
|
||||
"WIDGET_BUILDER": "Widget Builder",
|
||||
"BOT_CONFIGURATION": "Bot Configuration"
|
||||
},
|
||||
"SETTINGS": "Settings",
|
||||
"FEATURES": {
|
||||
"LABEL": "Features",
|
||||
"DISPLAY_FILE_PICKER": "Display file picker on the widget",
|
||||
"DISPLAY_EMOJI_PICKER": "Display emoji picker on the widget",
|
||||
"ALLOW_END_CONVERSATION": "Allow users to end conversation from the widget",
|
||||
"USE_INBOX_AVATAR_FOR_BOT": "Use inbox name and avatar for the bot"
|
||||
},
|
||||
"SETTINGS_POPUP": {
|
||||
"MESSENGER_HEADING": "Messenger Script",
|
||||
"MESSENGER_SUB_HEAD": "Place this button inside your body tag",
|
||||
"INBOX_AGENTS": "Agents",
|
||||
"INBOX_AGENTS_SUB_TEXT": "Add or remove agents from this inbox",
|
||||
"AGENT_ASSIGNMENT": "Conversation Assignment",
|
||||
"AGENT_ASSIGNMENT_SUB_TEXT": "Update conversation assignment settings",
|
||||
"UPDATE": "Update",
|
||||
"ENABLE_EMAIL_COLLECT_BOX": "Enable email collect box",
|
||||
"ENABLE_EMAIL_COLLECT_BOX_SUB_TEXT": "Enable or disable email collect box on new conversation",
|
||||
"AUTO_ASSIGNMENT": "Enable auto assignment",
|
||||
"ENABLE_CSAT": "Enable CSAT",
|
||||
"SENDER_NAME_SECTION": "Enable Agent Name in Email",
|
||||
"ENABLE_CSAT_SUB_TEXT": "Enable/Disable CSAT(Customer satisfaction) survey after resolving a conversation",
|
||||
"SENDER_NAME_SECTION_TEXT": "Enable/Disable showing Agent's name in email, if disabled it will show business name",
|
||||
"ENABLE_CONTINUITY_VIA_EMAIL": "Enable conversation continuity via email",
|
||||
"ENABLE_CONTINUITY_VIA_EMAIL_SUB_TEXT": "Conversations will continue over email if the contact email address is available.",
|
||||
"LOCK_TO_SINGLE_CONVERSATION": "Lock to single conversation",
|
||||
"LOCK_TO_SINGLE_CONVERSATION_SUB_TEXT": "Enable or disable multiple conversations for the same contact in this inbox",
|
||||
"INBOX_UPDATE_TITLE": "Inbox Settings",
|
||||
"INBOX_UPDATE_SUB_TEXT": "Update your inbox settings",
|
||||
"AUTO_ASSIGNMENT_SUB_TEXT": "Enable or disable the automatic assignment of new conversations to the agents added to this inbox.",
|
||||
"HMAC_VERIFICATION": "User Identity Validation",
|
||||
"HMAC_DESCRIPTION": "With this key you can generate a secret token that can be used to verify the identity of your users.",
|
||||
"HMAC_LINK_TO_DOCS": "You can read more here.",
|
||||
"HMAC_MANDATORY_VERIFICATION": "Enforce User Identity Validation",
|
||||
"HMAC_MANDATORY_DESCRIPTION": "If enabled, requests that cannot be verified will be rejected.",
|
||||
"INBOX_IDENTIFIER": "Inbox Identifier",
|
||||
"INBOX_IDENTIFIER_SUB_TEXT": "Use the `inbox_identifier` token shown here to authentication your API clients.",
|
||||
"FORWARD_EMAIL_TITLE": "Forward to Email",
|
||||
"FORWARD_EMAIL_SUB_TEXT": "Start forwarding your emails to the following email address.",
|
||||
"ALLOW_MESSAGES_AFTER_RESOLVED": "Allow messages after conversation resolved",
|
||||
"ALLOW_MESSAGES_AFTER_RESOLVED_SUB_TEXT": "Allow the end-users to send messages even after the conversation is resolved.",
|
||||
"WHATSAPP_SECTION_SUBHEADER": "This API Key is used for the integration with the WhatsApp APIs.",
|
||||
"WHATSAPP_SECTION_UPDATE_SUBHEADER": "Enter the updated key to be used for the integration with the WhatsApp APIs.",
|
||||
"WHATSAPP_SECTION_TITLE": "API Key",
|
||||
"WHATSAPP_SECTION_UPDATE_TITLE": "Update API Key",
|
||||
"WHATSAPP_SECTION_UPDATE_PLACEHOLDER": "Enter the new API Key here",
|
||||
"WHATSAPP_SECTION_UPDATE_BUTTON": "Update",
|
||||
"WHATSAPP_WEBHOOK_TITLE": "Webhook Verify Token",
|
||||
"WHATSAPP_WEBHOOK_SUBHEADER": "This token is used to verify the authenticity of the webhook endpoint.",
|
||||
"UPDATE_PRE_CHAT_FORM_SETTINGS": "Update Pre Chat Form Settings"
|
||||
},
|
||||
"HELP_CENTER": {
|
||||
"LABEL": "Help Center",
|
||||
"PLACEHOLDER": "Select Help Center",
|
||||
"SELECT_PLACEHOLDER": "Select Help Center",
|
||||
"REMOVE": "Remove Help Center",
|
||||
"SUB_TEXT": "Attach a Help Center with the inbox"
|
||||
},
|
||||
"AUTO_ASSIGNMENT": {
|
||||
"MAX_ASSIGNMENT_LIMIT": "Auto assignment limit",
|
||||
"MAX_ASSIGNMENT_LIMIT_RANGE_ERROR": "Please enter a value greater than 0",
|
||||
"MAX_ASSIGNMENT_LIMIT_SUB_TEXT": "Limit the maximum number of conversations from this inbox that can be auto assigned to an agent"
|
||||
},
|
||||
"FACEBOOK_REAUTHORIZE": {
|
||||
"TITLE": "Reauthorize",
|
||||
"SUBTITLE": "Your Facebook connection has expired, please reconnect your Facebook page to continue services",
|
||||
"MESSAGE_SUCCESS": "Reconnection successful",
|
||||
"MESSAGE_ERROR": "There was an error, please try again"
|
||||
},
|
||||
"PRE_CHAT_FORM": {
|
||||
"DESCRIPTION": "Pre chat forms enable you to capture user information before they start conversation with you.",
|
||||
"SET_FIELDS": "Pre chat form fields",
|
||||
"SET_FIELDS_HEADER": {
|
||||
"FIELDS": "Fields",
|
||||
"LABEL": "Label",
|
||||
"PLACE_HOLDER": "Placeholder",
|
||||
"KEY": "Key",
|
||||
"TYPE": "Type",
|
||||
"REQUIRED": "Required"
|
||||
},
|
||||
"ENABLE": {
|
||||
"LABEL": "Enable pre chat form",
|
||||
"OPTIONS": {
|
||||
"ENABLED": "Yes",
|
||||
"DISABLED": "No"
|
||||
}
|
||||
},
|
||||
"PRE_CHAT_MESSAGE": {
|
||||
"LABEL": "Pre chat message",
|
||||
"PLACEHOLDER": "This message would be visible to the users along with the form"
|
||||
},
|
||||
"REQUIRE_EMAIL": {
|
||||
"LABEL": "Visitors should provide their name and email address before starting the chat"
|
||||
}
|
||||
},
|
||||
"BUSINESS_HOURS": {
|
||||
"TITLE": "Set your availability",
|
||||
"SUBTITLE": "Set your availability on your livechat widget",
|
||||
"WEEKLY_TITLE": "Set your weekly hours",
|
||||
"TIMEZONE_LABEL": "Select timezone",
|
||||
"UPDATE": "Update business hours settings",
|
||||
"TOGGLE_AVAILABILITY": "Enable business availability for this inbox",
|
||||
"UNAVAILABLE_MESSAGE_LABEL": "Unavailable message for visitors",
|
||||
"TOGGLE_HELP": "Enabling business availability will show the available hours on live chat widget even if all the agents are offline. Outside available hours vistors can be warned with a message and a pre-chat form.",
|
||||
"DAY": {
|
||||
"ENABLE": "Enable availability for this day",
|
||||
"UNAVAILABLE": "Unavailable",
|
||||
"HOURS": "hours",
|
||||
"VALIDATION_ERROR": "Starting time should be before closing time.",
|
||||
"CHOOSE": "Choose"
|
||||
},
|
||||
"ALL_DAY": "All-Day"
|
||||
},
|
||||
"IMAP": {
|
||||
"TITLE": "IMAP",
|
||||
"SUBTITLE": "Set your IMAP details",
|
||||
"NOTE_TEXT": "To enable SMTP, please configure IMAP.",
|
||||
"UPDATE": "Update IMAP settings",
|
||||
"TOGGLE_AVAILABILITY": "Enable IMAP configuration for this inbox",
|
||||
"TOGGLE_HELP": "Enabling IMAP will help the user to recieve email",
|
||||
"EDIT": {
|
||||
"SUCCESS_MESSAGE": "IMAP settings updated successfully",
|
||||
"ERROR_MESSAGE": "Unable to update IMAP settings"
|
||||
},
|
||||
"ADDRESS": {
|
||||
"LABEL": "Address",
|
||||
"PLACE_HOLDER": "Address (Eg: imap.gmail.com)"
|
||||
},
|
||||
"PORT": {
|
||||
"LABEL": "Port",
|
||||
"PLACE_HOLDER": "Port"
|
||||
},
|
||||
"LOGIN": {
|
||||
"LABEL": "Login",
|
||||
"PLACE_HOLDER": "Login"
|
||||
},
|
||||
"PASSWORD": {
|
||||
"LABEL": "Password",
|
||||
"PLACE_HOLDER": "Password"
|
||||
},
|
||||
"ENABLE_SSL": "Enable SSL"
|
||||
},
|
||||
"MICROSOFT": {
|
||||
"TITLE": "Microsoft",
|
||||
"SUBTITLE": "Reauthorize your MICROSOFT account"
|
||||
},
|
||||
"SMTP": {
|
||||
"TITLE": "SMTP",
|
||||
"SUBTITLE": "Set your SMTP details",
|
||||
"UPDATE": "Update SMTP settings",
|
||||
"TOGGLE_AVAILABILITY": "Enable SMTP configuration for this inbox",
|
||||
"TOGGLE_HELP": "Enabling SMTP will help the user to send email",
|
||||
"EDIT": {
|
||||
"SUCCESS_MESSAGE": "SMTP settings updated successfully",
|
||||
"ERROR_MESSAGE": "Unable to update SMTP settings"
|
||||
},
|
||||
"ADDRESS": {
|
||||
"LABEL": "Address",
|
||||
"PLACE_HOLDER": "Address (Eg: smtp.gmail.com)"
|
||||
},
|
||||
"PORT": {
|
||||
"LABEL": "Port",
|
||||
"PLACE_HOLDER": "Port"
|
||||
},
|
||||
"LOGIN": {
|
||||
"LABEL": "Login",
|
||||
"PLACE_HOLDER": "Login"
|
||||
},
|
||||
"PASSWORD": {
|
||||
"LABEL": "Password",
|
||||
"PLACE_HOLDER": "Password"
|
||||
},
|
||||
"DOMAIN": {
|
||||
"LABEL": "Domain",
|
||||
"PLACE_HOLDER": "Domain"
|
||||
},
|
||||
"ENCRYPTION": "Encryption",
|
||||
"SSL_TLS": "SSL/TLS",
|
||||
"START_TLS": "STARTTLS",
|
||||
"OPEN_SSL_VERIFY_MODE": "Open SSL Verify Mode",
|
||||
"AUTH_MECHANISM": "Authentication"
|
||||
},
|
||||
"NOTE": "Note: ",
|
||||
"WIDGET_BUILDER": {
|
||||
"WIDGET_OPTIONS": {
|
||||
"AVATAR": {
|
||||
"LABEL": "Website Avatar",
|
||||
"DELETE": {
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Avatar deleted successfully",
|
||||
"ERROR_MESSAGE": "There was an error, please try again"
|
||||
}
|
||||
}
|
||||
},
|
||||
"WEBSITE_NAME": {
|
||||
"LABEL": "Website Name",
|
||||
"PLACE_HOLDER": "Enter your website name (eg: Acme Inc)",
|
||||
"ERROR": "Please enter a valid website name"
|
||||
},
|
||||
"WELCOME_HEADING": {
|
||||
"LABEL": "Welcome Heading",
|
||||
"PLACE_HOLDER": "Hi there!"
|
||||
},
|
||||
"WELCOME_TAGLINE": {
|
||||
"LABEL": "Welcome Tagline",
|
||||
"PLACE_HOLDER": "We make it simple to connect with us. Ask us anything, or share your feedback."
|
||||
},
|
||||
"REPLY_TIME": {
|
||||
"LABEL": "Reply Time",
|
||||
"IN_A_FEW_MINUTES": "In a few minutes",
|
||||
"IN_A_FEW_HOURS": "In a few hours",
|
||||
"IN_A_DAY": "In a day"
|
||||
},
|
||||
"WIDGET_COLOR_LABEL": "Widget Color",
|
||||
"WIDGET_BUBBLE_POSITION_LABEL": "Widget Bubble Position",
|
||||
"WIDGET_BUBBLE_TYPE_LABEL": "Widget Bubble Type",
|
||||
"WIDGET_BUBBLE_LAUNCHER_TITLE": {
|
||||
"DEFAULT": "Chat with us",
|
||||
"LABEL": "Widget Bubble Launcher Title",
|
||||
"PLACE_HOLDER": "Chat with us"
|
||||
},
|
||||
"UPDATE": {
|
||||
"BUTTON_TEXT": "Update Widget Settings",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Widget settings updated successfully",
|
||||
"ERROR_MESSAGE": "Unable to update widget settings"
|
||||
}
|
||||
},
|
||||
"WIDGET_VIEW_OPTION": {
|
||||
"PREVIEW": "Preview",
|
||||
"SCRIPT": "Script"
|
||||
},
|
||||
"WIDGET_BUBBLE_POSITION": {
|
||||
"LEFT": "Left",
|
||||
"RIGHT": "Right"
|
||||
},
|
||||
"WIDGET_BUBBLE_TYPE": {
|
||||
"STANDARD": "Standard",
|
||||
"EXPANDED_BUBBLE": "Expanded Bubble"
|
||||
}
|
||||
},
|
||||
"WIDGET_SCREEN": {
|
||||
"DEFAULT": "Default",
|
||||
"CHAT": "Chat"
|
||||
},
|
||||
"REPLY_TIME": {
|
||||
"IN_A_FEW_MINUTES": "Typically replies in a few minutes",
|
||||
"IN_A_FEW_HOURS": "Typically replies in a few hours",
|
||||
"IN_A_DAY": "Typically replies in a day"
|
||||
},
|
||||
"FOOTER": {
|
||||
"START_CONVERSATION_BUTTON_TEXT": "Start Conversation",
|
||||
"CHAT_INPUT_PLACEHOLDER": "Type your message"
|
||||
},
|
||||
"BODY": {
|
||||
"TEAM_AVAILABILITY": {
|
||||
"ONLINE": "We are Online",
|
||||
"OFFLINE": "We are away at the moment"
|
||||
},
|
||||
"USER_MESSAGE": "Hi",
|
||||
"AGENT_MESSAGE": "Hello"
|
||||
},
|
||||
"BRANDING_TEXT": "Powered by Chatwoot",
|
||||
"SCRIPT_SETTINGS": "\n window.chatwootSettings = {options};"
|
||||
},
|
||||
"EMAIL_PROVIDERS": {
|
||||
"MICROSOFT": "Microsoft",
|
||||
"OTHER_PROVIDERS": "Other Providers"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
{
|
||||
"INTEGRATION_APPS": {
|
||||
"FETCHING": "Fetching Integrations",
|
||||
"NO_HOOK_CONFIGURED": "There are no %{integrationId} integrations configured in this account.",
|
||||
"HEADER": "Applications",
|
||||
"STATUS": {
|
||||
"ENABLED": "Enabled",
|
||||
"DISABLED": "Disabled"
|
||||
},
|
||||
"CONFIGURE": "Configure",
|
||||
"ADD_BUTTON": "Add a new hook",
|
||||
"DELETE": {
|
||||
"TITLE": {
|
||||
"INBOX": "Confirm deletion",
|
||||
"ACCOUNT": "Disconnect"
|
||||
},
|
||||
"MESSAGE": {
|
||||
"INBOX": "Are you sure to delete?",
|
||||
"ACCOUNT": "Are you sure to disconnect?"
|
||||
},
|
||||
"CONFIRM_BUTTON_TEXT": {
|
||||
"INBOX": "Yes, Delete",
|
||||
"ACCOUNT": "Yes, Disconnect"
|
||||
},
|
||||
"CANCEL_BUTTON_TEXT": "Cancel",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Hook deleted successfully",
|
||||
"ERROR_MESSAGE": "Could not connect to Woot Server, Please try again later"
|
||||
}
|
||||
},
|
||||
"LIST": {
|
||||
"FETCHING": "Fetching integration hooks",
|
||||
"INBOX": "Inbox",
|
||||
"DELETE": {
|
||||
"BUTTON_TEXT": "Delete"
|
||||
}
|
||||
},
|
||||
"ADD": {
|
||||
"FORM": {
|
||||
"INBOX": {
|
||||
"LABEL": "Select Inbox",
|
||||
"PLACEHOLDER": "Select Inbox"
|
||||
},
|
||||
"SUBMIT": "Create",
|
||||
"CANCEL": "Cancel"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Integration hook added successfully",
|
||||
"ERROR_MESSAGE": "Could not connect to Woot Server, Please try again later"
|
||||
}
|
||||
},
|
||||
"CONNECT": {
|
||||
"BUTTON_TEXT": "Connect"
|
||||
},
|
||||
"DISCONNECT": {
|
||||
"BUTTON_TEXT": "Disconnect"
|
||||
},
|
||||
"SIDEBAR_DESCRIPTION": {
|
||||
"DIALOGFLOW": "Dialogflow is a natural language understanding platform that makes it easy to design and integrate a conversational user interface into your mobile app, web application, device, bot, interactive voice response system, and so on. <br /> <br /> Dialogflow integration with %{installationName} allows you to configure a Dialogflow bot with your inboxes which lets the bot handle the queries initially and hand them over to an agent when needed. Dialogflow can be used to qualifying the leads, reduce the workload of agents by providing frequently asked questions etc. <br /> <br /> To add Dialogflow, you need to create a Service Account in your Google project console and share the credentials. Please refer to the Dialogflow docs for more information."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,214 @@
|
||||
{
|
||||
"INTEGRATION_SETTINGS": {
|
||||
"HEADER": "Integrations",
|
||||
"WEBHOOK": {
|
||||
"SUBSCRIBED_EVENTS": "Subscribed Events",
|
||||
"FORM": {
|
||||
"CANCEL": "Cancel",
|
||||
"DESC": "Webhook events provide you the realtime information about what's happening in your Chatwoot account. Please enter a valid URL to configure a callback.",
|
||||
"SUBSCRIPTIONS": {
|
||||
"LABEL": "Events",
|
||||
"EVENTS": {
|
||||
"CONVERSATION_CREATED": "Conversation Created",
|
||||
"CONVERSATION_STATUS_CHANGED": "Conversation Status Changed",
|
||||
"CONVERSATION_UPDATED": "Conversation Updated",
|
||||
"MESSAGE_CREATED": "Message created",
|
||||
"MESSAGE_UPDATED": "Message updated",
|
||||
"WEBWIDGET_TRIGGERED": "Live chat widget opened by the user",
|
||||
"CONTACT_CREATED": "Contact created",
|
||||
"CONTACT_UPDATED": "Contact updated"
|
||||
}
|
||||
},
|
||||
"END_POINT": {
|
||||
"LABEL": "Webhook URL",
|
||||
"PLACEHOLDER": "Example: %{webhookExampleURL}",
|
||||
"ERROR": "Please enter a valid URL"
|
||||
},
|
||||
"EDIT_SUBMIT": "Update webhook",
|
||||
"ADD_SUBMIT": "Create webhook"
|
||||
},
|
||||
"TITLE": "Webhook",
|
||||
"CONFIGURE": "Configure",
|
||||
"HEADER": "Webhook settings",
|
||||
"HEADER_BTN_TXT": "Add new webhook",
|
||||
"LOADING": "Fetching attached webhooks",
|
||||
"SEARCH_404": "There are no items matching this query",
|
||||
"SIDEBAR_TXT": "<p><b>Webhooks</b> </p> <p>Webhooks are HTTP callbacks which can be defined for every account. They are triggered by events like message creation in Chatwoot. You can create more than one webhook for this account. <br /><br /> For creating a <b>webhook</b>, click on the <b>Add new webhook</b> button. You can also remove any existing webhook by clicking on the Delete button.</p>",
|
||||
"LIST": {
|
||||
"404": "There are no webhooks configured for this account.",
|
||||
"TITLE": "Manage webhooks",
|
||||
"TABLE_HEADER": [
|
||||
"Webhook endpoint",
|
||||
"Actions"
|
||||
]
|
||||
},
|
||||
"EDIT": {
|
||||
"BUTTON_TEXT": "Edit",
|
||||
"TITLE": "Edit webhook",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Webhook configuration updated successfully",
|
||||
"ERROR_MESSAGE": "Could not connect to Woot Server, Please try again later"
|
||||
}
|
||||
},
|
||||
"ADD": {
|
||||
"CANCEL": "Cancel",
|
||||
"TITLE": "Add new webhook",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Webhook configuration added successfully",
|
||||
"ERROR_MESSAGE": "Could not connect to Woot Server, Please try again later"
|
||||
}
|
||||
},
|
||||
"DELETE": {
|
||||
"BUTTON_TEXT": "Delete",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Webhook deleted successfully",
|
||||
"ERROR_MESSAGE": "Could not connect to Woot Server, Please try again later"
|
||||
},
|
||||
"CONFIRM": {
|
||||
"TITLE": "Confirm Deletion",
|
||||
"MESSAGE": "Are you sure to delete the webhook? (%{webhookURL})",
|
||||
"YES": "Yes, Delete ",
|
||||
"NO": "No, Keep it"
|
||||
}
|
||||
}
|
||||
},
|
||||
"SLACK": {
|
||||
"DELETE": "Delete",
|
||||
"DELETE_CONFIRMATION": {
|
||||
"TITLE": "Delete the integration",
|
||||
"MESSAGE": "Are you sure you want to delete the integration? Doing so will result in the loss of access to conversations on your Slack workspace."
|
||||
},
|
||||
"HELP_TEXT": {
|
||||
"TITLE": "How to use the Slack Integration?",
|
||||
"BODY": "With this integration, all of your incoming conversations will be synced to the ***%{selectedChannelName}*** channel in your Slack workspace. You can manage all your customer conversations right within the channel and never miss a message.\n\nHere are the main features of the integration:\n\n**Respond to conversations from within Slack:** To respond to a conversation in the ***%{selectedChannelName}*** Slack channel, simply type out your message and send it as a thread. This will create a response back to the customer through Chatwoot. It's that simple!\n\n **Create private notes:** If you want to create private notes instead of replies, start your message with ***`note:`***. This ensures that your message is kept private and won't be visible to the customer.\n\n**Associate an agent profile:** If the person who replied on Slack has an agent profile in Chatwoot under the same email, the replies will be associated with that agent profile automatically. This means you can easily track who said what and when. On the other hand, when the replier doesn't have an associated agent profile, the replies will appear from the bot profile to the customer.",
|
||||
"SELECTED": "selected"
|
||||
},
|
||||
"SELECT_CHANNEL": {
|
||||
"OPTION_LABEL": "Select a channel",
|
||||
"UPDATE": "Update",
|
||||
"BUTTON_TEXT": "Connect channel",
|
||||
"DESCRIPTION": "Your Slack workspace is now linked with Chatwoot. However, the integration is currently inactive. To activate the integration and connect a channel to Chatwoot, please click the button below.\n\n**Note:** If you are attempting to connect a private channel, add the Chatwoot app to the Slack channel before proceeding with this step.",
|
||||
"ATTENTION_REQUIRED": "Attention required",
|
||||
"EXPIRED": "Your Slack integration has expired. To continue receiving messages on Slack, please delete the integration and connect your workspace again."
|
||||
},
|
||||
"UPDATE_ERROR": "There was an error updating the integration, please try again",
|
||||
"UPDATE_SUCCESS": "The channel is connected successfully",
|
||||
"FAILED_TO_FETCH_CHANNELS": "There was an error fetching the channels from Slack, please try again"
|
||||
},
|
||||
"DYTE": {
|
||||
"CLICK_HERE_TO_JOIN": "Click here to join",
|
||||
"LEAVE_THE_ROOM": "Leave the room",
|
||||
"START_VIDEO_CALL_HELP_TEXT": "Start a new video call with the customer",
|
||||
"JOIN_ERROR": "There was an error joining the call, please try again",
|
||||
"CREATE_ERROR": "There was an error creating a meeting link, please try again"
|
||||
},
|
||||
"OPEN_AI": {
|
||||
"AI_ASSIST": "AI Assist",
|
||||
"WITH_AI": " %{option} with AI ",
|
||||
"OPTIONS": {
|
||||
"REPLY_SUGGESTION": "Reply Suggestion",
|
||||
"SUMMARIZE": "Summarize",
|
||||
"REPHRASE": "Improve Writing",
|
||||
"FIX_SPELLING_GRAMMAR": "Fix Spelling and Grammar",
|
||||
"SHORTEN": "Shorten",
|
||||
"EXPAND": "Expand",
|
||||
"MAKE_FRIENDLY": "Change message tone to friendly",
|
||||
"MAKE_FORMAL": "Use formal tone",
|
||||
"SIMPLIFY": "Simplify"
|
||||
},
|
||||
"ASSISTANCE_MODAL": {
|
||||
"DRAFT_TITLE": "Draft content",
|
||||
"GENERATED_TITLE": "Generated content",
|
||||
"AI_WRITING": "AI is writing",
|
||||
"BUTTONS": {
|
||||
"APPLY": "Use this suggestion",
|
||||
"CANCEL": "Cancel"
|
||||
}
|
||||
},
|
||||
"CTA_MODAL": {
|
||||
"TITLE": "Integrate with OpenAI",
|
||||
"DESC": "Bring advanced AI features to your dashboard with OpenAI's GPT models. To begin, enter the API key from your OpenAI account.",
|
||||
"KEY_PLACEHOLDER": "Enter your OpenAI API key",
|
||||
"BUTTONS": {
|
||||
"NEED_HELP": "Need help?",
|
||||
"DISMISS": "Dismiss",
|
||||
"FINISH": "Finish Setup"
|
||||
},
|
||||
"DISMISS_MESSAGE": "You can setup OpenAI integration later Whenever you want.",
|
||||
"SUCCESS_MESSAGE": "OpenAI integration setup successfully"
|
||||
},
|
||||
"TITLE": "Improve With AI",
|
||||
"SUMMARY_TITLE": "Summary with AI",
|
||||
"REPLY_TITLE": "Reply suggestion with AI",
|
||||
"SUBTITLE": "An improved reply will be generated using AI, based on your current draft.",
|
||||
"TONE": {
|
||||
"TITLE": "Tone",
|
||||
"OPTIONS": {
|
||||
"PROFESSIONAL": "Professional",
|
||||
"FRIENDLY": "Friendly"
|
||||
}
|
||||
},
|
||||
"BUTTONS": {
|
||||
"GENERATE": "Generate",
|
||||
"GENERATING": "Generating...",
|
||||
"CANCEL": "Cancel"
|
||||
},
|
||||
"GENERATE_ERROR": "There was an error processing the content, please verify your OpenAI API key and try again"
|
||||
},
|
||||
"DELETE": {
|
||||
"BUTTON_TEXT": "Delete",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Integration deleted successfully"
|
||||
}
|
||||
},
|
||||
"CONNECT": {
|
||||
"BUTTON_TEXT": "Connect"
|
||||
},
|
||||
"DASHBOARD_APPS": {
|
||||
"TITLE": "Dashboard Apps",
|
||||
"HEADER_BTN_TXT": "Add a new dashboard app",
|
||||
"SIDEBAR_TXT": "<p><b>Dashboard Apps</b></p><p>Dashboard Apps allow organizations to embed an application inside the Chatwoot dashboard to provide the context for customer support agents. This feature allows you to create an application independently and embed that inside the dashboard to provide user information, their orders, or their previous payment history.</p><p>When you embed your application using the dashboard in Chatwoot, your application will get the context of the conversation and contact as a window event. Implement a listener for the message event on your page to receive the context.</p><p>To add a new dashboard app, click on the button 'Add a new dashboard app'.</p>",
|
||||
"DESCRIPTION": "Dashboard Apps allow organizations to embed an application inside the dashboard to provide the context for customer support agents. This feature allows you to create an application independently and embed that to provide user information, their orders, or their previous payment history.",
|
||||
"LIST": {
|
||||
"404": "There are no dashboard apps configured on this account yet",
|
||||
"LOADING": "Fetching dashboard apps...",
|
||||
"TABLE_HEADER": [
|
||||
"Name",
|
||||
"Endpoint"
|
||||
],
|
||||
"EDIT_TOOLTIP": "Edit app",
|
||||
"DELETE_TOOLTIP": "Delete app"
|
||||
},
|
||||
"FORM": {
|
||||
"TITLE_LABEL": "Name",
|
||||
"TITLE_PLACEHOLDER": "Enter a name for your dashboard app",
|
||||
"TITLE_ERROR": "A name for the dashboard app is required",
|
||||
"URL_LABEL": "Endpoint",
|
||||
"URL_PLACEHOLDER": "Enter the endpoint URL where your app is hosted",
|
||||
"URL_ERROR": "A valid URL is required"
|
||||
},
|
||||
"CREATE": {
|
||||
"HEADER": "Add a new dashboard app",
|
||||
"FORM_SUBMIT": "Submit",
|
||||
"FORM_CANCEL": "Cancel",
|
||||
"API_SUCCESS": "Dashboard app configured successfully",
|
||||
"API_ERROR": "We couldn't create an app. Please try again later"
|
||||
},
|
||||
"UPDATE": {
|
||||
"HEADER": "Edit dashboard app",
|
||||
"FORM_SUBMIT": "Update",
|
||||
"FORM_CANCEL": "Cancel",
|
||||
"API_SUCCESS": "Dashboard app updated successfully",
|
||||
"API_ERROR": "We couldn't update the app. Please try again later"
|
||||
},
|
||||
"DELETE": {
|
||||
"CONFIRM_YES": "Yes, delete it",
|
||||
"CONFIRM_NO": "No, keep it",
|
||||
"TITLE": "Confirm deletion",
|
||||
"MESSAGE": "Are you sure to delete the app - %{appName}?",
|
||||
"API_SUCCESS": "Dashboard app deleted successfully",
|
||||
"API_ERROR": "We couldn't delete the app. Please try again later"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
{
|
||||
"LABEL_MGMT": {
|
||||
"HEADER": "Labels",
|
||||
"HEADER_BTN_TXT": "Add label",
|
||||
"LOADING": "Fetching labels",
|
||||
"SEARCH_404": "There are no items matching this query",
|
||||
"SIDEBAR_TXT": "<p><b>Labels</b> <p>Labels help you to categorize conversations and prioritize them. You can assign label to a conversation from the sidepanel. <br /><br />Labels are tied to the account and can be used to create custom workflows in your organization. You can assign custom color to a label, it makes it easier to identify the label. You will be able to display the label on the sidebar to filter the conversations easily.</p>",
|
||||
"LIST": {
|
||||
"404": "There are no labels available in this account.",
|
||||
"TITLE": "Manage labels",
|
||||
"DESC": "Labels let you group the conversations together.",
|
||||
"TABLE_HEADER": [
|
||||
"Name",
|
||||
"Description",
|
||||
"Color"
|
||||
]
|
||||
},
|
||||
"FORM": {
|
||||
"NAME": {
|
||||
"LABEL": "Label Name",
|
||||
"PLACEHOLDER": "Label name",
|
||||
"REQUIRED_ERROR": "Label name is required",
|
||||
"MINIMUM_LENGTH_ERROR": "Minimum length 2 is required",
|
||||
"VALID_ERROR": "Only Alphabets, Numbers, Hyphen and Underscore are allowed"
|
||||
},
|
||||
"DESCRIPTION": {
|
||||
"LABEL": "Description",
|
||||
"PLACEHOLDER": "Label Description"
|
||||
},
|
||||
"COLOR": {
|
||||
"LABEL": "Color"
|
||||
},
|
||||
"SHOW_ON_SIDEBAR": {
|
||||
"LABEL": "Show label on sidebar"
|
||||
},
|
||||
"EDIT": "Edit",
|
||||
"CREATE": "Create",
|
||||
"DELETE": "Delete",
|
||||
"CANCEL": "Cancel"
|
||||
},
|
||||
"SUGGESTIONS": {
|
||||
"TOOLTIP": {
|
||||
"SINGLE_SUGGESTION": "Add label to conversation",
|
||||
"MULTIPLE_SUGGESTION": "Select this label",
|
||||
"DESELECT": "Deselect label",
|
||||
"DISMISS": "Dismiss suggestion"
|
||||
},
|
||||
"POWERED_BY": "Chatwoot AI",
|
||||
"DISMISS": "Dismiss",
|
||||
"ADD_SELECTED_LABELS": "Add selected labels",
|
||||
"ADD_SELECTED_LABEL": "Add selected label",
|
||||
"ADD_ALL_LABELS": "Add all labels"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Add label",
|
||||
"DESC": "Labels let you group the conversations together.",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Label added successfully",
|
||||
"ERROR_MESSAGE": "There was an error, please try again"
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Edit label",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Label updated successfully",
|
||||
"ERROR_MESSAGE": "There was an error, please try again"
|
||||
}
|
||||
},
|
||||
"DELETE": {
|
||||
"BUTTON_TEXT": "Delete",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Label deleted successfully",
|
||||
"ERROR_MESSAGE": "There was an error, please try again"
|
||||
},
|
||||
"CONFIRM": {
|
||||
"TITLE": "Confirm Deletion",
|
||||
"MESSAGE": "Are you sure to delete ",
|
||||
"YES": "Yes, Delete ",
|
||||
"NO": "No, Keep "
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"LOGIN": {
|
||||
"TITLE": "Login to Chatwoot",
|
||||
"EMAIL": {
|
||||
"LABEL": "Email",
|
||||
"PLACEHOLDER": "example@companyname.com",
|
||||
"ERROR": "Please enter a valid email address"
|
||||
},
|
||||
"PASSWORD": {
|
||||
"LABEL": "Password",
|
||||
"PLACEHOLDER": "Password"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Login successful",
|
||||
"ERROR_MESSAGE": "Could not connect to Woot server. Please try again.",
|
||||
"UNAUTH": "Username or password is incorrect. Please try again."
|
||||
},
|
||||
"OAUTH": {
|
||||
"GOOGLE_LOGIN": "Login with Google",
|
||||
"BUSINESS_ACCOUNTS_ONLY": "Please use your company email address to login",
|
||||
"NO_ACCOUNT_FOUND": "We couldn't find an account for your email address."
|
||||
},
|
||||
"FORGOT_PASSWORD": "Forgot your password?",
|
||||
"CREATE_NEW_ACCOUNT": "Create a new account",
|
||||
"SUBMIT": "Login"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
{
|
||||
"MACROS": {
|
||||
"HEADER": "Macros",
|
||||
"HEADER_BTN_TXT": "Add a new macro",
|
||||
"HEADER_BTN_TXT_SAVE": "Save macro",
|
||||
"LOADING": "Fetching macros",
|
||||
"SIDEBAR_TXT": "<p><b>Macros</b><p>A macro is a set of saved actions that help customer service agents easily complete tasks. The agents can define a set of actions like tagging a conversation with a label, sending an email transcript, updating a custom attribute, etc., and they can run these actions in a single click. When the agents run the macro, the actions would be performed sequentially in the order they are defined. Macros improve productivity and increase consistency in actions. </p><p>A macro can be helpful in 2 ways. </p><p><b>As an agent assist:</b> If an agent performs a set of actions multiple times, they can save it as a macro and execute all the actions together using a single click.</p><p><b>As an option to onboard a team member:</b> Every agent has to perform many different checks/actions during each conversation. Onboarding a new support team member will be easy if pre-defined macros are available on the account. Instead of describing each step in detail, the manager/team lead can point to the macros used in different scenarios.</p>",
|
||||
"ERROR": "Something went wrong. Please try again",
|
||||
"ORDER_INFO": "Macros will run in the order you add your actions. You can rearrange them by dragging them by the handle beside each node.",
|
||||
"ADD": {
|
||||
"FORM": {
|
||||
"NAME": {
|
||||
"LABEL": "Macro name",
|
||||
"PLACEHOLDER": "Enter a name for your macro",
|
||||
"ERROR": "Name is required for creating a macro"
|
||||
},
|
||||
"ACTIONS": {
|
||||
"LABEL": "Actions"
|
||||
}
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Macro added successfully",
|
||||
"ERROR_MESSAGE": "Unable to create macro, Please try again later"
|
||||
}
|
||||
},
|
||||
"LIST": {
|
||||
"TABLE_HEADER": [
|
||||
"Name",
|
||||
"Created by",
|
||||
"Last updated by",
|
||||
"Visibility"
|
||||
],
|
||||
"404": "No macros found"
|
||||
},
|
||||
"DELETE": {
|
||||
"TOOLTIP": "Delete macro",
|
||||
"CONFIRM": {
|
||||
"MESSAGE": "Are you sure to delete ",
|
||||
"YES": "Yes, Delete",
|
||||
"NO": "No"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Macro deleted successfully",
|
||||
"ERROR_MESSAGE": "There was an error deleting the macro. Please try again later"
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TOOLTIP": "Edit macro",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Macro updated successfully",
|
||||
"ERROR_MESSAGE": "Could not update Macro, Please try again later"
|
||||
}
|
||||
},
|
||||
"EDITOR": {
|
||||
"START_FLOW": "Start Flow",
|
||||
"END_FLOW": "End Flow",
|
||||
"LOADING": "Fetching macro",
|
||||
"ADD_BTN_TOOLTIP": "Add new action",
|
||||
"DELETE_BTN_TOOLTIP": "Delete Action",
|
||||
"VISIBILITY": {
|
||||
"LABEL": "Macro Visibility",
|
||||
"GLOBAL": {
|
||||
"LABEL": "Public",
|
||||
"DESCRIPTION": "This macro is available publicly for all agents in this account."
|
||||
},
|
||||
"PERSONAL": {
|
||||
"LABEL": "Private",
|
||||
"DESCRIPTION": "This macro will be private to you and not be available to others."
|
||||
}
|
||||
}
|
||||
},
|
||||
"EXECUTE": {
|
||||
"BUTTON_TOOLTIP": "Execute",
|
||||
"PREVIEW": "Preview Macro",
|
||||
"EXECUTED_SUCCESSFULLY": "Macro executed successfully"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,479 @@
|
||||
{
|
||||
"REPORT": {
|
||||
"HEADER": "Conversations",
|
||||
"LOADING_CHART": "Loading chart data...",
|
||||
"NO_ENOUGH_DATA": "We've not received enough data points to generate report, Please try again later.",
|
||||
"DOWNLOAD_AGENT_REPORTS": "Download agent reports",
|
||||
"DATA_FETCHING_FAILED": "Failed to fetch data, please try again later.",
|
||||
"SUMMARY_FETCHING_FAILED": "Failed to fetch summary, please try again later.",
|
||||
"METRICS": {
|
||||
"CONVERSATIONS": {
|
||||
"NAME": "Conversations",
|
||||
"DESC": "( Total )"
|
||||
},
|
||||
"INCOMING_MESSAGES": {
|
||||
"NAME": "Messages received",
|
||||
"DESC": "( Total )"
|
||||
},
|
||||
"OUTGOING_MESSAGES": {
|
||||
"NAME": "Messages sent",
|
||||
"DESC": "( Total )"
|
||||
},
|
||||
"FIRST_RESPONSE_TIME": {
|
||||
"NAME": "First Response Time",
|
||||
"DESC": "( Avg )",
|
||||
"INFO_TEXT": "Total number of conversations used for computation:",
|
||||
"TOOLTIP_TEXT": "First Response Time is %{metricValue} (based on %{conversationCount} conversations)"
|
||||
},
|
||||
"RESOLUTION_TIME": {
|
||||
"NAME": "Resolution Time",
|
||||
"DESC": "( Avg )",
|
||||
"INFO_TEXT": "Total number of conversations used for computation:",
|
||||
"TOOLTIP_TEXT": "Resolution Time is %{metricValue} (based on %{conversationCount} conversations)"
|
||||
},
|
||||
"RESOLUTION_COUNT": {
|
||||
"NAME": "Resolution Count",
|
||||
"DESC": "( Total )"
|
||||
},
|
||||
"REPLY_TIME": {
|
||||
"NAME": "Customer waiting time",
|
||||
"TOOLTIP_TEXT": "Waiting time is %{metricValue} (based on %{conversationCount} conversations)"
|
||||
}
|
||||
},
|
||||
"DATE_RANGE_OPTIONS": {
|
||||
"LAST_7_DAYS": "Last 7 days",
|
||||
"LAST_30_DAYS": "Last 30 days",
|
||||
"LAST_3_MONTHS": "Last 3 months",
|
||||
"LAST_6_MONTHS": "Last 6 months",
|
||||
"LAST_YEAR": "Last year",
|
||||
"CUSTOM_DATE_RANGE": "Custom date range"
|
||||
},
|
||||
"DATE_RANGE": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "Last 7 days"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Last 30 days"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Last 3 months"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Last 6 months"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Last year"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "Custom date range"
|
||||
}
|
||||
],
|
||||
"CUSTOM_DATE_RANGE": {
|
||||
"CONFIRM": "Apply",
|
||||
"PLACEHOLDER": "Select date range"
|
||||
},
|
||||
"GROUP_BY_FILTER_DROPDOWN_LABEL": "Group By",
|
||||
"DURATION_FILTER_LABEL": "Duration",
|
||||
"GROUPING_OPTIONS": {
|
||||
"DAY": "Day",
|
||||
"WEEK": "Week",
|
||||
"MONTH": "Month",
|
||||
"YEAR": "Year"
|
||||
},
|
||||
"GROUP_BY_DAY_OPTIONS": [
|
||||
{
|
||||
"id": 1,
|
||||
"groupBy": "Day"
|
||||
}
|
||||
],
|
||||
"GROUP_BY_WEEK_OPTIONS": [
|
||||
{
|
||||
"id": 1,
|
||||
"groupBy": "Day"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"groupBy": "Week"
|
||||
}
|
||||
],
|
||||
"GROUP_BY_MONTH_OPTIONS": [
|
||||
{
|
||||
"id": 1,
|
||||
"groupBy": "Day"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"groupBy": "Week"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"groupBy": "Month"
|
||||
}
|
||||
],
|
||||
"GROUP_BY_YEAR_OPTIONS": [
|
||||
{
|
||||
"id": 2,
|
||||
"groupBy": "Week"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"groupBy": "Month"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"groupBy": "Year"
|
||||
}
|
||||
],
|
||||
"BUSINESS_HOURS": "Business Hours"
|
||||
},
|
||||
"AGENT_REPORTS": {
|
||||
"HEADER": "Agents Overview",
|
||||
"LOADING_CHART": "Loading chart data...",
|
||||
"NO_ENOUGH_DATA": "We've not received enough data points to generate report, Please try again later.",
|
||||
"DOWNLOAD_AGENT_REPORTS": "Download agent reports",
|
||||
"FILTER_DROPDOWN_LABEL": "Select Agent",
|
||||
"METRICS": {
|
||||
"CONVERSATIONS": {
|
||||
"NAME": "Conversations",
|
||||
"DESC": "( Total )"
|
||||
},
|
||||
"INCOMING_MESSAGES": {
|
||||
"NAME": "Incoming Messages",
|
||||
"DESC": "( Total )"
|
||||
},
|
||||
"OUTGOING_MESSAGES": {
|
||||
"NAME": "Outgoing Messages",
|
||||
"DESC": "( Total )"
|
||||
},
|
||||
"FIRST_RESPONSE_TIME": {
|
||||
"NAME": "First Response Time",
|
||||
"DESC": "( Avg )",
|
||||
"INFO_TEXT": "Total number of conversations used for computation:",
|
||||
"TOOLTIP_TEXT": "First Response Time is %{metricValue} (based on %{conversationCount} conversations)"
|
||||
},
|
||||
"RESOLUTION_TIME": {
|
||||
"NAME": "Resolution Time",
|
||||
"DESC": "( Avg )",
|
||||
"INFO_TEXT": "Total number of conversations used for computation:",
|
||||
"TOOLTIP_TEXT": "Resolution Time is %{metricValue} (based on %{conversationCount} conversations)"
|
||||
},
|
||||
"RESOLUTION_COUNT": {
|
||||
"NAME": "Resolution Count",
|
||||
"DESC": "( Total )"
|
||||
}
|
||||
},
|
||||
"DATE_RANGE": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "Last 7 days"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Last 30 days"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Last 3 months"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Last 6 months"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Last year"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "Custom date range"
|
||||
}
|
||||
],
|
||||
"CUSTOM_DATE_RANGE": {
|
||||
"CONFIRM": "Apply",
|
||||
"PLACEHOLDER": "Select date range"
|
||||
}
|
||||
},
|
||||
"LABEL_REPORTS": {
|
||||
"HEADER": "Labels Overview",
|
||||
"LOADING_CHART": "Loading chart data...",
|
||||
"NO_ENOUGH_DATA": "We've not received enough data points to generate report, Please try again later.",
|
||||
"DOWNLOAD_LABEL_REPORTS": "Download label reports",
|
||||
"FILTER_DROPDOWN_LABEL": "Select Label",
|
||||
"METRICS": {
|
||||
"CONVERSATIONS": {
|
||||
"NAME": "Conversations",
|
||||
"DESC": "( Total )"
|
||||
},
|
||||
"INCOMING_MESSAGES": {
|
||||
"NAME": "Incoming Messages",
|
||||
"DESC": "( Total )"
|
||||
},
|
||||
"OUTGOING_MESSAGES": {
|
||||
"NAME": "Outgoing Messages",
|
||||
"DESC": "( Total )"
|
||||
},
|
||||
"FIRST_RESPONSE_TIME": {
|
||||
"NAME": "First Response Time",
|
||||
"DESC": "( Avg )",
|
||||
"INFO_TEXT": "Total number of conversations used for computation:",
|
||||
"TOOLTIP_TEXT": "First Response Time is %{metricValue} (based on %{conversationCount} conversations)"
|
||||
},
|
||||
"RESOLUTION_TIME": {
|
||||
"NAME": "Resolution Time",
|
||||
"DESC": "( Avg )",
|
||||
"INFO_TEXT": "Total number of conversations used for computation:",
|
||||
"TOOLTIP_TEXT": "Resolution Time is %{metricValue} (based on %{conversationCount} conversations)"
|
||||
},
|
||||
"RESOLUTION_COUNT": {
|
||||
"NAME": "Resolution Count",
|
||||
"DESC": "( Total )"
|
||||
}
|
||||
},
|
||||
"DATE_RANGE": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "Last 7 days"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Last 30 days"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Last 3 months"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Last 6 months"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Last year"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "Custom date range"
|
||||
}
|
||||
],
|
||||
"CUSTOM_DATE_RANGE": {
|
||||
"CONFIRM": "Apply",
|
||||
"PLACEHOLDER": "Select date range"
|
||||
}
|
||||
},
|
||||
"INBOX_REPORTS": {
|
||||
"HEADER": "Inbox Overview",
|
||||
"LOADING_CHART": "Loading chart data...",
|
||||
"NO_ENOUGH_DATA": "We've not received enough data points to generate report, Please try again later.",
|
||||
"DOWNLOAD_INBOX_REPORTS": "Download inbox reports",
|
||||
"FILTER_DROPDOWN_LABEL": "Select Inbox",
|
||||
"METRICS": {
|
||||
"CONVERSATIONS": {
|
||||
"NAME": "Conversations",
|
||||
"DESC": "( Total )"
|
||||
},
|
||||
"INCOMING_MESSAGES": {
|
||||
"NAME": "Incoming Messages",
|
||||
"DESC": "( Total )"
|
||||
},
|
||||
"OUTGOING_MESSAGES": {
|
||||
"NAME": "Outgoing Messages",
|
||||
"DESC": "( Total )"
|
||||
},
|
||||
"FIRST_RESPONSE_TIME": {
|
||||
"NAME": "First Response Time",
|
||||
"DESC": "( Avg )",
|
||||
"INFO_TEXT": "Total number of conversations used for computation:",
|
||||
"TOOLTIP_TEXT": "First Response Time is %{metricValue} (based on %{conversationCount} conversations)"
|
||||
},
|
||||
"RESOLUTION_TIME": {
|
||||
"NAME": "Resolution Time",
|
||||
"DESC": "( Avg )",
|
||||
"INFO_TEXT": "Total number of conversations used for computation:",
|
||||
"TOOLTIP_TEXT": "Resolution Time is %{metricValue} (based on %{conversationCount} conversations)"
|
||||
},
|
||||
"RESOLUTION_COUNT": {
|
||||
"NAME": "Resolution Count",
|
||||
"DESC": "( Total )"
|
||||
}
|
||||
},
|
||||
"DATE_RANGE": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "Last 7 days"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Last 30 days"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Last 3 months"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Last 6 months"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Last year"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "Custom date range"
|
||||
}
|
||||
],
|
||||
"CUSTOM_DATE_RANGE": {
|
||||
"CONFIRM": "Apply",
|
||||
"PLACEHOLDER": "Select date range"
|
||||
}
|
||||
},
|
||||
"TEAM_REPORTS": {
|
||||
"HEADER": "Team Overview",
|
||||
"LOADING_CHART": "Loading chart data...",
|
||||
"NO_ENOUGH_DATA": "We've not received enough data points to generate report, Please try again later.",
|
||||
"DOWNLOAD_TEAM_REPORTS": "Download team reports",
|
||||
"FILTER_DROPDOWN_LABEL": "Select Team",
|
||||
"METRICS": {
|
||||
"CONVERSATIONS": {
|
||||
"NAME": "Conversations",
|
||||
"DESC": "( Total )"
|
||||
},
|
||||
"INCOMING_MESSAGES": {
|
||||
"NAME": "Incoming Messages",
|
||||
"DESC": "( Total )"
|
||||
},
|
||||
"OUTGOING_MESSAGES": {
|
||||
"NAME": "Outgoing Messages",
|
||||
"DESC": "( Total )"
|
||||
},
|
||||
"FIRST_RESPONSE_TIME": {
|
||||
"NAME": "First Response Time",
|
||||
"DESC": "( Avg )",
|
||||
"INFO_TEXT": "Total number of conversations used for computation:",
|
||||
"TOOLTIP_TEXT": "First Response Time is %{metricValue} (based on %{conversationCount} conversations)"
|
||||
},
|
||||
"RESOLUTION_TIME": {
|
||||
"NAME": "Resolution Time",
|
||||
"DESC": "( Avg )",
|
||||
"INFO_TEXT": "Total number of conversations used for computation:",
|
||||
"TOOLTIP_TEXT": "Resolution Time is %{metricValue} (based on %{conversationCount} conversations)"
|
||||
},
|
||||
"RESOLUTION_COUNT": {
|
||||
"NAME": "Resolution Count",
|
||||
"DESC": "( Total )"
|
||||
}
|
||||
},
|
||||
"DATE_RANGE": [
|
||||
{
|
||||
"id": 0,
|
||||
"name": "Last 7 days"
|
||||
},
|
||||
{
|
||||
"id": 1,
|
||||
"name": "Last 30 days"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Last 3 months"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Last 6 months"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Last year"
|
||||
},
|
||||
{
|
||||
"id": 5,
|
||||
"name": "Custom date range"
|
||||
}
|
||||
],
|
||||
"CUSTOM_DATE_RANGE": {
|
||||
"CONFIRM": "Apply",
|
||||
"PLACEHOLDER": "Select date range"
|
||||
}
|
||||
},
|
||||
"CSAT_REPORTS": {
|
||||
"HEADER": "CSAT Reports",
|
||||
"NO_RECORDS": "There are no CSAT survey responses available.",
|
||||
"DOWNLOAD": "Download CSAT Reports",
|
||||
"DOWNLOAD_FAILED": "Failed to download CSAT Reports",
|
||||
"FILTERS": {
|
||||
"AGENTS": {
|
||||
"PLACEHOLDER": "Choose Agents"
|
||||
}
|
||||
},
|
||||
"TABLE": {
|
||||
"HEADER": {
|
||||
"CONTACT_NAME": "Contact",
|
||||
"AGENT_NAME": "Assigned agent",
|
||||
"RATING": "Rating",
|
||||
"FEEDBACK_TEXT": "Feedback comment"
|
||||
}
|
||||
},
|
||||
"METRIC": {
|
||||
"TOTAL_RESPONSES": {
|
||||
"LABEL": "Total responses",
|
||||
"TOOLTIP": "Total number of responses collected"
|
||||
},
|
||||
"SATISFACTION_SCORE": {
|
||||
"LABEL": "Satisfaction score",
|
||||
"TOOLTIP": "Total number of positive responses / Total number of responses * 100"
|
||||
},
|
||||
"RESPONSE_RATE": {
|
||||
"LABEL": "Response rate",
|
||||
"TOOLTIP": "Total number of responses / Total number of CSAT survey messages sent * 100"
|
||||
}
|
||||
}
|
||||
},
|
||||
"OVERVIEW_REPORTS": {
|
||||
"HEADER": "Overview",
|
||||
"LIVE": "Live",
|
||||
"ACCOUNT_CONVERSATIONS": {
|
||||
"HEADER": "Open Conversations",
|
||||
"LOADING_MESSAGE": "Loading conversation metrics...",
|
||||
"OPEN": "Open",
|
||||
"UNATTENDED": "Unattended",
|
||||
"UNASSIGNED": "Unassigned"
|
||||
},
|
||||
"CONVERSATION_HEATMAP": {
|
||||
"HEADER": "Conversation Traffic",
|
||||
"NO_CONVERSATIONS": "No conversations",
|
||||
"CONVERSATION": "%{count} conversation",
|
||||
"CONVERSATIONS": "%{count} conversations"
|
||||
},
|
||||
"AGENT_CONVERSATIONS": {
|
||||
"HEADER": "Conversations by agents",
|
||||
"LOADING_MESSAGE": "Loading agent metrics...",
|
||||
"NO_AGENTS": "There are no conversations by agents",
|
||||
"TABLE_HEADER": {
|
||||
"AGENT": "Agent",
|
||||
"OPEN": "OPEN",
|
||||
"UNATTENDED": "Unattended",
|
||||
"STATUS": "Status"
|
||||
}
|
||||
},
|
||||
"AGENT_STATUS": {
|
||||
"HEADER": "Agent status",
|
||||
"ONLINE": "Online",
|
||||
"BUSY": "Busy",
|
||||
"OFFLINE": "Offline"
|
||||
}
|
||||
},
|
||||
"DAYS_OF_WEEK": {
|
||||
"SUNDAY": "Sunday",
|
||||
"MONDAY": "Monday",
|
||||
"TUESDAY": "Tuesday",
|
||||
"WEDNESDAY": "Wednesday",
|
||||
"THURSDAY": "Thursday",
|
||||
"FRIDAY": "Friday",
|
||||
"SATURDAY": "Saturday"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"RESET_PASSWORD": {
|
||||
"TITLE": "Reset password",
|
||||
"DESCRIPTION": "Enter the email address you use to log in to Chatwoot to get the password reset instructions.",
|
||||
"GO_BACK_TO_LOGIN": "If you want to go back to the login page,",
|
||||
"EMAIL": {
|
||||
"LABEL": "Email",
|
||||
"PLACEHOLDER": "Please enter your email.",
|
||||
"ERROR": "Please enter a valid email."
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Password reset link has been sent to your email.",
|
||||
"ERROR_MESSAGE": "Could not connect to Woot server. Please try again."
|
||||
},
|
||||
"SUBMIT": "Submit"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"SEARCH": {
|
||||
"TABS": {
|
||||
"ALL": "All",
|
||||
"CONTACTS": "Contacts",
|
||||
"CONVERSATIONS": "Conversations",
|
||||
"MESSAGES": "Messages"
|
||||
},
|
||||
"SECTION": {
|
||||
"CONTACTS": "Contacts",
|
||||
"CONVERSATIONS": "Conversations",
|
||||
"MESSAGES": "Messages"
|
||||
},
|
||||
"EMPTY_STATE": "No %{item} found for query '%{query}'",
|
||||
"EMPTY_STATE_FULL": "No results found for query '%{query}'",
|
||||
"PLACEHOLDER_KEYBINDING": "/ to focus",
|
||||
"INPUT_PLACEHOLDER": "Type 3 or more characters to search",
|
||||
"EMPTY_STATE_DEFAULT": "Search by conversation id, email, phone number, messages for better search results. ",
|
||||
"BOT_LABEL": "Bot",
|
||||
"READ_MORE": "Read more",
|
||||
"WROTE": "wrote:",
|
||||
"FROM": "from",
|
||||
"EMAIL": "email"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"SET_NEW_PASSWORD": {
|
||||
"TITLE": "Set new password",
|
||||
"PASSWORD": {
|
||||
"LABEL": "Password",
|
||||
"PLACEHOLDER": "Password",
|
||||
"ERROR": "Password is too short."
|
||||
},
|
||||
"CONFIRM_PASSWORD": {
|
||||
"LABEL": "Confirm password",
|
||||
"PLACEHOLDER": "Confirm Password",
|
||||
"ERROR": "Passwords do not match."
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Successfully changed the password.",
|
||||
"ERROR_MESSAGE": "Could not connect to Woot server. Please try again."
|
||||
},
|
||||
"CAPTCHA": {
|
||||
"ERROR": "Verification expired. Please solve captcha again."
|
||||
},
|
||||
"SUBMIT": "Submit"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,320 @@
|
||||
{
|
||||
"PROFILE_SETTINGS": {
|
||||
"LINK": "Profile Settings",
|
||||
"TITLE": "Profile Settings",
|
||||
"BTN_TEXT": "Update Profile",
|
||||
"DELETE_AVATAR": "Delete Avatar",
|
||||
"AVATAR_DELETE_SUCCESS": "Avatar has been deleted successfully",
|
||||
"AVATAR_DELETE_FAILED": "There is an error while deleting avatar, please try again",
|
||||
"UPDATE_SUCCESS": "Your profile has been updated successfully",
|
||||
"PASSWORD_UPDATE_SUCCESS": "Your password has been changed successfully",
|
||||
"AFTER_EMAIL_CHANGED": "Your profile has been updated successfully, please login again as your login credentials are changed",
|
||||
"FORM": {
|
||||
"AVATAR": "Profile Image",
|
||||
"ERROR": "Please fix form errors",
|
||||
"REMOVE_IMAGE": "Remove",
|
||||
"UPLOAD_IMAGE": "Upload image",
|
||||
"UPDATE_IMAGE": "Update image",
|
||||
"PROFILE_SECTION": {
|
||||
"TITLE": "Profile",
|
||||
"NOTE": "Your email address is your identity and is used to log in."
|
||||
},
|
||||
"SEND_MESSAGE": {
|
||||
"TITLE": "Hotkey to send messages",
|
||||
"NOTE": "You can select a hotkey (either Enter or Cmd/Ctrl+Enter) based on your preference of writing.",
|
||||
"UPDATE_SUCCESS": "Your settings have been updated successfully",
|
||||
"CARD": {
|
||||
"ENTER_KEY": {
|
||||
"HEADING": "Enter (↵)",
|
||||
"CONTENT": "Send messages by pressing Enter key instead of clicking the send button."
|
||||
},
|
||||
"CMD_ENTER_KEY": {
|
||||
"HEADING": "Cmd/Ctrl + Enter (⌘ + ↵)",
|
||||
"CONTENT": "Send messages by pressing Cmd/Ctrl + enter key instead of clicking the send button."
|
||||
}
|
||||
}
|
||||
},
|
||||
"MESSAGE_SIGNATURE_SECTION": {
|
||||
"TITLE": "Personal message signature",
|
||||
"NOTE": "Create a personal message signature that would be added to all the messages you send from your email inbox. Use the rich content editor to create a highly personalised signature.",
|
||||
"BTN_TEXT": "Save message signature",
|
||||
"API_ERROR": "Couldn't save signature! Try again",
|
||||
"API_SUCCESS": "Signature saved successfully",
|
||||
"IMAGE_UPLOAD_ERROR": "Couldn't upload image! Try again",
|
||||
"IMAGE_UPLOAD_SUCCESS": "Image added successfully. Please click on save to save the signature",
|
||||
"IMAGE_UPLOAD_SIZE_ERROR": "Image size should be less than {size}MB"
|
||||
},
|
||||
"MESSAGE_SIGNATURE": {
|
||||
"LABEL": "Message Signature",
|
||||
"ERROR": "Message Signature cannot be empty",
|
||||
"PLACEHOLDER": "Insert your personal message signature here."
|
||||
},
|
||||
"PASSWORD_SECTION": {
|
||||
"TITLE": "Password",
|
||||
"NOTE": "Updating your password would reset your logins in multiple devices.",
|
||||
"BTN_TEXT": "Change password"
|
||||
},
|
||||
"ACCESS_TOKEN": {
|
||||
"TITLE": "Access Token",
|
||||
"NOTE": "This token can be used if you are building an API based integration"
|
||||
},
|
||||
"AUDIO_NOTIFICATIONS_SECTION": {
|
||||
"TITLE": "Audio Notifications",
|
||||
"NOTE": "Enable audio notifications in dashboard for new messages and conversations.",
|
||||
"ALERT_TYPE": {
|
||||
"TITLE": "Alert events:",
|
||||
"NONE": "None",
|
||||
"ASSIGNED": "Assigned Conversations",
|
||||
"ALL_CONVERSATIONS": "All Conversations"
|
||||
},
|
||||
"DEFAULT_TONE": {
|
||||
"TITLE": "Alert tone:"
|
||||
},
|
||||
"CONDITIONS": {
|
||||
"TITLE": "Alert conditions:",
|
||||
"CONDITION_ONE": "Send audio alerts only if the browser window is not active",
|
||||
"CONDITION_TWO": "Send alerts every 30s until all the assigned conversations are read"
|
||||
}
|
||||
},
|
||||
"EMAIL_NOTIFICATIONS_SECTION": {
|
||||
"TITLE": "Email Notifications",
|
||||
"NOTE": "Update your email notification preferences here",
|
||||
"CONVERSATION_ASSIGNMENT": "Send email notifications when a conversation is assigned to me",
|
||||
"CONVERSATION_CREATION": "Send email notifications when a new conversation is created",
|
||||
"CONVERSATION_MENTION": "Send email notifications when you are mentioned in a conversation",
|
||||
"ASSIGNED_CONVERSATION_NEW_MESSAGE": "Send email notifications when a new message is created in an assigned conversation",
|
||||
"PARTICIPATING_CONVERSATION_NEW_MESSAGE": "Send email notifications when a new message is created in a participating conversation"
|
||||
},
|
||||
"API": {
|
||||
"UPDATE_SUCCESS": "Your notification preferences are updated successfully",
|
||||
"UPDATE_ERROR": "There is an error while updating the preferences, please try again"
|
||||
},
|
||||
"PUSH_NOTIFICATIONS_SECTION": {
|
||||
"TITLE": "Push Notifications",
|
||||
"NOTE": "Update your push notification preferences here",
|
||||
"CONVERSATION_ASSIGNMENT": "Send push notifications when a conversation is assigned to me",
|
||||
"CONVERSATION_CREATION": "Send push notifications when a new conversation is created",
|
||||
"CONVERSATION_MENTION": "Send push notifications when you are mentioned in a conversation",
|
||||
"ASSIGNED_CONVERSATION_NEW_MESSAGE": "Send push notifications when a new message is created in an assigned conversation",
|
||||
"PARTICIPATING_CONVERSATION_NEW_MESSAGE": "Send push notifications when a new message is created in a participating conversation",
|
||||
"HAS_ENABLED_PUSH": "You have enabled push for this browser.",
|
||||
"REQUEST_PUSH": "Enable push notifications"
|
||||
},
|
||||
"PROFILE_IMAGE": {
|
||||
"LABEL": "Profile Image"
|
||||
},
|
||||
"NAME": {
|
||||
"LABEL": "Your full name",
|
||||
"ERROR": "Please enter a valid full name",
|
||||
"PLACEHOLDER": "Please enter your full name"
|
||||
},
|
||||
"DISPLAY_NAME": {
|
||||
"LABEL": "Display name",
|
||||
"ERROR": "Please enter a valid display name",
|
||||
"PLACEHOLDER": "Please enter a display name, this would be displayed in conversations"
|
||||
},
|
||||
"AVAILABILITY": {
|
||||
"LABEL": "Availability",
|
||||
"STATUSES_LIST": [
|
||||
"Online",
|
||||
"Busy",
|
||||
"Offline"
|
||||
],
|
||||
"SET_AVAILABILITY_SUCCESS": "Availability has been set successfully",
|
||||
"SET_AVAILABILITY_ERROR": "Couldn't set availability, please try again"
|
||||
},
|
||||
"EMAIL": {
|
||||
"LABEL": "Your email address",
|
||||
"ERROR": "Please enter a valid email address",
|
||||
"PLACEHOLDER": "Please enter your email address, this would be displayed in conversations"
|
||||
},
|
||||
"CURRENT_PASSWORD": {
|
||||
"LABEL": "Current password",
|
||||
"ERROR": "Please enter the current password",
|
||||
"PLACEHOLDER": "Please enter the current password"
|
||||
},
|
||||
"PASSWORD": {
|
||||
"LABEL": "New password",
|
||||
"ERROR": "Please enter a password of length 6 or more",
|
||||
"PLACEHOLDER": "Please enter a new password"
|
||||
},
|
||||
"PASSWORD_CONFIRMATION": {
|
||||
"LABEL": "Confirm new password",
|
||||
"ERROR": "Confirm password should match the password",
|
||||
"PLACEHOLDER": "Please re-enter your new password"
|
||||
}
|
||||
}
|
||||
},
|
||||
"SIDEBAR_ITEMS": {
|
||||
"CHANGE_AVAILABILITY_STATUS": "Change",
|
||||
"CHANGE_ACCOUNTS": "Switch Account",
|
||||
"CONTACT_SUPPORT": "Contact Support",
|
||||
"SELECTOR_SUBTITLE": "Select an account from the following list",
|
||||
"PROFILE_SETTINGS": "Profile Settings",
|
||||
"KEYBOARD_SHORTCUTS": "Keyboard Shortcuts",
|
||||
"APPEARANCE": "Change Appearance",
|
||||
"SUPER_ADMIN_CONSOLE": "Super Admin Console",
|
||||
"LOGOUT": "Logout"
|
||||
},
|
||||
"APP_GLOBAL": {
|
||||
"TRIAL_MESSAGE": "days trial remaining.",
|
||||
"TRAIL_BUTTON": "Buy Now",
|
||||
"DELETED_USER": "Deleted User",
|
||||
"ACCOUNT_SUSPENDED": {
|
||||
"TITLE": "Account Suspended",
|
||||
"MESSAGE": "Your account is suspended. Please reach out to the support team for more information."
|
||||
}
|
||||
},
|
||||
"COMPONENTS": {
|
||||
"CODE": {
|
||||
"BUTTON_TEXT": "Copy",
|
||||
"CODEPEN": "Open in CodePen",
|
||||
"COPY_SUCCESSFUL": "Copied to clipboard"
|
||||
},
|
||||
"SHOW_MORE_BLOCK": {
|
||||
"SHOW_MORE": "Show More",
|
||||
"SHOW_LESS": "Show Less"
|
||||
},
|
||||
"FILE_BUBBLE": {
|
||||
"DOWNLOAD": "Download",
|
||||
"UPLOADING": "Uploading...",
|
||||
"INSTAGRAM_STORY_UNAVAILABLE": "This story is no longer available."
|
||||
},
|
||||
"LOCATION_BUBBLE": {
|
||||
"SEE_ON_MAP": "See on map"
|
||||
},
|
||||
"FORM_BUBBLE": {
|
||||
"SUBMIT": "Submit"
|
||||
}
|
||||
},
|
||||
"CONFIRM_EMAIL": "Verifying...",
|
||||
"SETTINGS": {
|
||||
"INBOXES": {
|
||||
"NEW_INBOX": "Add Inbox"
|
||||
}
|
||||
},
|
||||
"SIDEBAR": {
|
||||
"CURRENTLY_VIEWING_ACCOUNT": "Currently viewing:",
|
||||
"SWITCH": "Switch",
|
||||
"CONVERSATIONS": "Conversations",
|
||||
"ALL_CONVERSATIONS": "All Conversations",
|
||||
"MENTIONED_CONVERSATIONS": "Mentions",
|
||||
"PARTICIPATING_CONVERSATIONS": "Participating",
|
||||
"UNATTENDED_CONVERSATIONS": "Unattended",
|
||||
"REPORTS": "Reports",
|
||||
"SETTINGS": "Settings",
|
||||
"CONTACTS": "Contacts",
|
||||
"HOME": "Home",
|
||||
"AGENTS": "Agents",
|
||||
"AGENT_BOTS": "Bots",
|
||||
"AUDIT_LOGS": "Audit Logs",
|
||||
"INBOXES": "Inboxes",
|
||||
"NOTIFICATIONS": "Notifications",
|
||||
"CANNED_RESPONSES": "Canned Responses",
|
||||
"INTEGRATIONS": "Integrations",
|
||||
"PROFILE_SETTINGS": "Profile Settings",
|
||||
"ACCOUNT_SETTINGS": "Account Settings",
|
||||
"APPLICATIONS": "Applications",
|
||||
"LABELS": "Labels",
|
||||
"CUSTOM_ATTRIBUTES": "Custom Attributes",
|
||||
"AUTOMATION": "Automation",
|
||||
"MACROS": "Macros",
|
||||
"TEAMS": "Teams",
|
||||
"BILLING": "Billing",
|
||||
"CUSTOM_VIEWS_FOLDER": "Folders",
|
||||
"CUSTOM_VIEWS_SEGMENTS": "Segments",
|
||||
"ALL_CONTACTS": "All Contacts",
|
||||
"TAGGED_WITH": "Tagged with",
|
||||
"NEW_LABEL": "New label",
|
||||
"NEW_TEAM": "New team",
|
||||
"NEW_INBOX": "New inbox",
|
||||
"REPORTS_CONVERSATION": "Conversations",
|
||||
"CSAT": "CSAT",
|
||||
"CAMPAIGNS": "Campaigns",
|
||||
"ONGOING": "Ongoing",
|
||||
"ONE_OFF": "One off",
|
||||
"REPORTS_AGENT": "Agents",
|
||||
"REPORTS_LABEL": "Labels",
|
||||
"REPORTS_INBOX": "Inbox",
|
||||
"REPORTS_TEAM": "Team",
|
||||
"SET_AVAILABILITY_TITLE": "Set yourself as",
|
||||
"BETA": "Beta",
|
||||
"REPORTS_OVERVIEW": "Overview",
|
||||
"FACEBOOK_REAUTHORIZE": "Your Facebook connection has expired, please reconnect your Facebook page to continue services",
|
||||
"HELP_CENTER": {
|
||||
"TITLE": "Help Center (Beta)",
|
||||
"ALL_ARTICLES": "All Articles",
|
||||
"MY_ARTICLES": "My Articles",
|
||||
"DRAFT": "Draft",
|
||||
"ARCHIVED": "Archived",
|
||||
"CATEGORY": "Category",
|
||||
"SETTINGS": "Settings",
|
||||
"CATEGORY_EMPTY_MESSAGE": "No categories found"
|
||||
},
|
||||
"SET_AUTO_OFFLINE": {
|
||||
"TEXT": "Mark offline automatically",
|
||||
"INFO_TEXT": "Let the system automatically mark you offline when you aren't using the app or dashboard."
|
||||
},
|
||||
"DOCS": "Read docs"
|
||||
},
|
||||
"BILLING_SETTINGS": {
|
||||
"TITLE": "Billing",
|
||||
"CURRENT_PLAN": {
|
||||
"TITLE": "Current Plan",
|
||||
"PLAN_NOTE": "You are currently subscribed to the **%{plan}** plan with **%{quantity}** licenses"
|
||||
},
|
||||
"MANAGE_SUBSCRIPTION": {
|
||||
"TITLE": "Manage your subscription",
|
||||
"DESCRIPTION": "View your previous invoices, edit your billing details, or cancel your subscription.",
|
||||
"BUTTON_TXT": "Go to the billing portal"
|
||||
},
|
||||
"CHAT_WITH_US": {
|
||||
"TITLE": "Need help?",
|
||||
"DESCRIPTION": "Do you face any issues in billing? We are here to help.",
|
||||
"BUTTON_TXT": "Chat with us"
|
||||
},
|
||||
"NO_BILLING_USER": "Your billing account is being configured. Please refresh the page and try again."
|
||||
},
|
||||
"CREATE_ACCOUNT": {
|
||||
"NO_ACCOUNT_WARNING": "Uh oh! We could not find any Chatwoot accounts. Please create a new account to continue.",
|
||||
"NEW_ACCOUNT": "New Account",
|
||||
"SELECTOR_SUBTITLE": "Create a new account",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Account created successfully",
|
||||
"EXIST_MESSAGE": "Account already exists",
|
||||
"ERROR_MESSAGE": "Could not connect to Woot Server, Please try again later"
|
||||
},
|
||||
"FORM": {
|
||||
"NAME": {
|
||||
"LABEL": "Company Name",
|
||||
"PLACEHOLDER": "Wayne Enterprises"
|
||||
},
|
||||
"SUBMIT": "Submit"
|
||||
}
|
||||
},
|
||||
"KEYBOARD_SHORTCUTS": {
|
||||
"TOGGLE_MODAL": "View all shortcuts",
|
||||
"TITLE": {
|
||||
"OPEN_CONVERSATION": "Open conversation",
|
||||
"RESOLVE_AND_NEXT": "Resolve and move to next",
|
||||
"NAVIGATE_DROPDOWN": "Navigate dropdown items",
|
||||
"RESOLVE_CONVERSATION": "Resolve Conversation",
|
||||
"GO_TO_CONVERSATION_DASHBOARD": "Go to Conversation Dashboard",
|
||||
"ADD_ATTACHMENT": "Add Attachment",
|
||||
"GO_TO_CONTACTS_DASHBOARD": "Go to Contacts Dashboard",
|
||||
"TOGGLE_SIDEBAR": "Toggle Sidebar",
|
||||
"GO_TO_REPORTS_SIDEBAR": "Go to Reports sidebar",
|
||||
"MOVE_TO_NEXT_TAB": "Move to next tab in conversation list",
|
||||
"GO_TO_SETTINGS": "Go to Settings",
|
||||
"SWITCH_CONVERSATION_STATUS": "Switch to the next conversation status",
|
||||
"SWITCH_TO_PRIVATE_NOTE": "Switch to Private Note",
|
||||
"SWITCH_TO_REPLY": "Switch to Reply",
|
||||
"TOGGLE_SNOOZE_DROPDOWN": "Toggle snooze dropdown"
|
||||
},
|
||||
"KEYS": {
|
||||
"WINDOWS_KEY_AND_COMMAND_KEY": "Win / ⌘",
|
||||
"ALT_OR_OPTION_KEY": "Alt / ⌥",
|
||||
"FORWARD_SLASH_KEY": "/"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
{
|
||||
"REGISTER": {
|
||||
"TRY_WOOT": "Create an account",
|
||||
"TITLE": "Register",
|
||||
"TESTIMONIAL_HEADER": "All it takes is one step to move forward",
|
||||
"TESTIMONIAL_CONTENT": "You're one step away from engaging your customers, retaining them and finding new ones.",
|
||||
"TERMS_ACCEPT": "By creating an account, you agree to our <a href=\"https://www.chatwoot.com/terms\">T & C</a> and <a href=\"https://www.chatwoot.com/privacy-policy\">Privacy policy</a>",
|
||||
"OAUTH": {
|
||||
"GOOGLE_SIGNUP": "Sign up with Google"
|
||||
},
|
||||
"COMPANY_NAME": {
|
||||
"LABEL": "Company name",
|
||||
"PLACEHOLDER": "Enter your company name. E.g., Wayne Enterprises",
|
||||
"ERROR": "Company name is too short."
|
||||
},
|
||||
"FULL_NAME": {
|
||||
"LABEL": "Full name",
|
||||
"PLACEHOLDER": "Enter your full name. E.g., Bruce Wayne",
|
||||
"ERROR": "Full name is too short."
|
||||
},
|
||||
"EMAIL": {
|
||||
"LABEL": "Work email",
|
||||
"PLACEHOLDER": "Enter your work email address. E.g., bruce@wayne.enterprises",
|
||||
"ERROR": "Please enter a valid work email address."
|
||||
},
|
||||
"PASSWORD": {
|
||||
"LABEL": "Password",
|
||||
"PLACEHOLDER": "Password",
|
||||
"ERROR": "Password is too short.",
|
||||
"IS_INVALID_PASSWORD": "Password should contain atleast 1 uppercase letter, 1 lowercase letter, 1 number and 1 special character."
|
||||
},
|
||||
"CONFIRM_PASSWORD": {
|
||||
"LABEL": "Confirm password",
|
||||
"PLACEHOLDER": "Confirm password",
|
||||
"ERROR": "Password doesnot match."
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Registration Successfull",
|
||||
"ERROR_MESSAGE": "Could not connect to Woot server. Please try again."
|
||||
},
|
||||
"SUBMIT": "Create account",
|
||||
"HAVE_AN_ACCOUNT": "Already have an account?"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
{
|
||||
"TEAMS_SETTINGS": {
|
||||
"NEW_TEAM": "Create new team",
|
||||
"HEADER": "Teams",
|
||||
"SIDEBAR_TXT": "<p><b>Teams</b></p> <p>Teams let you organize your agents into groups based on their responsibilities. <br /> An agent can be part of multiple teams. You can assign conversations to a team when you are working collaboratively. </p>",
|
||||
"LIST": {
|
||||
"404": "There are no teams created on this account.",
|
||||
"EDIT_TEAM": "Edit team"
|
||||
},
|
||||
"CREATE_FLOW": {
|
||||
"CREATE": {
|
||||
"TITLE": "Create a new team",
|
||||
"DESC": "Add a title and description to your new team."
|
||||
},
|
||||
"AGENTS": {
|
||||
"BUTTON_TEXT": "Add agents to team",
|
||||
"TITLE": "Add agents to team - %{teamName}",
|
||||
"DESC": "Add Agents to your newly created team. This lets you collaborate as a team on conversations, get notified on new events in the same conversation."
|
||||
},
|
||||
"WIZARD": [
|
||||
{
|
||||
"title": "Create",
|
||||
"route": "settings_teams_new",
|
||||
"body": "Create a new team of agents."
|
||||
},
|
||||
{
|
||||
"title": "Add Agents",
|
||||
"route": "settings_teams_add_agents",
|
||||
"body": "Add agents to the team."
|
||||
},
|
||||
{
|
||||
"title": "Finish",
|
||||
"route": "settings_teams_finish",
|
||||
"body": "You are all set to go!"
|
||||
}
|
||||
]
|
||||
},
|
||||
"EDIT_FLOW": {
|
||||
"CREATE": {
|
||||
"TITLE": "Edit your team details",
|
||||
"DESC": "Edit title and description to your team.",
|
||||
"BUTTON_TEXT": "Update team"
|
||||
},
|
||||
"AGENTS": {
|
||||
"BUTTON_TEXT": "Update agents in team",
|
||||
"TITLE": "Add agents to team - %{teamName}",
|
||||
"DESC": "Add Agents to your newly created team. All the added agents will be notified when a conversation is assigned to this team."
|
||||
},
|
||||
"WIZARD": [
|
||||
{
|
||||
"title": "Team details",
|
||||
"route": "settings_teams_edit",
|
||||
"body": "Change name, description and other details."
|
||||
},
|
||||
{
|
||||
"title": "Edit Agents",
|
||||
"route": "settings_teams_edit_members",
|
||||
"body": "Edit agents in your team."
|
||||
},
|
||||
{
|
||||
"title": "Finish",
|
||||
"route": "settings_teams_edit_finish",
|
||||
"body": "You are all set to go!"
|
||||
}
|
||||
]
|
||||
},
|
||||
"TEAM_FORM": {
|
||||
"ERROR_MESSAGE": "Couldn't save the team details. Try again."
|
||||
},
|
||||
"AGENTS": {
|
||||
"AGENT": "AGENT",
|
||||
"EMAIL": "EMAIL",
|
||||
"BUTTON_TEXT": "Add agents",
|
||||
"ADD_AGENTS": "Adding Agents to your Team...",
|
||||
"SELECT": "select",
|
||||
"SELECT_ALL": "select all agents",
|
||||
"SELECTED_COUNT": "%{selected} out of %{total} agents selected."
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Add agents to team - %{teamName}",
|
||||
"DESC": "Add Agents to your newly created team. This lets you collaborate as a team on conversations, get notified on new events in the same conversation.",
|
||||
"SELECT": "select",
|
||||
"SELECT_ALL": "select all agents",
|
||||
"SELECTED_COUNT": "%{selected} out of %{total} agents selected.",
|
||||
"BUTTON_TEXT": "Add agents",
|
||||
"AGENT_VALIDATION_ERROR": "Select at least one agent."
|
||||
},
|
||||
"FINISH": {
|
||||
"TITLE": "Your team is ready!",
|
||||
"MESSAGE": "You can now collaborate as a team on conversations. Happy supporting ",
|
||||
"BUTTON_TEXT": "Finish"
|
||||
},
|
||||
"DELETE": {
|
||||
"BUTTON_TEXT": "Delete",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Team deleted successfully.",
|
||||
"ERROR_MESSAGE": "Couldn't delete the team. Try again."
|
||||
},
|
||||
"CONFIRM": {
|
||||
"TITLE": "Are you sure want to delete - %{teamName}",
|
||||
"PLACE_HOLDER": "Please type {teamName} to confirm",
|
||||
"MESSAGE": "Deleting the team will remove the team assignment from the conversations assigned to this team.",
|
||||
"YES": "Delete ",
|
||||
"NO": "Cancel"
|
||||
}
|
||||
},
|
||||
"SETTINGS": "Settings",
|
||||
"FORM": {
|
||||
"UPDATE": "Update team",
|
||||
"CREATE": "Create team",
|
||||
"NAME": {
|
||||
"LABEL": "Team name",
|
||||
"PLACEHOLDER": "Example: Sales, Customer Support"
|
||||
},
|
||||
"DESCRIPTION": {
|
||||
"LABEL": "Team Description",
|
||||
"PLACEHOLDER": "Short description about this team."
|
||||
},
|
||||
"AUTO_ASSIGN": {
|
||||
"LABEL": "Allow auto assign for this team."
|
||||
},
|
||||
"SUBMIT_CREATE": "Create team"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"WEBHOOKS_SETTINGS": {
|
||||
"HEADER": "Webhook Settings"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"WHATSAPP_TEMPLATES": {
|
||||
"MODAL": {
|
||||
"TITLE": "Whatsapp Templates",
|
||||
"SUBTITLE": "Select the whatsapp template you want to send",
|
||||
"TEMPLATE_SELECTED_SUBTITLE": "Process %{templateName}"
|
||||
},
|
||||
"PICKER": {
|
||||
"SEARCH_PLACEHOLDER": "Search Templates",
|
||||
"NO_TEMPLATES_FOUND": "No templates found for",
|
||||
"LABELS": {
|
||||
"LANGUAGE": "Language",
|
||||
"TEMPLATE_BODY": "Template Body",
|
||||
"CATEGORY": "Category"
|
||||
}
|
||||
},
|
||||
"PARSER": {
|
||||
"VARIABLES_LABEL": "Variables",
|
||||
"VARIABLE_PLACEHOLDER": "Enter %{variable} value",
|
||||
"GO_BACK_LABEL": "Go Back",
|
||||
"SEND_MESSAGE_LABEL": "Send Message",
|
||||
"FORM_ERROR_MESSAGE": "Please fill all variables before sending"
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user