Merge branch 'release/2.13.0'
This commit is contained in:
commit
e054c2a32f
13
.env.example
13
.env.example
@ -35,7 +35,7 @@ REDIS_SENTINELS=
|
|||||||
REDIS_SENTINEL_MASTER_NAME=
|
REDIS_SENTINEL_MASTER_NAME=
|
||||||
|
|
||||||
# By default Chatwoot will pass REDIS_PASSWORD as the password value for sentinels
|
# By default Chatwoot will pass REDIS_PASSWORD as the password value for sentinels
|
||||||
# Use the following environment variable to customize passwords for sentinels.
|
# Use the following environment variable to customize passwords for sentinels.
|
||||||
# Use empty string if sentinels are configured with out passwords
|
# Use empty string if sentinels are configured with out passwords
|
||||||
# REDIS_SENTINEL_PASSWORD=
|
# REDIS_SENTINEL_PASSWORD=
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ REDIS_SENTINEL_MASTER_NAME=
|
|||||||
# REDIS_OPENSSL_VERIFY_MODE=none
|
# REDIS_OPENSSL_VERIFY_MODE=none
|
||||||
|
|
||||||
# Postgres Database config variables
|
# Postgres Database config variables
|
||||||
# You can leave POSTGRES_DATABASE blank. The default name of
|
# You can leave POSTGRES_DATABASE blank. The default name of
|
||||||
# the database in the production environment is chatwoot_production
|
# the database in the production environment is chatwoot_production
|
||||||
# POSTGRES_DATABASE=
|
# POSTGRES_DATABASE=
|
||||||
POSTGRES_HOST=postgres
|
POSTGRES_HOST=postgres
|
||||||
@ -213,3 +213,12 @@ STRIPE_WEBHOOK_SECRET=
|
|||||||
# Set to true if you want to upload files to cloud storage using the signed url
|
# Set to true if you want to upload files to cloud storage using the signed url
|
||||||
# Make sure to follow https://edgeguides.rubyonrails.org/active_storage_overview.html#cross-origin-resource-sharing-cors-configuration on the cloud storage after setting this to true.
|
# Make sure to follow https://edgeguides.rubyonrails.org/active_storage_overview.html#cross-origin-resource-sharing-cors-configuration on the cloud storage after setting this to true.
|
||||||
DIRECT_UPLOADS_ENABLED=
|
DIRECT_UPLOADS_ENABLED=
|
||||||
|
|
||||||
|
#MS OAUTH creds
|
||||||
|
AZURE_APP_ID=
|
||||||
|
AZURE_APP_SECRET=
|
||||||
|
|
||||||
|
## Advanced configurations
|
||||||
|
## Change these values to fine tune performance
|
||||||
|
# control the concurrency setting of sidekiq
|
||||||
|
# SIDEKIQ_CONCURRENCY=10
|
||||||
|
|||||||
6
Gemfile
6
Gemfile
@ -37,6 +37,8 @@ gem 'json_schemer'
|
|||||||
gem 'rack-attack'
|
gem 'rack-attack'
|
||||||
# a utility tool for streaming, flexible and safe downloading of remote files
|
# a utility tool for streaming, flexible and safe downloading of remote files
|
||||||
gem 'down', '~> 5.0'
|
gem 'down', '~> 5.0'
|
||||||
|
# authentication type to fetch and send mail over oauth2.0
|
||||||
|
gem 'gmail_xoauth'
|
||||||
|
|
||||||
##-- for active storage --##
|
##-- for active storage --##
|
||||||
gem 'aws-sdk-s3', require: false
|
gem 'aws-sdk-s3', require: false
|
||||||
@ -160,6 +162,8 @@ group :test do
|
|||||||
gem 'database_cleaner'
|
gem 'database_cleaner'
|
||||||
# mock http calls
|
# mock http calls
|
||||||
gem 'webmock'
|
gem 'webmock'
|
||||||
|
# test profiling
|
||||||
|
gem 'test-prof'
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
@ -186,3 +190,5 @@ group :development, :test do
|
|||||||
gem 'spring'
|
gem 'spring'
|
||||||
gem 'spring-watcher-listen'
|
gem 'spring-watcher-listen'
|
||||||
end
|
end
|
||||||
|
# worked with microsoft refresh token
|
||||||
|
gem 'omniauth-oauth2'
|
||||||
|
|||||||
30
Gemfile.lock
30
Gemfile.lock
@ -249,6 +249,8 @@ GEM
|
|||||||
gli (2.21.0)
|
gli (2.21.0)
|
||||||
globalid (1.0.0)
|
globalid (1.0.0)
|
||||||
activesupport (>= 5.0)
|
activesupport (>= 5.0)
|
||||||
|
gmail_xoauth (0.4.2)
|
||||||
|
oauth (>= 0.3.6)
|
||||||
google-apis-core (0.7.0)
|
google-apis-core (0.7.0)
|
||||||
addressable (~> 2.5, >= 2.5.1)
|
addressable (~> 2.5, >= 2.5.1)
|
||||||
googleauth (>= 0.16.2, < 2.a)
|
googleauth (>= 0.16.2, < 2.a)
|
||||||
@ -333,8 +335,8 @@ GEM
|
|||||||
http-cookie (1.0.5)
|
http-cookie (1.0.5)
|
||||||
domain_name (~> 0.5)
|
domain_name (~> 0.5)
|
||||||
http-form_data (2.3.0)
|
http-form_data (2.3.0)
|
||||||
httparty (0.20.0)
|
httparty (0.21.0)
|
||||||
mime-types (~> 3.0)
|
mini_mime (>= 1.0.0)
|
||||||
multi_xml (>= 0.5.2)
|
multi_xml (>= 0.5.2)
|
||||||
httpclient (2.8.3)
|
httpclient (2.8.3)
|
||||||
i18n (1.11.0)
|
i18n (1.11.0)
|
||||||
@ -437,6 +439,20 @@ GEM
|
|||||||
nokogiri (1.13.10-x86_64-linux)
|
nokogiri (1.13.10-x86_64-linux)
|
||||||
racc (~> 1.4)
|
racc (~> 1.4)
|
||||||
oauth (0.5.10)
|
oauth (0.5.10)
|
||||||
|
oauth2 (2.0.9)
|
||||||
|
faraday (>= 0.17.3, < 3.0)
|
||||||
|
jwt (>= 1.0, < 3.0)
|
||||||
|
multi_xml (~> 0.5)
|
||||||
|
rack (>= 1.2, < 4)
|
||||||
|
snaky_hash (~> 2.0)
|
||||||
|
version_gem (~> 1.1)
|
||||||
|
omniauth (2.1.0)
|
||||||
|
hashie (>= 3.4.6)
|
||||||
|
rack (>= 2.2.3)
|
||||||
|
rack-protection
|
||||||
|
omniauth-oauth2 (1.8.0)
|
||||||
|
oauth2 (>= 1.4, < 3)
|
||||||
|
omniauth (~> 2.0)
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
os (1.1.4)
|
os (1.1.4)
|
||||||
parallel (1.22.1)
|
parallel (1.22.1)
|
||||||
@ -465,6 +481,8 @@ GEM
|
|||||||
rack (>= 1.0, < 3)
|
rack (>= 1.0, < 3)
|
||||||
rack-cors (1.1.1)
|
rack-cors (1.1.1)
|
||||||
rack (>= 2.0.0)
|
rack (>= 2.0.0)
|
||||||
|
rack-protection (3.0.5)
|
||||||
|
rack
|
||||||
rack-proxy (0.7.2)
|
rack-proxy (0.7.2)
|
||||||
rack
|
rack
|
||||||
rack-test (2.0.2)
|
rack-test (2.0.2)
|
||||||
@ -620,6 +638,9 @@ GEM
|
|||||||
gli
|
gli
|
||||||
hashie
|
hashie
|
||||||
websocket-driver
|
websocket-driver
|
||||||
|
snaky_hash (2.0.1)
|
||||||
|
hashie
|
||||||
|
version_gem (~> 1.1, >= 1.1.1)
|
||||||
spring (2.1.1)
|
spring (2.1.1)
|
||||||
spring-watcher-listen (2.0.1)
|
spring-watcher-listen (2.0.1)
|
||||||
listen (>= 2.7, < 4.0)
|
listen (>= 2.7, < 4.0)
|
||||||
@ -635,6 +656,7 @@ GEM
|
|||||||
statsd-ruby (1.5.0)
|
statsd-ruby (1.5.0)
|
||||||
stripe (6.5.0)
|
stripe (6.5.0)
|
||||||
telephone_number (1.4.16)
|
telephone_number (1.4.16)
|
||||||
|
test-prof (1.0.11)
|
||||||
thor (1.2.1)
|
thor (1.2.1)
|
||||||
tilt (2.0.10)
|
tilt (2.0.10)
|
||||||
time_diff (0.3.0)
|
time_diff (0.3.0)
|
||||||
@ -663,6 +685,7 @@ GEM
|
|||||||
valid_email2 (4.0.3)
|
valid_email2 (4.0.3)
|
||||||
activemodel (>= 3.2)
|
activemodel (>= 3.2)
|
||||||
mail (~> 2.5)
|
mail (~> 2.5)
|
||||||
|
version_gem (1.1.1)
|
||||||
warden (1.2.9)
|
warden (1.2.9)
|
||||||
rack (>= 2.0.9)
|
rack (>= 2.0.9)
|
||||||
web-console (4.2.0)
|
web-console (4.2.0)
|
||||||
@ -735,6 +758,7 @@ DEPENDENCIES
|
|||||||
flag_shih_tzu
|
flag_shih_tzu
|
||||||
foreman
|
foreman
|
||||||
geocoder
|
geocoder
|
||||||
|
gmail_xoauth
|
||||||
google-cloud-dialogflow
|
google-cloud-dialogflow
|
||||||
google-cloud-storage
|
google-cloud-storage
|
||||||
groupdate
|
groupdate
|
||||||
@ -756,6 +780,7 @@ DEPENDENCIES
|
|||||||
maxminddb
|
maxminddb
|
||||||
mock_redis
|
mock_redis
|
||||||
newrelic_rpm
|
newrelic_rpm
|
||||||
|
omniauth-oauth2
|
||||||
pg
|
pg
|
||||||
pg_search
|
pg_search
|
||||||
procore-sift
|
procore-sift
|
||||||
@ -791,6 +816,7 @@ DEPENDENCIES
|
|||||||
squasher
|
squasher
|
||||||
stripe
|
stripe
|
||||||
telephone_number
|
telephone_number
|
||||||
|
test-prof
|
||||||
time_diff
|
time_diff
|
||||||
twilio-ruby (~> 5.66)
|
twilio-ruby (~> 5.66)
|
||||||
twitty
|
twitty
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
backend: bin/rails s -p 3000
|
backend: bin/rails s -p 3000
|
||||||
frontend: bin/webpack-dev-server
|
frontend: bin/webpack-dev-server
|
||||||
worker: bundle exec sidekiq -C config/sidekiq.yml
|
# https://github.com/mperham/sidekiq/issues/3090#issuecomment-389748695
|
||||||
|
worker: dotenv bundle exec sidekiq -C config/sidekiq.yml
|
||||||
|
|||||||
@ -1,3 +1,3 @@
|
|||||||
backend: RAILS_ENV=test bin/rails s -p 5050
|
backend: RAILS_ENV=test bin/rails s -p 5050
|
||||||
frontend: bin/webpack-dev-server
|
frontend: bin/webpack-dev-server
|
||||||
worker: RAILS_ENV=test bundle exec sidekiq -C config/sidekiq.yml
|
worker: dotenv RAILS_ENV=test bundle exec sidekiq -C config/sidekiq.yml
|
||||||
|
|||||||
@ -119,4 +119,4 @@ Thanks goes to all these [wonderful people](https://www.chatwoot.com/docs/contri
|
|||||||
<a href="https://github.com/chatwoot/chatwoot/graphs/contributors"><img src="https://opencollective.com/chatwoot/contributors.svg?width=890&button=false" /></a>
|
<a href="https://github.com/chatwoot/chatwoot/graphs/contributors"><img src="https://opencollective.com/chatwoot/contributors.svg?width=890&button=false" /></a>
|
||||||
|
|
||||||
|
|
||||||
*Chatwoot* © 2017-2022, Chatwoot Inc - Released under the MIT License.
|
*Chatwoot* © 2017-2023, Chatwoot Inc - Released under the MIT License.
|
||||||
|
|||||||
@ -0,0 +1,48 @@
|
|||||||
|
class Api::V1::Accounts::Integrations::DyteController < Api::V1::Accounts::BaseController
|
||||||
|
before_action :fetch_conversation, only: [:create_a_meeting]
|
||||||
|
before_action :fetch_message, only: [:add_participant_to_meeting]
|
||||||
|
before_action :authorize_request
|
||||||
|
|
||||||
|
def create_a_meeting
|
||||||
|
render_response(dyte_processor_service.create_a_meeting(Current.user))
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_participant_to_meeting
|
||||||
|
if @message.content_type != 'integrations'
|
||||||
|
return render json: {
|
||||||
|
error: I18n.t('errors.dyte.invalid_message_type')
|
||||||
|
}, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
|
||||||
|
render_response(
|
||||||
|
dyte_processor_service.add_participant_to_meeting(@message.content_attributes['data']['meeting_id'], Current.user)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def authorize_request
|
||||||
|
authorize @conversation.inbox, :show?
|
||||||
|
end
|
||||||
|
|
||||||
|
def render_response(response)
|
||||||
|
render json: response, status: response[:error].blank? ? :ok : :unprocessable_entity
|
||||||
|
end
|
||||||
|
|
||||||
|
def dyte_processor_service
|
||||||
|
Integrations::Dyte::ProcessorService.new(account: Current.account, conversation: @conversation)
|
||||||
|
end
|
||||||
|
|
||||||
|
def permitted_params
|
||||||
|
params.permit(:conversation_id, :message_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_conversation
|
||||||
|
@conversation = Current.account.conversations.find_by!(display_id: permitted_params[:conversation_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_message
|
||||||
|
@message = Current.account.messages.find(permitted_params[:message_id])
|
||||||
|
@conversation = @message.conversation
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -0,0 +1,27 @@
|
|||||||
|
class Api::V1::Accounts::Microsoft::AuthorizationsController < Api::V1::Accounts::BaseController
|
||||||
|
include MicrosoftConcern
|
||||||
|
before_action :check_authorization
|
||||||
|
|
||||||
|
def create
|
||||||
|
email = params[:authorization][:email]
|
||||||
|
redirect_url = microsoft_client.auth_code.authorize_url(
|
||||||
|
{
|
||||||
|
redirect_uri: "#{base_url}/microsoft/callback",
|
||||||
|
scope: 'offline_access https://outlook.office.com/IMAP.AccessAsUser.All https://outlook.office.com/SMTP.Send openid',
|
||||||
|
prompt: 'consent'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
if redirect_url
|
||||||
|
::Redis::Alfred.setex(email, Current.account.id, 5.minutes)
|
||||||
|
render json: { success: true, url: redirect_url }
|
||||||
|
else
|
||||||
|
render json: { success: false }, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def check_authorization
|
||||||
|
raise Pundit::NotAuthorizedError unless Current.account_user.administrator?
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -0,0 +1,36 @@
|
|||||||
|
class Api::V1::Widget::Integrations::DyteController < Api::V1::Widget::BaseController
|
||||||
|
before_action :set_message
|
||||||
|
|
||||||
|
def add_participant_to_meeting
|
||||||
|
if @message.content_type != 'integrations'
|
||||||
|
return render json: {
|
||||||
|
error: I18n.t('errors.dyte.invalid_message_type')
|
||||||
|
}, status: :unprocessable_entity
|
||||||
|
end
|
||||||
|
|
||||||
|
response = dyte_processor_service.add_participant_to_meeting(
|
||||||
|
@message.content_attributes['data']['meeting_id'],
|
||||||
|
@conversation.contact
|
||||||
|
)
|
||||||
|
render_response(response)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def render_response(response)
|
||||||
|
render json: response, status: response[:error].blank? ? :ok : :unprocessable_entity
|
||||||
|
end
|
||||||
|
|
||||||
|
def dyte_processor_service
|
||||||
|
Integrations::Dyte::ProcessorService.new(account: @web_widget.inbox.account, conversation: @conversation)
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_message
|
||||||
|
@message = @web_widget.inbox.messages.find(permitted_params[:message_id])
|
||||||
|
@conversation = @message.conversation
|
||||||
|
end
|
||||||
|
|
||||||
|
def permitted_params
|
||||||
|
params.permit(:website_token, :message_id)
|
||||||
|
end
|
||||||
|
end
|
||||||
22
app/controllers/concerns/microsoft_concern.rb
Normal file
22
app/controllers/concerns/microsoft_concern.rb
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
module MicrosoftConcern
|
||||||
|
extend ActiveSupport::Concern
|
||||||
|
|
||||||
|
def microsoft_client
|
||||||
|
::OAuth2::Client.new(ENV.fetch('AZURE_APP_ID', nil), ENV.fetch('AZURE_APP_SECRET', nil),
|
||||||
|
{
|
||||||
|
site: 'https://login.microsoftonline.com',
|
||||||
|
authorize_url: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',
|
||||||
|
token_url: 'https://login.microsoftonline.com/common/oauth2/v2.0/token'
|
||||||
|
})
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def parsed_body
|
||||||
|
@parsed_body ||= Rack::Utils.parse_nested_query(@response.raw_response.body)
|
||||||
|
end
|
||||||
|
|
||||||
|
def base_url
|
||||||
|
ENV.fetch('FRONTEND_URL', 'http://localhost:3000')
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -55,7 +55,8 @@ class DashboardController < ActionController::Base
|
|||||||
ENABLE_ACCOUNT_SIGNUP: GlobalConfigService.load('ENABLE_ACCOUNT_SIGNUP', 'false'),
|
ENABLE_ACCOUNT_SIGNUP: GlobalConfigService.load('ENABLE_ACCOUNT_SIGNUP', 'false'),
|
||||||
FB_APP_ID: GlobalConfigService.load('FB_APP_ID', ''),
|
FB_APP_ID: GlobalConfigService.load('FB_APP_ID', ''),
|
||||||
FACEBOOK_API_VERSION: 'v14.0',
|
FACEBOOK_API_VERSION: 'v14.0',
|
||||||
IS_ENTERPRISE: ChatwootApp.enterprise?
|
IS_ENTERPRISE: ChatwootApp.enterprise?,
|
||||||
|
AZURE_APP_ID: ENV.fetch('AZURE_APP_ID', '')
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
72
app/controllers/microsoft/callbacks_controller.rb
Normal file
72
app/controllers/microsoft/callbacks_controller.rb
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
class Microsoft::CallbacksController < ApplicationController
|
||||||
|
include MicrosoftConcern
|
||||||
|
|
||||||
|
def show
|
||||||
|
@response = microsoft_client.auth_code.get_token(
|
||||||
|
oauth_code,
|
||||||
|
redirect_uri: "#{base_url}/microsoft/callback"
|
||||||
|
)
|
||||||
|
|
||||||
|
inbox = find_or_create_inbox
|
||||||
|
::Redis::Alfred.delete(users_data['email'])
|
||||||
|
redirect_to app_microsoft_inbox_agents_url(account_id: account.id, inbox_id: inbox.id)
|
||||||
|
rescue StandardError => e
|
||||||
|
ChatwootExceptionTracker.new(e).capture_exception
|
||||||
|
redirect_to '/'
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def oauth_code
|
||||||
|
params[:code]
|
||||||
|
end
|
||||||
|
|
||||||
|
def users_data
|
||||||
|
decoded_token = JWT.decode parsed_body[:id_token], nil, false
|
||||||
|
decoded_token[0]
|
||||||
|
end
|
||||||
|
|
||||||
|
def parsed_body
|
||||||
|
@parsed_body ||= @response.response.parsed
|
||||||
|
end
|
||||||
|
|
||||||
|
def account_id
|
||||||
|
::Redis::Alfred.get(users_data['email'])
|
||||||
|
end
|
||||||
|
|
||||||
|
def account
|
||||||
|
@account ||= Account.find(account_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_or_create_inbox
|
||||||
|
channel_email = Channel::Email.find_by(email: users_data['email'], account: account)
|
||||||
|
channel_email ||= create_microsoft_channel_with_inbox
|
||||||
|
update_microsoft_channel(channel_email)
|
||||||
|
channel_email.inbox
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_microsoft_channel_with_inbox
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
channel_email = Channel::Email.create!(email: users_data['email'], account: account)
|
||||||
|
account.inboxes.create!(
|
||||||
|
account: account,
|
||||||
|
channel: channel_email,
|
||||||
|
name: users_data['name']
|
||||||
|
)
|
||||||
|
channel_email
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_microsoft_channel(channel_email)
|
||||||
|
channel_email.update!({
|
||||||
|
imap_login: users_data['email'], imap_address: 'outlook.office365.com',
|
||||||
|
imap_port: '993', imap_enabled: true,
|
||||||
|
provider: 'microsoft',
|
||||||
|
provider_config: {
|
||||||
|
access_token: parsed_body['access_token'],
|
||||||
|
refresh_token: parsed_body['refresh_token'],
|
||||||
|
expires_on: (Time.current.utc + 1.hour).to_s
|
||||||
|
}
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -11,8 +11,8 @@ class SwaggerController < ApplicationController
|
|||||||
|
|
||||||
def derived_path
|
def derived_path
|
||||||
params[:path] ||= 'index.html'
|
params[:path] ||= 'index.html'
|
||||||
path = params[:path]
|
path = Rack::Utils.clean_path_info(params[:path])
|
||||||
path << ".#{params[:format]}" unless path.ends_with?(params[:format].to_s)
|
path << ".#{Rack::Utils.clean_path_info(params[:format])}" unless path.ends_with?(params[:format].to_s)
|
||||||
path
|
path
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
17
app/drops/contact_drop.rb
Normal file
17
app/drops/contact_drop.rb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
class ContactDrop < BaseDrop
|
||||||
|
def email
|
||||||
|
@obj.try(:email)
|
||||||
|
end
|
||||||
|
|
||||||
|
def phone_number
|
||||||
|
@obj.try(:phone_number)
|
||||||
|
end
|
||||||
|
|
||||||
|
def first_name
|
||||||
|
@obj.try(:name).try(:split).try(:first)
|
||||||
|
end
|
||||||
|
|
||||||
|
def last_name
|
||||||
|
@obj.try(:name).try(:split).try(:last) if @obj.try(:name).try(:split).try(:size) > 1
|
||||||
|
end
|
||||||
|
end
|
||||||
@ -2,4 +2,12 @@ class UserDrop < BaseDrop
|
|||||||
def available_name
|
def available_name
|
||||||
@obj.try(:available_name)
|
@obj.try(:available_name)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def first_name
|
||||||
|
@obj.try(:name).try(:split).try(:first)
|
||||||
|
end
|
||||||
|
|
||||||
|
def last_name
|
||||||
|
@obj.try(:name).try(:split).try(:last) if @obj.try(:name).try(:split).try(:size) > 1
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
14
app/javascript/dashboard/api/channel/microsoftClient.js
Normal file
14
app/javascript/dashboard/api/channel/microsoftClient.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
/* global axios */
|
||||||
|
import ApiClient from '../ApiClient';
|
||||||
|
|
||||||
|
class MicrosoftClient extends ApiClient {
|
||||||
|
constructor() {
|
||||||
|
super('microsoft', { accountScoped: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
generateAuthorization(payload) {
|
||||||
|
return axios.post(`${this.url}/authorization`, payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new MicrosoftClient();
|
||||||
23
app/javascript/dashboard/api/integrations/dyte.js
Normal file
23
app/javascript/dashboard/api/integrations/dyte.js
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
/* global axios */
|
||||||
|
|
||||||
|
import ApiClient from '../ApiClient';
|
||||||
|
|
||||||
|
class DyteAPI extends ApiClient {
|
||||||
|
constructor() {
|
||||||
|
super('integrations/dyte', { accountScoped: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
createAMeeting(conversationId) {
|
||||||
|
return axios.post(`${this.url}/create_a_meeting`, {
|
||||||
|
conversation_id: conversationId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
addParticipantToMeeting(messageId) {
|
||||||
|
return axios.post(`${this.url}/add_participant_to_meeting`, {
|
||||||
|
message_id: messageId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default new DyteAPI();
|
||||||
35
app/javascript/dashboard/api/specs/integrations/dyte.spec.js
Normal file
35
app/javascript/dashboard/api/specs/integrations/dyte.spec.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import DyteAPIClient from '../../integrations/dyte';
|
||||||
|
import ApiClient from '../../ApiClient';
|
||||||
|
import describeWithAPIMock from '../apiSpecHelper';
|
||||||
|
|
||||||
|
describe('#accountAPI', () => {
|
||||||
|
it('creates correct instance', () => {
|
||||||
|
expect(DyteAPIClient).toBeInstanceOf(ApiClient);
|
||||||
|
expect(DyteAPIClient).toHaveProperty('createAMeeting');
|
||||||
|
expect(DyteAPIClient).toHaveProperty('addParticipantToMeeting');
|
||||||
|
});
|
||||||
|
|
||||||
|
describeWithAPIMock('createAMeeting', context => {
|
||||||
|
it('creates a valid request', () => {
|
||||||
|
DyteAPIClient.createAMeeting(1);
|
||||||
|
expect(context.axiosMock.post).toHaveBeenCalledWith(
|
||||||
|
'/api/v1/integrations/dyte/create_a_meeting',
|
||||||
|
{
|
||||||
|
conversation_id: 1,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describeWithAPIMock('addParticipantToMeeting', context => {
|
||||||
|
it('creates a valid request', () => {
|
||||||
|
DyteAPIClient.addParticipantToMeeting(1);
|
||||||
|
expect(context.axiosMock.post).toHaveBeenCalledWith(
|
||||||
|
'/api/v1/integrations/dyte/add_participant_to_meeting',
|
||||||
|
{
|
||||||
|
message_id: 1,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 12 KiB |
@ -75,7 +75,7 @@ Arial,
|
|||||||
sans-serif;
|
sans-serif;
|
||||||
$body-antialiased: true;
|
$body-antialiased: true;
|
||||||
$global-margin: $space-small;
|
$global-margin: $space-small;
|
||||||
$global-padding: $space-micro;
|
$global-padding: $space-small;
|
||||||
$global-weight-normal: normal;
|
$global-weight-normal: normal;
|
||||||
$global-weight-bold: bold;
|
$global-weight-bold: bold;
|
||||||
$global-radius: 0;
|
$global-radius: 0;
|
||||||
|
|||||||
@ -37,7 +37,6 @@
|
|||||||
@include foundation-prototype-sizing;
|
@include foundation-prototype-sizing;
|
||||||
@include foundation-prototype-spacing;
|
@include foundation-prototype-spacing;
|
||||||
|
|
||||||
|
|
||||||
@import 'typography';
|
@import 'typography';
|
||||||
@import 'layout';
|
@import 'layout';
|
||||||
@import 'animations';
|
@import 'animations';
|
||||||
@ -61,7 +60,6 @@
|
|||||||
@import 'widgets/woot-tables';
|
@import 'widgets/woot-tables';
|
||||||
|
|
||||||
@import 'views/settings/inbox';
|
@import 'views/settings/inbox';
|
||||||
@import 'views/settings/channel';
|
|
||||||
@import 'views/settings/integrations';
|
@import 'views/settings/integrations';
|
||||||
|
|
||||||
@import 'plugins/multiselect';
|
@import 'plugins/multiselect';
|
||||||
|
|||||||
@ -1,52 +0,0 @@
|
|||||||
$channel-hover-color: rgba(0, 0, 0, 0.1);
|
|
||||||
|
|
||||||
.channels {
|
|
||||||
margin-top: $space-medium;
|
|
||||||
|
|
||||||
.inactive {
|
|
||||||
filter: grayscale(100%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.channel {
|
|
||||||
@include flex;
|
|
||||||
@include background-white;
|
|
||||||
@include border-light;
|
|
||||||
|
|
||||||
cursor: pointer;
|
|
||||||
flex-direction: column;
|
|
||||||
margin: -1px;
|
|
||||||
padding: $space-normal $zero;
|
|
||||||
transition: all 0.2s ease-in;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
@include border-light;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
border: 1px solid $primary-color;
|
|
||||||
box-shadow: 0 2px 8px $channel-hover-color;
|
|
||||||
z-index: 999;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.disabled {
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
margin: $space-normal auto;
|
|
||||||
width: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.channel__title {
|
|
||||||
color: $color-body;
|
|
||||||
font-size: var(--font-size-default);
|
|
||||||
text-align: center;
|
|
||||||
text-transform: capitalize;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
color: $medium-gray;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -42,7 +42,6 @@ $resolve-button-width: 13.2rem;
|
|||||||
margin-right: var(--space-normal);
|
margin-right: var(--space-normal);
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
|
|
||||||
|
|
||||||
.user--profile__meta {
|
.user--profile__meta {
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -54,13 +53,17 @@ $resolve-button-width: 13.2rem;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.header-actions-wrap {
|
.header-actions-wrap {
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
|
margin-top: var(--space-small);
|
||||||
|
|
||||||
|
@include breakpoint(medium up) {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
&.has-open-sidebar {
|
&.has-open-sidebar {
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
|
|||||||
@ -81,8 +81,12 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.conversations-list {
|
.conversations-list {
|
||||||
@include scroll-on-hover;
|
overflow-y: auto;
|
||||||
flex: 1 1;
|
flex: 1 1;
|
||||||
|
|
||||||
|
@include breakpoint(large up) {
|
||||||
|
@include scroll-on-hover;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.chat-list__top {
|
.chat-list__top {
|
||||||
@ -324,6 +328,7 @@
|
|||||||
var(--space-one);
|
var(--space-one);
|
||||||
|
|
||||||
.is-text {
|
.is-text {
|
||||||
|
align-items: center;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
text-align: start;
|
text-align: start;
|
||||||
|
|
||||||
|
|||||||
@ -82,8 +82,8 @@
|
|||||||
@include flex-align($x: flex-end, $y: middle);
|
@include flex-align($x: flex-end, $y: middle);
|
||||||
padding: $space-small $zero;
|
padding: $space-small $zero;
|
||||||
|
|
||||||
button {
|
.button {
|
||||||
font-size: $font-size-small;
|
margin-left: var(--space-small);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.justify-content-end {
|
&.justify-content-end {
|
||||||
|
|||||||
67
app/javascript/dashboard/components/ChannelSelector.vue
Normal file
67
app/javascript/dashboard/components/ChannelSelector.vue
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<template>
|
||||||
|
<button class="small-6 medium-4 large-3 channel" @click="$emit('click')">
|
||||||
|
<img :src="src" :alt="title" />
|
||||||
|
<h3 class="channel__title">
|
||||||
|
{{ title }}
|
||||||
|
</h3>
|
||||||
|
</button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
src: {
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
.inactive {
|
||||||
|
filter: grayscale(100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.channel {
|
||||||
|
background: var(--white);
|
||||||
|
border: 1px solid var(--color-border-light);
|
||||||
|
cursor: pointer;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin: -1px;
|
||||||
|
padding: var(--space-normal) 0;
|
||||||
|
transition: all 0.2s ease-in;
|
||||||
|
align-items: center;
|
||||||
|
&:hover {
|
||||||
|
border: 1px solid var(--w-500);
|
||||||
|
box-shadow: var(--shadow-medium);
|
||||||
|
z-index: var(--z-index-high);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.disabled {
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin: var(--space-normal) auto;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.channel__title {
|
||||||
|
color: var(--color-body);
|
||||||
|
font-size: var(--font-size-default);
|
||||||
|
text-align: center;
|
||||||
|
text-transform: capitalize;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
color: var(--b-500);
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -794,30 +794,15 @@ export default {
|
|||||||
|
|
||||||
.conversations-list-wrap {
|
.conversations-list-wrap {
|
||||||
flex-shrink: 0;
|
flex-shrink: 0;
|
||||||
width: 34rem;
|
flex-basis: clamp(32rem, 4vw + 34rem, 44rem);
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@include breakpoint(large up) {
|
|
||||||
width: 36rem;
|
|
||||||
}
|
|
||||||
@include breakpoint(xlarge up) {
|
|
||||||
width: 35rem;
|
|
||||||
}
|
|
||||||
@include breakpoint(xxlarge up) {
|
|
||||||
width: 38rem;
|
|
||||||
}
|
|
||||||
@include breakpoint(xxxlarge up) {
|
|
||||||
flex-basis: 46rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.hide {
|
&.hide {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.list--full-width {
|
&.list--full-width {
|
||||||
width: 100%;
|
flex-basis: 100%;
|
||||||
@include breakpoint(xxxlarge up) {
|
|
||||||
flex-basis: 100%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.filter--actions {
|
.filter--actions {
|
||||||
|
|||||||
@ -39,6 +39,8 @@ export default {
|
|||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.wrap-content {
|
.wrap-content {
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
|
margin-top: var(--space-small);
|
||||||
|
|
||||||
.content-value {
|
.content-value {
|
||||||
font-weight: var(--font-weight-bold);
|
font-weight: var(--font-weight-bold);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -233,9 +233,6 @@ export default {
|
|||||||
width: 40rem;
|
width: 40rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.off-canvas-content.is-open-left {
|
|
||||||
transform: translateX(18.8rem);
|
|
||||||
}
|
|
||||||
|
|
||||||
.secondary-sidebar {
|
.secondary-sidebar {
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|||||||
@ -88,9 +88,9 @@
|
|||||||
v-model="action_params"
|
v-model="action_params"
|
||||||
:teams="dropdownValues"
|
:teams="dropdownValues"
|
||||||
/>
|
/>
|
||||||
<textarea
|
<woot-message-editor
|
||||||
v-if="inputType === 'textarea'"
|
v-if="inputType === 'textarea'"
|
||||||
v-model="action_params"
|
v-model="castMessageVmodel"
|
||||||
rows="4"
|
rows="4"
|
||||||
:placeholder="$t('AUTOMATION.ACTION.TEAM_MESSAGE_INPUT_PLACEHOLDER')"
|
:placeholder="$t('AUTOMATION.ACTION.TEAM_MESSAGE_INPUT_PLACEHOLDER')"
|
||||||
class="action-message"
|
class="action-message"
|
||||||
@ -107,10 +107,12 @@
|
|||||||
<script>
|
<script>
|
||||||
import AutomationActionTeamMessageInput from './AutomationActionTeamMessageInput.vue';
|
import AutomationActionTeamMessageInput from './AutomationActionTeamMessageInput.vue';
|
||||||
import AutomationActionFileInput from './AutomationFileInput.vue';
|
import AutomationActionFileInput from './AutomationFileInput.vue';
|
||||||
|
import WootMessageEditor from 'dashboard/components/widgets/WootWriter/Editor';
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
AutomationActionTeamMessageInput,
|
AutomationActionTeamMessageInput,
|
||||||
AutomationActionFileInput,
|
AutomationActionFileInput,
|
||||||
|
WootMessageEditor,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
value: {
|
value: {
|
||||||
@ -173,6 +175,17 @@ export default {
|
|||||||
'is-a-macro': this.isMacro,
|
'is-a-macro': this.isMacro,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
castMessageVmodel: {
|
||||||
|
get() {
|
||||||
|
if (Array.isArray(this.action_params)) {
|
||||||
|
return this.action_params[0];
|
||||||
|
}
|
||||||
|
return this.action_params;
|
||||||
|
},
|
||||||
|
set(value) {
|
||||||
|
this.action_params = value;
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
removeAction() {
|
removeAction() {
|
||||||
@ -281,4 +294,8 @@ export default {
|
|||||||
.action-message {
|
.action-message {
|
||||||
margin: var(--space-small) var(--space-zero) var(--space-zero);
|
margin: var(--space-small) var(--space-zero) var(--space-zero);
|
||||||
}
|
}
|
||||||
|
// Prosemirror does not have a native way of hiding the menu bar, hence
|
||||||
|
::v-deep .ProseMirror-menubar {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -1,56 +1,15 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<channel-selector
|
||||||
class="small-6 medium-4 large-3 columns channel"
|
|
||||||
:class="{ inactive: !isActive }"
|
:class="{ inactive: !isActive }"
|
||||||
|
:title="channel.name"
|
||||||
|
:src="getChannelThumbnail()"
|
||||||
@click="onItemClick"
|
@click="onItemClick"
|
||||||
>
|
/>
|
||||||
<img
|
|
||||||
v-if="channel.key === 'facebook'"
|
|
||||||
src="~dashboard/assets/images/channels/messenger.png"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
v-if="channel.key === 'twitter'"
|
|
||||||
src="~dashboard/assets/images/channels/twitter.png"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
v-if="channel.key === 'telegram'"
|
|
||||||
src="~dashboard/assets/images/channels/telegram.png"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
v-if="channel.key === 'api' && !channel.thumbnail"
|
|
||||||
src="~dashboard/assets/images/channels/api.png"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
v-if="channel.key === 'api' && channel.thumbnail"
|
|
||||||
:src="channel.thumbnail"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
v-if="channel.key === 'email'"
|
|
||||||
src="~dashboard/assets/images/channels/email.png"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
v-if="channel.key === 'line'"
|
|
||||||
src="~dashboard/assets/images/channels/line.png"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
v-if="channel.key === 'website'"
|
|
||||||
src="~dashboard/assets/images/channels/website.png"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
v-if="channel.key === 'sms'"
|
|
||||||
src="~dashboard/assets/images/channels/sms.png"
|
|
||||||
/>
|
|
||||||
<img
|
|
||||||
v-if="channel.key === 'whatsapp'"
|
|
||||||
src="~dashboard/assets/images/channels/whatsapp.png"
|
|
||||||
/>
|
|
||||||
<h3 class="channel__title">
|
|
||||||
{{ channel.name }}
|
|
||||||
</h3>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
|
import ChannelSelector from '../ChannelSelector';
|
||||||
export default {
|
export default {
|
||||||
|
components: { ChannelSelector },
|
||||||
props: {
|
props: {
|
||||||
channel: {
|
channel: {
|
||||||
type: Object,
|
type: Object,
|
||||||
@ -92,6 +51,12 @@ export default {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
getChannelThumbnail() {
|
||||||
|
if (this.channel.key === 'api' && this.channel.thumbnail) {
|
||||||
|
return this.channel.thumbnail;
|
||||||
|
}
|
||||||
|
return `/assets/images/dashboard/channels/${this.channel.key}.png`;
|
||||||
|
},
|
||||||
onItemClick() {
|
onItemClick() {
|
||||||
if (this.isActive) {
|
if (this.isActive) {
|
||||||
this.$emit('channel-item-click', this.channel.key);
|
this.$emit('channel-item-click', this.channel.key);
|
||||||
|
|||||||
@ -0,0 +1,57 @@
|
|||||||
|
<template>
|
||||||
|
<woot-button
|
||||||
|
v-if="isVideoIntegrationEnabled"
|
||||||
|
v-tooltip.top-end="
|
||||||
|
$t('INTEGRATION_SETTINGS.DYTE.START_VIDEO_CALL_HELP_TEXT')
|
||||||
|
"
|
||||||
|
icon="video"
|
||||||
|
:is-loading="isLoading"
|
||||||
|
color-scheme="secondary"
|
||||||
|
variant="smooth"
|
||||||
|
size="small"
|
||||||
|
@click="onClick"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import { mapGetters } from 'vuex';
|
||||||
|
import DyteAPI from 'dashboard/api/integrations/dyte';
|
||||||
|
import alertMixin from 'shared/mixins/alertMixin';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [alertMixin],
|
||||||
|
props: {
|
||||||
|
conversationId: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return { isLoading: false };
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters({ appIntegrations: 'integrations/getAppIntegrations' }),
|
||||||
|
isVideoIntegrationEnabled() {
|
||||||
|
return this.appIntegrations.find(
|
||||||
|
integration => integration.id === 'dyte' && !!integration.hooks.length
|
||||||
|
);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
if (!this.appIntegrations.length) {
|
||||||
|
this.$store.dispatch('integrations/get');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async onClick() {
|
||||||
|
this.isLoading = true;
|
||||||
|
try {
|
||||||
|
await DyteAPI.createAMeeting(this.conversationId);
|
||||||
|
} catch (error) {
|
||||||
|
this.showAlert(this.$t('INTEGRATION_SETTINGS.DYTE.CREATE_ERROR'));
|
||||||
|
} finally {
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@ -15,29 +15,25 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { EditorView } from 'prosemirror-view';
|
|
||||||
|
|
||||||
import { defaultMarkdownSerializer } from 'prosemirror-markdown';
|
|
||||||
import {
|
import {
|
||||||
addMentionsToMarkdownSerializer,
|
messageSchema,
|
||||||
addMentionsToMarkdownParser,
|
wootMessageWriterSetup,
|
||||||
schemaWithMentions,
|
EditorView,
|
||||||
} from '@chatwoot/prosemirror-schema/src/mentions/schema';
|
MessageMarkdownTransformer,
|
||||||
|
MessageMarkdownSerializer,
|
||||||
|
EditorState,
|
||||||
|
Selection,
|
||||||
|
} from '@chatwoot/prosemirror-schema';
|
||||||
import {
|
import {
|
||||||
suggestionsPlugin,
|
suggestionsPlugin,
|
||||||
triggerCharacters,
|
triggerCharacters,
|
||||||
} from '@chatwoot/prosemirror-schema/src/mentions/plugin';
|
} from '@chatwoot/prosemirror-schema/src/mentions/plugin';
|
||||||
import { EditorState, Selection } from 'prosemirror-state';
|
|
||||||
import { defaultMarkdownParser } from 'prosemirror-markdown';
|
|
||||||
import { wootWriterSetup } from '@chatwoot/prosemirror-schema';
|
|
||||||
|
|
||||||
import TagAgents from '../conversation/TagAgents';
|
import TagAgents from '../conversation/TagAgents';
|
||||||
import CannedResponse from '../conversation/CannedResponse';
|
import CannedResponse from '../conversation/CannedResponse';
|
||||||
|
|
||||||
const TYPING_INDICATOR_IDLE_TIME = 4000;
|
const TYPING_INDICATOR_IDLE_TIME = 4000;
|
||||||
|
|
||||||
import '@chatwoot/prosemirror-schema/src/woot-editor.css';
|
|
||||||
import {
|
import {
|
||||||
hasPressedEnterAndNotCmdOrShift,
|
hasPressedEnterAndNotCmdOrShift,
|
||||||
hasPressedCommandAndEnter,
|
hasPressedCommandAndEnter,
|
||||||
@ -53,9 +49,9 @@ import AnalyticsHelper, {
|
|||||||
|
|
||||||
const createState = (content, placeholder, plugins = []) => {
|
const createState = (content, placeholder, plugins = []) => {
|
||||||
return EditorState.create({
|
return EditorState.create({
|
||||||
doc: addMentionsToMarkdownParser(defaultMarkdownParser).parse(content),
|
doc: new MessageMarkdownTransformer(messageSchema).parse(content),
|
||||||
plugins: wootWriterSetup({
|
plugins: wootMessageWriterSetup({
|
||||||
schema: schemaWithMentions,
|
schema: messageSchema,
|
||||||
placeholder,
|
placeholder,
|
||||||
plugins,
|
plugins,
|
||||||
}),
|
}),
|
||||||
@ -88,9 +84,7 @@ export default {
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
contentFromEditor() {
|
contentFromEditor() {
|
||||||
return addMentionsToMarkdownSerializer(
|
return MessageMarkdownSerializer.serialize(this.editorView.state.doc);
|
||||||
defaultMarkdownSerializer
|
|
||||||
).serialize(this.editorView.state.doc);
|
|
||||||
},
|
},
|
||||||
plugins() {
|
plugins() {
|
||||||
if (!this.enableSuggestions) {
|
if (!this.enableSuggestions) {
|
||||||
@ -282,11 +276,11 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let from = this.range.from - 1;
|
let from = this.range.from - 1;
|
||||||
let node = addMentionsToMarkdownParser(defaultMarkdownParser).parse(
|
let node = new MessageMarkdownTransformer(messageSchema).parse(
|
||||||
cannedItem
|
cannedItem
|
||||||
);
|
);
|
||||||
|
|
||||||
if (node.childCount === 1) {
|
if (node.textContent === cannedItem) {
|
||||||
node = this.editorView.state.schema.text(cannedItem);
|
node = this.editorView.state.schema.text(cannedItem);
|
||||||
from = this.range.from;
|
from = this.range.from;
|
||||||
}
|
}
|
||||||
@ -372,10 +366,18 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
@import '~@chatwoot/prosemirror-schema/src/styles/base.scss';
|
||||||
|
|
||||||
.ProseMirror-menubar-wrapper {
|
.ProseMirror-menubar-wrapper {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
|
.ProseMirror-menubar {
|
||||||
|
min-height: var(--space-two) !important;
|
||||||
|
margin-left: var(--space-minus-one);
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
> .ProseMirror {
|
> .ProseMirror {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
@ -384,6 +386,7 @@ export default {
|
|||||||
|
|
||||||
.editor-root {
|
.editor-root {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ProseMirror-woot-style {
|
.ProseMirror-woot-style {
|
||||||
@ -406,6 +409,9 @@ export default {
|
|||||||
color: var(--s-900);
|
color: var(--s-900);
|
||||||
padding: 0 var(--space-smaller);
|
padding: 0 var(--space-smaller);
|
||||||
}
|
}
|
||||||
|
.ProseMirror-menubar {
|
||||||
|
background: var(--y-50);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-wrap {
|
.editor-wrap {
|
||||||
|
|||||||
@ -0,0 +1,167 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="editor-root editor--article">
|
||||||
|
<div ref="editor" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import {
|
||||||
|
fullSchema,
|
||||||
|
wootArticleWriterSetup,
|
||||||
|
EditorView,
|
||||||
|
ArticleMarkdownSerializer,
|
||||||
|
ArticleMarkdownTransformer,
|
||||||
|
EditorState,
|
||||||
|
Selection,
|
||||||
|
} from '@chatwoot/prosemirror-schema';
|
||||||
|
|
||||||
|
import eventListenerMixins from 'shared/mixins/eventListenerMixins';
|
||||||
|
import uiSettingsMixin from 'dashboard/mixins/uiSettings';
|
||||||
|
|
||||||
|
const createState = (content, placeholder, plugins = []) => {
|
||||||
|
return EditorState.create({
|
||||||
|
doc: new ArticleMarkdownTransformer(fullSchema).parse(content),
|
||||||
|
plugins: wootArticleWriterSetup({
|
||||||
|
schema: fullSchema,
|
||||||
|
placeholder,
|
||||||
|
plugins,
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [eventListenerMixins, uiSettingsMixin],
|
||||||
|
props: {
|
||||||
|
value: { type: String, default: '' },
|
||||||
|
editorId: { type: String, default: '' },
|
||||||
|
placeholder: { type: String, default: '' },
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
editorView: null,
|
||||||
|
state: undefined,
|
||||||
|
plugins: [],
|
||||||
|
};
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
contentFromEditor() {
|
||||||
|
if (this.editorView) {
|
||||||
|
return ArticleMarkdownSerializer.serialize(this.editorView.state.doc);
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
value(newValue = '') {
|
||||||
|
if (newValue !== this.contentFromEditor) {
|
||||||
|
this.reloadState();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
editorId() {
|
||||||
|
this.reloadState();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.state = createState(this.value, this.placeholder, this.plugins);
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.createEditorView();
|
||||||
|
|
||||||
|
this.editorView.updateState(this.state);
|
||||||
|
this.focusEditorInputField();
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
reloadState() {
|
||||||
|
this.state = createState(this.value, this.placeholder, this.plugins);
|
||||||
|
this.editorView.updateState(this.state);
|
||||||
|
this.focusEditorInputField();
|
||||||
|
},
|
||||||
|
createEditorView() {
|
||||||
|
this.editorView = new EditorView(this.$refs.editor, {
|
||||||
|
state: this.state,
|
||||||
|
dispatchTransaction: tx => {
|
||||||
|
this.state = this.state.apply(tx);
|
||||||
|
this.emitOnChange();
|
||||||
|
},
|
||||||
|
handleDOMEvents: {
|
||||||
|
keyup: () => {
|
||||||
|
this.onKeyup();
|
||||||
|
},
|
||||||
|
keydown: (view, event) => {
|
||||||
|
this.onKeydown(event);
|
||||||
|
},
|
||||||
|
focus: () => {
|
||||||
|
this.onFocus();
|
||||||
|
},
|
||||||
|
blur: () => {
|
||||||
|
this.onBlur();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
handleKeyEvents() {},
|
||||||
|
focusEditorInputField() {
|
||||||
|
const { tr } = this.editorView.state;
|
||||||
|
const selection = Selection.atEnd(tr.doc);
|
||||||
|
|
||||||
|
this.editorView.dispatch(tr.setSelection(selection));
|
||||||
|
this.editorView.focus();
|
||||||
|
},
|
||||||
|
|
||||||
|
emitOnChange() {
|
||||||
|
this.editorView.updateState(this.state);
|
||||||
|
|
||||||
|
this.$emit('input', this.contentFromEditor);
|
||||||
|
},
|
||||||
|
|
||||||
|
onKeyup() {
|
||||||
|
this.$emit('keyup');
|
||||||
|
},
|
||||||
|
onKeydown() {
|
||||||
|
this.$emit('keydown');
|
||||||
|
},
|
||||||
|
onBlur() {
|
||||||
|
this.$emit('blur');
|
||||||
|
},
|
||||||
|
onFocus() {
|
||||||
|
this.$emit('focus');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import '~@chatwoot/prosemirror-schema/src/styles/article.scss';
|
||||||
|
|
||||||
|
.ProseMirror-menubar-wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
> .ProseMirror {
|
||||||
|
padding: 0;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-root {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ProseMirror-woot-style {
|
||||||
|
min-height: 8rem;
|
||||||
|
max-height: 12rem;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ProseMirror-prompt {
|
||||||
|
z-index: var(--z-index-highest);
|
||||||
|
background: var(--white);
|
||||||
|
box-shadow: var(--shadow-large);
|
||||||
|
border-radius: var(--border-radius-normal);
|
||||||
|
border: 1px solid var(--color-border);
|
||||||
|
min-width: 40rem;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -87,6 +87,10 @@
|
|||||||
:title="'Whatsapp Templates'"
|
:title="'Whatsapp Templates'"
|
||||||
@click="$emit('selectWhatsappTemplate')"
|
@click="$emit('selectWhatsappTemplate')"
|
||||||
/>
|
/>
|
||||||
|
<video-call-button
|
||||||
|
v-if="(isAWebWidgetInbox || isAPIInbox) && !isOnPrivateNote"
|
||||||
|
:conversation-id="conversationId"
|
||||||
|
/>
|
||||||
<transition name="modal-fade">
|
<transition name="modal-fade">
|
||||||
<div
|
<div
|
||||||
v-show="$refs.upload && $refs.upload.dropActive"
|
v-show="$refs.upload && $refs.upload.dropActive"
|
||||||
@ -124,13 +128,13 @@ import {
|
|||||||
ALLOWED_FILE_TYPES,
|
ALLOWED_FILE_TYPES,
|
||||||
ALLOWED_FILE_TYPES_FOR_TWILIO_WHATSAPP,
|
ALLOWED_FILE_TYPES_FOR_TWILIO_WHATSAPP,
|
||||||
} from 'shared/constants/messages';
|
} from 'shared/constants/messages';
|
||||||
|
import VideoCallButton from '../VideoCallButton';
|
||||||
import { REPLY_EDITOR_MODES } from './constants';
|
import { REPLY_EDITOR_MODES } from './constants';
|
||||||
import { mapGetters } from 'vuex';
|
import { mapGetters } from 'vuex';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ReplyBottomPanel',
|
name: 'ReplyBottomPanel',
|
||||||
components: { FileUpload },
|
components: { FileUpload, VideoCallButton },
|
||||||
mixins: [eventListenerMixins, uiSettingsMixin, inboxMixin],
|
mixins: [eventListenerMixins, uiSettingsMixin, inboxMixin],
|
||||||
props: {
|
props: {
|
||||||
mode: {
|
mode: {
|
||||||
@ -209,6 +213,10 @@ export default {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
},
|
},
|
||||||
|
conversationId: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
...mapGetters({
|
...mapGetters({
|
||||||
@ -269,7 +277,7 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
showMessageSignatureButton() {
|
showMessageSignatureButton() {
|
||||||
return !this.isPrivate && this.isAnEmailChannel;
|
return !this.isOnPrivateNote && this.isAnEmailChannel;
|
||||||
},
|
},
|
||||||
sendWithSignature() {
|
sendWithSignature() {
|
||||||
const { send_with_signature: isEnabled } = this.uiSettings;
|
const { send_with_signature: isEnabled } = this.uiSettings;
|
||||||
|
|||||||
@ -166,10 +166,14 @@ export default {
|
|||||||
.conversation-sidebar-wrap {
|
.conversation-sidebar-wrap {
|
||||||
height: auto;
|
height: auto;
|
||||||
flex: 0 0;
|
flex: 0 0;
|
||||||
overflow: hidden;
|
z-index: var(--z-index-low);
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
background: white;
|
background: white;
|
||||||
flex-basis: 28rem;
|
flex-basis: 100%;
|
||||||
|
|
||||||
|
@include breakpoint(medium up) {
|
||||||
|
flex-basis: 28rem;
|
||||||
|
}
|
||||||
|
|
||||||
@include breakpoint(large up) {
|
@include breakpoint(large up) {
|
||||||
flex-basis: 30em;
|
flex-basis: 30em;
|
||||||
|
|||||||
@ -1,53 +1,54 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="conv-header">
|
<div class="conv-header">
|
||||||
<div class="user">
|
<div class="conversation-header--details">
|
||||||
<back-button v-if="showBackButton" :back-url="backButtonUrl" />
|
<div class="user">
|
||||||
<Thumbnail
|
<back-button v-if="showBackButton" :back-url="backButtonUrl" />
|
||||||
:src="currentContact.thumbnail"
|
<Thumbnail
|
||||||
size="40px"
|
:src="currentContact.thumbnail"
|
||||||
:badge="inboxBadge"
|
:badge="inboxBadge"
|
||||||
:username="currentContact.name"
|
:username="currentContact.name"
|
||||||
:status="currentContact.availability_status"
|
:status="currentContact.availability_status"
|
||||||
/>
|
/>
|
||||||
<div class="user--profile__meta">
|
<div class="user--profile__meta">
|
||||||
<h3 class="user--name text-truncate">
|
<h3 class="user--name text-truncate">
|
||||||
<span class="margin-right-smaller">{{ currentContact.name }}</span>
|
<span class="margin-right-smaller">{{ currentContact.name }}</span>
|
||||||
<fluent-icon
|
<fluent-icon
|
||||||
v-if="!isHMACVerified"
|
v-if="!isHMACVerified"
|
||||||
v-tooltip="$t('CONVERSATION.UNVERIFIED_SESSION')"
|
v-tooltip="$t('CONVERSATION.UNVERIFIED_SESSION')"
|
||||||
size="14"
|
size="14"
|
||||||
class="hmac-warning__icon"
|
class="hmac-warning__icon"
|
||||||
icon="warning"
|
icon="warning"
|
||||||
/>
|
/>
|
||||||
</h3>
|
</h3>
|
||||||
<div class="conversation--header--actions">
|
<div class="conversation--header--actions text-truncate">
|
||||||
<inbox-name
|
<inbox-name
|
||||||
v-if="hasMultipleInboxes"
|
v-if="hasMultipleInboxes"
|
||||||
:inbox="inbox"
|
:inbox="inbox"
|
||||||
class="margin-right-small"
|
class="margin-right-small"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
v-if="isSnoozed"
|
v-if="isSnoozed"
|
||||||
class="snoozed--display-text margin-right-small"
|
class="snoozed--display-text margin-right-small"
|
||||||
>
|
>
|
||||||
{{ snoozedDisplayText }}
|
{{ snoozedDisplayText }}
|
||||||
</span>
|
</span>
|
||||||
<woot-button
|
<woot-button
|
||||||
class="user--profile__button margin-right-small"
|
class="user--profile__button margin-right-small"
|
||||||
size="small"
|
size="small"
|
||||||
variant="link"
|
variant="link"
|
||||||
@click="$emit('contact-panel-toggle')"
|
@click="$emit('contact-panel-toggle')"
|
||||||
>
|
>
|
||||||
{{ contactPanelToggleText }}
|
{{ contactPanelToggleText }}
|
||||||
</woot-button>
|
</woot-button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div
|
||||||
<div
|
class="header-actions-wrap"
|
||||||
class="header-actions-wrap"
|
:class="{ 'has-open-sidebar': isContactPanelOpen }"
|
||||||
:class="{ 'has-open-sidebar': isContactPanelOpen }"
|
>
|
||||||
>
|
<more-actions :conversation-id="currentChat.id" />
|
||||||
<more-actions :conversation-id="currentChat.id" />
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -165,14 +166,27 @@ export default {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.text-truncate {
|
@import '~dashboard/assets/scss/woot';
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
.conv-header {
|
.conv-header {
|
||||||
flex: 0 0 var(--space-jumbo);
|
flex: 0 0 var(--space-jumbo);
|
||||||
|
flex-direction: row;
|
||||||
|
|
||||||
|
@include breakpoint(medium up) {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.conversation-header--details {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
@include breakpoint(medium up) {
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.option__desc {
|
.option__desc {
|
||||||
|
|||||||
@ -1,8 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<li
|
<li v-if="shouldRenderMessage" :class="alignBubble">
|
||||||
v-if="hasAttachments || data.content || isEmailContentType"
|
|
||||||
:class="alignBubble"
|
|
||||||
>
|
|
||||||
<div :class="wrapClass">
|
<div :class="wrapClass">
|
||||||
<div v-tooltip.top-start="messageToolTip" :class="bubbleClass">
|
<div v-tooltip.top-start="messageToolTip" :class="bubbleClass">
|
||||||
<bubble-mail-head
|
<bubble-mail-head
|
||||||
@ -17,6 +14,11 @@
|
|||||||
:is-email="isEmailContentType"
|
:is-email="isEmailContentType"
|
||||||
:display-quoted-button="displayQuotedButton"
|
:display-quoted-button="displayQuotedButton"
|
||||||
/>
|
/>
|
||||||
|
<bubble-integration
|
||||||
|
:message-id="data.id"
|
||||||
|
:content-attributes="contentAttributes"
|
||||||
|
:inbox-id="data.inbox_id"
|
||||||
|
/>
|
||||||
<span
|
<span
|
||||||
v-if="isPending && hasAttachments"
|
v-if="isPending && hasAttachments"
|
||||||
class="chat-bubble has-attachment agent"
|
class="chat-bubble has-attachment agent"
|
||||||
@ -111,14 +113,14 @@
|
|||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import messageFormatterMixin from 'shared/mixins/messageFormatterMixin';
|
import messageFormatterMixin from 'shared/mixins/messageFormatterMixin';
|
||||||
|
import BubbleActions from './bubble/Actions';
|
||||||
|
import BubbleFile from './bubble/File';
|
||||||
|
import BubbleImage from './bubble/Image';
|
||||||
|
import BubbleIntegration from './bubble/Integration.vue';
|
||||||
|
import BubbleLocation from './bubble/Location';
|
||||||
import BubbleMailHead from './bubble/MailHead';
|
import BubbleMailHead from './bubble/MailHead';
|
||||||
import BubbleText from './bubble/Text';
|
import BubbleText from './bubble/Text';
|
||||||
import BubbleImage from './bubble/Image';
|
|
||||||
import BubbleFile from './bubble/File';
|
|
||||||
import BubbleVideo from './bubble/Video.vue';
|
import BubbleVideo from './bubble/Video.vue';
|
||||||
import BubbleActions from './bubble/Actions';
|
|
||||||
import BubbleLocation from './bubble/Location';
|
|
||||||
|
|
||||||
import Spinner from 'shared/components/Spinner';
|
import Spinner from 'shared/components/Spinner';
|
||||||
import ContextMenu from 'dashboard/modules/conversations/components/MessageContextMenu';
|
import ContextMenu from 'dashboard/modules/conversations/components/MessageContextMenu';
|
||||||
|
|
||||||
@ -130,12 +132,13 @@ import { generateBotMessageContent } from './helpers/botMessageContentHelper';
|
|||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
BubbleActions,
|
BubbleActions,
|
||||||
BubbleText,
|
|
||||||
BubbleImage,
|
|
||||||
BubbleFile,
|
BubbleFile,
|
||||||
BubbleVideo,
|
BubbleImage,
|
||||||
BubbleMailHead,
|
BubbleIntegration,
|
||||||
BubbleLocation,
|
BubbleLocation,
|
||||||
|
BubbleMailHead,
|
||||||
|
BubbleText,
|
||||||
|
BubbleVideo,
|
||||||
ContextMenu,
|
ContextMenu,
|
||||||
Spinner,
|
Spinner,
|
||||||
},
|
},
|
||||||
@ -169,6 +172,14 @@ export default {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
shouldRenderMessage() {
|
||||||
|
return (
|
||||||
|
this.hasAttachments ||
|
||||||
|
this.data.content ||
|
||||||
|
this.isEmailContentType ||
|
||||||
|
this.isAnIntegrationMessage
|
||||||
|
);
|
||||||
|
},
|
||||||
emailMessageContent() {
|
emailMessageContent() {
|
||||||
const {
|
const {
|
||||||
html_content: { full: fullHTMLContent } = {},
|
html_content: { full: fullHTMLContent } = {},
|
||||||
@ -274,6 +285,9 @@ export default {
|
|||||||
isTemplate() {
|
isTemplate() {
|
||||||
return this.data.message_type === MESSAGE_TYPE.TEMPLATE;
|
return this.data.message_type === MESSAGE_TYPE.TEMPLATE;
|
||||||
},
|
},
|
||||||
|
isAnIntegrationMessage() {
|
||||||
|
return this.contentType === 'integrations';
|
||||||
|
},
|
||||||
emailHeadAttributes() {
|
emailHeadAttributes() {
|
||||||
return {
|
return {
|
||||||
email: this.contentAttributes.email,
|
email: this.contentAttributes.email,
|
||||||
|
|||||||
@ -96,25 +96,26 @@
|
|||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<reply-bottom-panel
|
<reply-bottom-panel
|
||||||
:mode="replyType"
|
:conversation-id="conversationId"
|
||||||
:inbox="inbox"
|
|
||||||
:send-button-text="replyButtonLabel"
|
|
||||||
:on-file-upload="onFileUpload"
|
|
||||||
:show-file-upload="showFileUpload"
|
|
||||||
:show-audio-recorder="showAudioRecorder"
|
|
||||||
:toggle-emoji-picker="toggleEmojiPicker"
|
|
||||||
:toggle-audio-recorder="toggleAudioRecorder"
|
|
||||||
:toggle-audio-recorder-play-pause="toggleAudioRecorderPlayPause"
|
|
||||||
:show-emoji-picker="showEmojiPicker"
|
|
||||||
:on-send="onSendReply"
|
|
||||||
:is-send-disabled="isReplyButtonDisabled"
|
|
||||||
:recording-audio-duration-text="recordingAudioDurationText"
|
|
||||||
:recording-audio-state="recordingAudioState"
|
|
||||||
:is-recording-audio="isRecordingAudio"
|
|
||||||
:is-on-private-note="isOnPrivateNote"
|
|
||||||
:show-editor-toggle="isAPIInbox && !isOnPrivateNote"
|
|
||||||
:enable-multiple-file-upload="enableMultipleFileUpload"
|
:enable-multiple-file-upload="enableMultipleFileUpload"
|
||||||
:has-whatsapp-templates="hasWhatsappTemplates"
|
:has-whatsapp-templates="hasWhatsappTemplates"
|
||||||
|
:inbox="inbox"
|
||||||
|
:is-on-private-note="isOnPrivateNote"
|
||||||
|
:is-recording-audio="isRecordingAudio"
|
||||||
|
:is-send-disabled="isReplyButtonDisabled"
|
||||||
|
:mode="replyType"
|
||||||
|
:on-file-upload="onFileUpload"
|
||||||
|
:on-send="onSendReply"
|
||||||
|
:recording-audio-duration-text="recordingAudioDurationText"
|
||||||
|
:recording-audio-state="recordingAudioState"
|
||||||
|
:send-button-text="replyButtonLabel"
|
||||||
|
:show-audio-recorder="showAudioRecorder"
|
||||||
|
:show-editor-toggle="isAPIInbox && !isOnPrivateNote"
|
||||||
|
:show-emoji-picker="showEmojiPicker"
|
||||||
|
:show-file-upload="showFileUpload"
|
||||||
|
:toggle-audio-recorder-play-pause="toggleAudioRecorderPlayPause"
|
||||||
|
:toggle-audio-recorder="toggleAudioRecorder"
|
||||||
|
:toggle-emoji-picker="toggleEmojiPicker"
|
||||||
@selectWhatsappTemplate="openWhatsappTemplateModal"
|
@selectWhatsappTemplate="openWhatsappTemplateModal"
|
||||||
@toggle-editor="toggleRichContentEditor"
|
@toggle-editor="toggleRichContentEditor"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@ -96,7 +96,9 @@ export default {
|
|||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.mention--box {
|
.mention--box {
|
||||||
background: var(--white);
|
background: var(--white);
|
||||||
|
border-radius: var(--border-radius-normal);
|
||||||
border-top: 1px solid var(--color-border);
|
border-top: 1px solid var(--color-border);
|
||||||
|
box-shadow: var(--shadow-medium);
|
||||||
font-size: var(--font-size-small);
|
font-size: var(--font-size-small);
|
||||||
left: 0;
|
left: 0;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
|
|||||||
@ -0,0 +1,39 @@
|
|||||||
|
<template>
|
||||||
|
<dyte-video-call
|
||||||
|
v-if="showDyteIntegration"
|
||||||
|
:message-id="messageId"
|
||||||
|
:meeting-data="contentAttributes.data"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import DyteVideoCall from './integrations/Dyte.vue';
|
||||||
|
import inboxMixin from 'shared/mixins/inboxMixin';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { DyteVideoCall },
|
||||||
|
mixins: [inboxMixin],
|
||||||
|
props: {
|
||||||
|
messageId: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
contentAttributes: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
inboxId: {
|
||||||
|
type: [String, Number],
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
showDyteIntegration() {
|
||||||
|
const isEnabledOnTheInbox = this.isAPIInbox || this.isAWebWidgetInbox;
|
||||||
|
return isEnabledOnTheInbox && this.contentAttributes.type === 'dyte';
|
||||||
|
},
|
||||||
|
inbox() {
|
||||||
|
return this.$store.getters['inboxes/getInbox'](this.inboxId);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@ -0,0 +1,103 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<woot-button
|
||||||
|
size="small"
|
||||||
|
variant="smooth"
|
||||||
|
color-scheme="secondary"
|
||||||
|
icon="video-add"
|
||||||
|
class="join-call-button"
|
||||||
|
:is-loading="isLoading"
|
||||||
|
@click="joinTheCall"
|
||||||
|
>
|
||||||
|
{{ $t('INTEGRATION_SETTINGS.DYTE.CLICK_HERE_TO_JOIN') }}
|
||||||
|
</woot-button>
|
||||||
|
<div v-if="dyteAuthToken" class="video-call--container">
|
||||||
|
<iframe
|
||||||
|
:src="meetingLink"
|
||||||
|
allow="camera;microphone;fullscreen;display-capture;picture-in-picture;clipboard-write;"
|
||||||
|
/>
|
||||||
|
<woot-button
|
||||||
|
size="small"
|
||||||
|
variant="smooth"
|
||||||
|
color-scheme="secondary"
|
||||||
|
class="join-call-button"
|
||||||
|
@click="leaveTheRoom"
|
||||||
|
>
|
||||||
|
{{ $t('INTEGRATION_SETTINGS.DYTE.LEAVE_THE_ROOM') }}
|
||||||
|
</woot-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
import DyteAPI from 'dashboard/api/integrations/dyte';
|
||||||
|
import { buildDyteURL } from 'shared/helpers/IntegrationHelper';
|
||||||
|
import alertMixin from 'shared/mixins/alertMixin';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [alertMixin],
|
||||||
|
props: {
|
||||||
|
messageId: {
|
||||||
|
type: Number,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
meetingData: {
|
||||||
|
type: Object,
|
||||||
|
default: () => ({}),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return { isLoading: false, dyteAuthToken: '', isSDKMounted: false };
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
meetingLink() {
|
||||||
|
return buildDyteURL(this.meetingData.room_name, this.dyteAuthToken);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
async joinTheCall() {
|
||||||
|
this.isLoading = true;
|
||||||
|
try {
|
||||||
|
const {
|
||||||
|
data: { authResponse: { authToken } = {} } = {},
|
||||||
|
} = await DyteAPI.addParticipantToMeeting(this.messageId);
|
||||||
|
this.dyteAuthToken = authToken;
|
||||||
|
} catch (err) {
|
||||||
|
this.showAlert(this.$t('INTEGRATION_SETTINGS.DYTE.JOIN_ERROR'));
|
||||||
|
} finally {
|
||||||
|
this.isLoading = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
leaveTheRoom() {
|
||||||
|
this.dyteAuthToken = '';
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
<style lang="scss">
|
||||||
|
.join-call-button {
|
||||||
|
margin: var(--space-small) 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-call--container {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
z-index: var(--z-index-high);
|
||||||
|
padding: var(--space-smaller);
|
||||||
|
background: var(--b-800);
|
||||||
|
|
||||||
|
iframe {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
position: absolute;
|
||||||
|
top: var(--space-smaller);
|
||||||
|
right: 16rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -70,7 +70,9 @@ export default {
|
|||||||
.mention--box {
|
.mention--box {
|
||||||
background: var(--white);
|
background: var(--white);
|
||||||
border-bottom: var(--space-small) solid var(--white);
|
border-bottom: var(--space-small) solid var(--white);
|
||||||
|
border-radius: var(--border-radius-normal);
|
||||||
border-top: 1px solid var(--color-border);
|
border-top: 1px solid var(--color-border);
|
||||||
|
box-shadow: var(--shadow-medium);
|
||||||
left: 0;
|
left: 0;
|
||||||
max-height: 14rem;
|
max-height: 14rem;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
|
|||||||
@ -1,23 +1,14 @@
|
|||||||
<template>
|
<template>
|
||||||
<modal :show.sync="show" :on-close="cancel">
|
<modal :show.sync="show" :on-close="cancel">
|
||||||
<div class="column content-box">
|
<div class="column content-box">
|
||||||
<woot-modal-header :header-title="title" />
|
<woot-modal-header :header-title="title" :header-content="description" />
|
||||||
<div class="row modal-content">
|
<div class="modal-footer">
|
||||||
<div class="medium-12 columns">
|
<woot-button variant="clear" @click="cancel">
|
||||||
<p>
|
{{ cancelLabel }}
|
||||||
{{ description }}
|
</woot-button>
|
||||||
</p>
|
<woot-button @click="confirm">
|
||||||
</div>
|
{{ confirmLabel }}
|
||||||
<div class="modal-footer">
|
</woot-button>
|
||||||
<div class="medium-12 columns">
|
|
||||||
<woot-button @click="confirm">
|
|
||||||
{{ confirmLabel }}
|
|
||||||
</woot-button>
|
|
||||||
<button class="button clear" @click="cancel">
|
|
||||||
{{ cancelLabel }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</modal>
|
</modal>
|
||||||
@ -73,3 +64,8 @@ export default {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.modal-container .modal-footer {
|
||||||
|
padding: var(--space-normal) var(--space-medium);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@ -23,5 +23,6 @@ export default {
|
|||||||
},
|
},
|
||||||
DOCS_URL: '//www.chatwoot.com/docs/product/',
|
DOCS_URL: '//www.chatwoot.com/docs/product/',
|
||||||
TESTIMONIAL_URL: 'https://testimonials.cdn.chatwoot.com/content.json',
|
TESTIMONIAL_URL: 'https://testimonials.cdn.chatwoot.com/content.json',
|
||||||
|
SMALL_SCREEN_BREAKPOINT: 1024,
|
||||||
};
|
};
|
||||||
export const DEFAULT_REDIRECT_URL = '/app/';
|
export const DEFAULT_REDIRECT_URL = '/app/';
|
||||||
|
|||||||
@ -97,8 +97,9 @@ export const generateConditionOptions = (options, key = 'id') => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getActionOptions = ({ teams, labels, type }) => {
|
export const getActionOptions = ({ agents, teams, labels, type }) => {
|
||||||
const actionsMap = {
|
const actionsMap = {
|
||||||
|
assign_agent: agents,
|
||||||
assign_team: teams,
|
assign_team: teams,
|
||||||
send_email_to_team: teams,
|
send_email_to_team: teams,
|
||||||
add_label: generateConditionOptions(labels, 'title'),
|
add_label: generateConditionOptions(labels, 'title'),
|
||||||
@ -178,7 +179,7 @@ export const getDefaultConditions = eventName => {
|
|||||||
export const getDefaultActions = () => {
|
export const getDefaultActions = () => {
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
action_name: 'assign_team',
|
action_name: 'assign_agent',
|
||||||
action_params: [],
|
action_params: [],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -213,7 +214,7 @@ export const isCustomAttribute = (attrs, key) => {
|
|||||||
|
|
||||||
export const generateCustomAttributes = (
|
export const generateCustomAttributes = (
|
||||||
conversationAttributes = [],
|
conversationAttributes = [],
|
||||||
contactAttribtues = [],
|
contactAttributes = [],
|
||||||
conversationlabel,
|
conversationlabel,
|
||||||
contactlabel
|
contactlabel
|
||||||
) => {
|
) => {
|
||||||
@ -228,14 +229,14 @@ export const generateCustomAttributes = (
|
|||||||
...conversationAttributes
|
...conversationAttributes
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (contactAttribtues.length) {
|
if (contactAttributes.length) {
|
||||||
customAttributes.push(
|
customAttributes.push(
|
||||||
{
|
{
|
||||||
key: `contact_custom_attribute`,
|
key: `contact_custom_attribute`,
|
||||||
name: contactlabel,
|
name: contactlabel,
|
||||||
disabled: true,
|
disabled: true,
|
||||||
},
|
},
|
||||||
...contactAttribtues
|
...contactAttributes
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return customAttributes;
|
return customAttributes;
|
||||||
|
|||||||
@ -24,8 +24,11 @@
|
|||||||
"TITLE": "Select an agent bot",
|
"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.",
|
"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": "تحديث",
|
"SUBMIT": "تحديث",
|
||||||
|
"DISCONNECT": "Disconnect Bot",
|
||||||
"SUCCESS_MESSAGE": "Successfully updated the agent 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",
|
"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"
|
"SELECT_PLACEHOLDER": "Select Bot"
|
||||||
},
|
},
|
||||||
"ADD": {
|
"ADD": {
|
||||||
|
|||||||
@ -42,8 +42,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"SUCCESS_MESSAGE": "تم إضافة سمة مخصصة بنجاح",
|
"SUCCESS_MESSAGE": "تم إضافة سمة مخصصة بنجاح!",
|
||||||
"ERROR_MESSAGE": "تعذر إنشاء سمة مخصصة، الرجاء المحاولة مرة أخرى لاحقاً"
|
"ERROR_MESSAGE": "تعذر إنشاء سمة مخصصة، الرجاء المحاولة مرة أخرى لاحقاً."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
|
|||||||
@ -2,8 +2,8 @@
|
|||||||
"BULK_ACTION": {
|
"BULK_ACTION": {
|
||||||
"CONVERSATIONS_SELECTED": "%{conversationCount} المحادثات المحددة",
|
"CONVERSATIONS_SELECTED": "%{conversationCount} المحادثات المحددة",
|
||||||
"AGENT_SELECT_LABEL": "اختر وكيل",
|
"AGENT_SELECT_LABEL": "اختر وكيل",
|
||||||
"ASSIGN_CONFIRMATION_LABEL": "Are you sure to assign %{conversationCount} %{conversationLabel} to",
|
"ASSIGN_CONFIRMATION_LABEL": "هل أنت متأكد من أنك تريد تعيين %{conversationCount} %{conversationLabel} إلى",
|
||||||
"UNASSIGN_CONFIRMATION_LABEL": "Are you sure to unassign %{conversationCount} %{conversationLabel}?",
|
"UNASSIGN_CONFIRMATION_LABEL": "هل أنت متأكد من إلغاء تعيين %{conversationCount} %{conversationLabel}؟",
|
||||||
"GO_BACK_LABEL": "العودة للخلف",
|
"GO_BACK_LABEL": "العودة للخلف",
|
||||||
"ASSIGN_LABEL": "تكليف",
|
"ASSIGN_LABEL": "تكليف",
|
||||||
"YES": "نعم",
|
"YES": "نعم",
|
||||||
@ -31,10 +31,10 @@
|
|||||||
"TEAMS": {
|
"TEAMS": {
|
||||||
"TEAM_SELECT_LABEL": "اختيار فريق",
|
"TEAM_SELECT_LABEL": "اختيار فريق",
|
||||||
"NONE": "لا شيء",
|
"NONE": "لا شيء",
|
||||||
"NO_TEAMS_AVAILABLE": "There are no teams added to this account yet.",
|
"NO_TEAMS_AVAILABLE": "لا توجد فرق مضافة إلى هذا الحساب حتى الآن.",
|
||||||
"ASSIGN_SELECTED_TEAMS": "Assign selected team",
|
"ASSIGN_SELECTED_TEAMS": "تعيين فريق محدد",
|
||||||
"ASSIGN_SUCCESFUL": "Teams assiged successfully",
|
"ASSIGN_SUCCESFUL": "تم تعيين الفرق بنجاح",
|
||||||
"ASSIGN_FAILED": "Failed to assign team, please try again"
|
"ASSIGN_FAILED": "فشل تعيين الفريق، الرجاء المحاولة مرة أخرى"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -57,8 +57,8 @@
|
|||||||
"REPLY_TO_TWEET": "الرد على هذه التغريدة",
|
"REPLY_TO_TWEET": "الرد على هذه التغريدة",
|
||||||
"LINK_TO_STORY": "الذهاب إلى قصة الإنستقرام",
|
"LINK_TO_STORY": "الذهاب إلى قصة الإنستقرام",
|
||||||
"SENT": "Sent successfully",
|
"SENT": "Sent successfully",
|
||||||
"READ": "Read successfully",
|
"READ": "تمت القراءة بنجاح",
|
||||||
"DELIVERED": "Delivered successfully",
|
"DELIVERED": "تم الإرسال بنجاح",
|
||||||
"NO_MESSAGES": "لا توجد رسائل",
|
"NO_MESSAGES": "لا توجد رسائل",
|
||||||
"NO_CONTENT": "لم يتم العثور على محتوى",
|
"NO_CONTENT": "لم يتم العثور على محتوى",
|
||||||
"HIDE_QUOTED_TEXT": "Hide Quoted Text",
|
"HIDE_QUOTED_TEXT": "Hide Quoted Text",
|
||||||
|
|||||||
@ -214,7 +214,7 @@
|
|||||||
"CONVERSATION_INFO": "معلومات المحادثة",
|
"CONVERSATION_INFO": "معلومات المحادثة",
|
||||||
"CONTACT_ATTRIBUTES": "سمات جهة الاتصال",
|
"CONTACT_ATTRIBUTES": "سمات جهة الاتصال",
|
||||||
"PREVIOUS_CONVERSATION": "المحادثات السابقة",
|
"PREVIOUS_CONVERSATION": "المحادثات السابقة",
|
||||||
"MACROS": "Macros"
|
"MACROS": "ماكروس"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"CONVERSATION_CUSTOM_ATTRIBUTES": {
|
"CONVERSATION_CUSTOM_ATTRIBUTES": {
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"EMOJI": {
|
"EMOJI": {
|
||||||
"PLACEHOLDER": "Search emojis",
|
"PLACEHOLDER": "ابحث في الايموجي",
|
||||||
"NOT_FOUND": "No emoji match your search"
|
"NOT_FOUND": "لا يوجد إيموجي يطابق بحثك"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,7 @@
|
|||||||
"ERROR": "الرجاء إدخال اسم حساب صحيح"
|
"ERROR": "الرجاء إدخال اسم حساب صحيح"
|
||||||
},
|
},
|
||||||
"LANGUAGE": {
|
"LANGUAGE": {
|
||||||
"LABEL": "Site language",
|
"LABEL": "لغة الموقع",
|
||||||
"PLACEHOLDER": "اسم الحساب الخاص بك",
|
"PLACEHOLDER": "اسم الحساب الخاص بك",
|
||||||
"ERROR": ""
|
"ERROR": ""
|
||||||
},
|
},
|
||||||
@ -55,7 +55,7 @@
|
|||||||
"ENTER_TO_SELECT": "اضغط على زر الإدخال للاختيار",
|
"ENTER_TO_SELECT": "اضغط على زر الإدخال للاختيار",
|
||||||
"ENTER_TO_REMOVE": "اضغط على زر الإدخال للحذف",
|
"ENTER_TO_REMOVE": "اضغط على زر الإدخال للحذف",
|
||||||
"SELECT_ONE": "اختر واحدا",
|
"SELECT_ONE": "اختر واحدا",
|
||||||
"SELECT": "Select"
|
"SELECT": "اختر"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"NOTIFICATIONS_PAGE": {
|
"NOTIFICATIONS_PAGE": {
|
||||||
@ -139,6 +139,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DASHBOARD_APPS": {
|
"DASHBOARD_APPS": {
|
||||||
"LOADING_MESSAGE": "Loading Dashboard App..."
|
"LOADING_MESSAGE": "تحميل تطبيق لوحة التحكم..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,6 +53,10 @@
|
|||||||
"ENABLE": "إنشاء محادثات من التغريدات المشار إليها"
|
"ENABLE": "إنشاء محادثات من التغريدات المشار إليها"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"MICROSOFT": {
|
||||||
|
"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"
|
||||||
|
},
|
||||||
"WEBSITE_CHANNEL": {
|
"WEBSITE_CHANNEL": {
|
||||||
"TITLE": "قناة الموقع",
|
"TITLE": "قناة الموقع",
|
||||||
"DESC": "قم بإنشاء قناة تواصل لموقع الويب الخاص بك وابدأ في استقبال الرسائل من عملائك عبر صندوق الدردشة المباشرة.",
|
"DESC": "قم بإنشاء قناة تواصل لموقع الويب الخاص بك وابدأ في استقبال الرسائل من عملائك عبر صندوق الدردشة المباشرة.",
|
||||||
@ -134,7 +138,7 @@
|
|||||||
"PHONE_NUMBER": {
|
"PHONE_NUMBER": {
|
||||||
"LABEL": "رقم الهاتف",
|
"LABEL": "رقم الهاتف",
|
||||||
"PLACEHOLDER": "الرجاء إدخال رقم الهاتف الذي سيتم إرسال الرسائل منه.",
|
"PLACEHOLDER": "الرجاء إدخال رقم الهاتف الذي سيتم إرسال الرسائل منه.",
|
||||||
"ERROR": "Please provide a valid phone number that starts with a `+` sign and does not contain any spaces."
|
"ERROR": "الرجاء تقديم رقم هاتف صالح يبدأ بإشارة '+' ولا يحتوي على أي مسافات."
|
||||||
},
|
},
|
||||||
"API_CALLBACK": {
|
"API_CALLBACK": {
|
||||||
"TITLE": "عنوان Callback URL",
|
"TITLE": "عنوان Callback URL",
|
||||||
@ -185,7 +189,7 @@
|
|||||||
"PHONE_NUMBER": {
|
"PHONE_NUMBER": {
|
||||||
"LABEL": "رقم الهاتف",
|
"LABEL": "رقم الهاتف",
|
||||||
"PLACEHOLDER": "الرجاء إدخال رقم الهاتف الذي سيتم إرسال الرسائل منه.",
|
"PLACEHOLDER": "الرجاء إدخال رقم الهاتف الذي سيتم إرسال الرسائل منه.",
|
||||||
"ERROR": "Please provide a valid phone number that starts with a `+` sign and does not contain any spaces."
|
"ERROR": "الرجاء تقديم رقم هاتف صالح يبدأ بإشارة '+' ولا يحتوي على أي مسافات."
|
||||||
},
|
},
|
||||||
"SUBMIT_BUTTON": "إنشاء قناة عرض التردد",
|
"SUBMIT_BUTTON": "إنشاء قناة عرض التردد",
|
||||||
"API": {
|
"API": {
|
||||||
@ -214,7 +218,7 @@
|
|||||||
"PHONE_NUMBER": {
|
"PHONE_NUMBER": {
|
||||||
"LABEL": "رقم الهاتف",
|
"LABEL": "رقم الهاتف",
|
||||||
"PLACEHOLDER": "الرجاء إدخال رقم الهاتف الذي سيتم إرسال الرسائل منه.",
|
"PLACEHOLDER": "الرجاء إدخال رقم الهاتف الذي سيتم إرسال الرسائل منه.",
|
||||||
"ERROR": "Please provide a valid phone number that starts with a `+` sign and does not contain any spaces."
|
"ERROR": "الرجاء تقديم رقم هاتف صالح يبدأ بإشارة '+' ولا يحتوي على أي مسافات."
|
||||||
},
|
},
|
||||||
"PHONE_NUMBER_ID": {
|
"PHONE_NUMBER_ID": {
|
||||||
"LABEL": "رقم الهاتف",
|
"LABEL": "رقم الهاتف",
|
||||||
@ -239,9 +243,9 @@
|
|||||||
},
|
},
|
||||||
"API_CALLBACK": {
|
"API_CALLBACK": {
|
||||||
"TITLE": "عنوان Callback URL",
|
"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.",
|
"SUBTITLE": "يجب عليك تكوين رابط الويب هوك و رمز التحقق في بوابة مطور الفيسبوك مع القيم الموضحة أدناه.",
|
||||||
"WEBHOOK_URL": "رابط Webhook",
|
"WEBHOOK_URL": "رابط Webhook",
|
||||||
"WEBHOOK_VERIFICATION_TOKEN": "Webhook Verification Token"
|
"WEBHOOK_VERIFICATION_TOKEN": "رمز التحقق من Webhook"
|
||||||
},
|
},
|
||||||
"SUBMIT_BUTTON": "إنشاء قناة واتساب",
|
"SUBMIT_BUTTON": "إنشاء قناة واتساب",
|
||||||
"API": {
|
"API": {
|
||||||
@ -421,7 +425,7 @@
|
|||||||
"PRE_CHAT_FORM": "نموذج ما قبل الدردشة",
|
"PRE_CHAT_FORM": "نموذج ما قبل الدردشة",
|
||||||
"BUSINESS_HOURS": "ساعات العمل",
|
"BUSINESS_HOURS": "ساعات العمل",
|
||||||
"WIDGET_BUILDER": "منشئ اللايف شات",
|
"WIDGET_BUILDER": "منشئ اللايف شات",
|
||||||
"BOT_CONFIGURATION": "Bot Configuration"
|
"BOT_CONFIGURATION": "اعدادات البوت"
|
||||||
},
|
},
|
||||||
"SETTINGS": "الإعدادات",
|
"SETTINGS": "الإعدادات",
|
||||||
"FEATURES": {
|
"FEATURES": {
|
||||||
@ -445,8 +449,8 @@
|
|||||||
"ENABLE_CSAT_SUB_TEXT": "تمكين/تعطيل تقييم خدمة العملاء بعد إنتهاء المحادثة",
|
"ENABLE_CSAT_SUB_TEXT": "تمكين/تعطيل تقييم خدمة العملاء بعد إنتهاء المحادثة",
|
||||||
"ENABLE_CONTINUITY_VIA_EMAIL": "تمكين استمرارية المحادثة عبر البريد الإلكتروني",
|
"ENABLE_CONTINUITY_VIA_EMAIL": "تمكين استمرارية المحادثة عبر البريد الإلكتروني",
|
||||||
"ENABLE_CONTINUITY_VIA_EMAIL_SUB_TEXT": "المحادثات ستستمر عبر البريد الإلكتروني إذا كان عنوان البريد الإلكتروني لجهة الاتصال متاحاً.",
|
"ENABLE_CONTINUITY_VIA_EMAIL_SUB_TEXT": "المحادثات ستستمر عبر البريد الإلكتروني إذا كان عنوان البريد الإلكتروني لجهة الاتصال متاحاً.",
|
||||||
"LOCK_TO_SINGLE_CONVERSATION": "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",
|
"LOCK_TO_SINGLE_CONVERSATION_SUB_TEXT": "تمكين أو تعطيل محادثات متعددة لنفس جهة الاتصال في هذا البريد الوارد",
|
||||||
"INBOX_UPDATE_TITLE": "إعدادات قناة التواصل",
|
"INBOX_UPDATE_TITLE": "إعدادات قناة التواصل",
|
||||||
"INBOX_UPDATE_SUB_TEXT": "تحديث إعدادات قناة التواصل",
|
"INBOX_UPDATE_SUB_TEXT": "تحديث إعدادات قناة التواصل",
|
||||||
"AUTO_ASSIGNMENT_SUB_TEXT": "تمكين أو تعطيل الإسناد التلقائي للمحادثات الجديدة إلى الموظفين المضافين إلى قناة التواصل هذه.",
|
"AUTO_ASSIGNMENT_SUB_TEXT": "تمكين أو تعطيل الإسناد التلقائي للمحادثات الجديدة إلى الموظفين المضافين إلى قناة التواصل هذه.",
|
||||||
@ -548,6 +552,10 @@
|
|||||||
},
|
},
|
||||||
"ENABLE_SSL": "تمكين SSL"
|
"ENABLE_SSL": "تمكين SSL"
|
||||||
},
|
},
|
||||||
|
"MICROSOFT": {
|
||||||
|
"TITLE": "Microsoft",
|
||||||
|
"SUBTITLE": "Reauthorize your MICROSOFT account"
|
||||||
|
},
|
||||||
"SMTP": {
|
"SMTP": {
|
||||||
"TITLE": "SMTP",
|
"TITLE": "SMTP",
|
||||||
"SUBTITLE": "تعيين تفاصيل IMAP الخاصة بك",
|
"SUBTITLE": "تعيين تفاصيل IMAP الخاصة بك",
|
||||||
|
|||||||
@ -76,6 +76,13 @@
|
|||||||
"BODY": "<br/><p>ستتم الآن مزامنة جميع المحادثات الواردة إلى <b><i>محادثة الزبائن</i></b> داخل مكان العمل الخاص بك.</p><p>الرد على موضوع محادثة في <b><i>محادثة العملاء</i></b> قناة الركود سوف تقوم بإنشاء رد على العميل من خلال المحادثة.</p><p>ابدأ الردود ب <b><i>ملاحظة:</i></b> لإنشاء ملاحظات خاصة بدلاً من الردود.</p><p>إذا كان للرد على slack ملف تعريف الوكيل في الدردشة تحت نفس البريد الإلكتروني، فسيتم ربط الردود وفقا لذلك.</p><p>عندما لا يكون للرد ملف شخصي للوكيل المرتبط، ستتم الردود من ملف بوت الشخصي.</p>"
|
"BODY": "<br/><p>ستتم الآن مزامنة جميع المحادثات الواردة إلى <b><i>محادثة الزبائن</i></b> داخل مكان العمل الخاص بك.</p><p>الرد على موضوع محادثة في <b><i>محادثة العملاء</i></b> قناة الركود سوف تقوم بإنشاء رد على العميل من خلال المحادثة.</p><p>ابدأ الردود ب <b><i>ملاحظة:</i></b> لإنشاء ملاحظات خاصة بدلاً من الردود.</p><p>إذا كان للرد على slack ملف تعريف الوكيل في الدردشة تحت نفس البريد الإلكتروني، فسيتم ربط الردود وفقا لذلك.</p><p>عندما لا يكون للرد ملف شخصي للوكيل المرتبط، ستتم الردود من ملف بوت الشخصي.</p>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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"
|
||||||
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
"BUTTON_TEXT": "حذف",
|
"BUTTON_TEXT": "حذف",
|
||||||
"API": {
|
"API": {
|
||||||
|
|||||||
@ -1,78 +1,78 @@
|
|||||||
{
|
{
|
||||||
"MACROS": {
|
"MACROS": {
|
||||||
"HEADER": "Macros",
|
"HEADER": "ماكروس",
|
||||||
"HEADER_BTN_TXT": "Add a new macro",
|
"HEADER_BTN_TXT": "إضافة ماكرو جديد",
|
||||||
"HEADER_BTN_TXT_SAVE": "Save macro",
|
"HEADER_BTN_TXT_SAVE": "حفظ الماكرو",
|
||||||
"LOADING": "Fetching macros",
|
"LOADING": "جاري جلب الماكروس",
|
||||||
"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>",
|
"SIDEBAR_TXT": "<p><b>الماكروس</b><p>الماكرو هو مجموعة من الإجراءات المحفوظة التي تساعد وكلاء خدمة العملاء على إكمال المهام بسهولة. يمكن للوكلاء تحديد مجموعة من الإجراءات مثل وضع علامة على محادثة مع تسمية، وإرسال نص بريد إلكتروني، وتحديث سمة مخصصة، إلخ. ويمكنهم تنفيذ هذه الإجراءات بنقرة واحدة. وعندما يدير الوكلاء الكلية، يتم تنفيذ الإجراءات بالتسلسل حسب الترتيب الذي تحدده. يحسن الماكرو الإنتاجية ويزيد الاتساق في الإجراءات. </p><p>يمكن أن يكون الماكرو مفيداً بطريقتين. </p><p><b>كوكيل يساعد:</b> إذا قام وكيل بمجموعة من الإجراءات عدة مرات، يمكنهم حفظه كماكلي وتنفيذ جميع الإجراءات معاً باستخدام نقرة واحدة.</p><p><b>كخيار للدخول إلى عضوية الفريق:</b> يجب على كل وكيل إجراء العديد من الشيكات والإجراءات المختلفة خلال كل محادثة. سيكون عضو فريق الدعم الجديد من أونبواردينغ سهلا إذا كان الماكرو المحدد مسبقا متاحا على الحساب. وبدلا من وصف كل خطوة بالتفصيل، يمكن للمدير/الفريق أن يشير إلى الكتلة الكلية المستخدمة في سيناريوهات مختلفة.</p>",
|
||||||
"ERROR": "Something went wrong. Please try again",
|
"ERROR": "حدث خطأ ما. الرجاء المحاولة مرة أخرى",
|
||||||
"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.",
|
"ORDER_INFO": "سيتم تشغيل الماكرو بالترتيب الذي تضيفه إجراءاتك. يمكنك إعادة ترتيبهم بسحبهم بواسطة المعالج بجانب كل عقدة.",
|
||||||
"ADD": {
|
"ADD": {
|
||||||
"FORM": {
|
"FORM": {
|
||||||
"NAME": {
|
"NAME": {
|
||||||
"LABEL": "Macro name",
|
"LABEL": "اسم الماكرو",
|
||||||
"PLACEHOLDER": "Enter a name for your macro",
|
"PLACEHOLDER": "أدخل اسم الماكرو الخاص بك",
|
||||||
"ERROR": "Name is required for creating a macro"
|
"ERROR": "الاسم مطلوب لإنشاء الماكرو"
|
||||||
},
|
},
|
||||||
"ACTIONS": {
|
"ACTIONS": {
|
||||||
"LABEL": "الإجراءات"
|
"LABEL": "الإجراءات"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"SUCCESS_MESSAGE": "Macro added successfully",
|
"SUCCESS_MESSAGE": "تمت إضافة الماكرو بنجاح",
|
||||||
"ERROR_MESSAGE": "Unable to create macro, Please try again later"
|
"ERROR_MESSAGE": "غير قادر على إنشاء الماكرو ، الرجاء المحاولة مرة أخرى لاحقاً"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"LIST": {
|
"LIST": {
|
||||||
"TABLE_HEADER": [
|
"TABLE_HEADER": [
|
||||||
"الاسم",
|
"الاسم",
|
||||||
"Created by",
|
"تم إنشاؤها بواسطة",
|
||||||
"Last updated by",
|
"آخر تحديث بواسطة",
|
||||||
"Visibility"
|
"الظهور"
|
||||||
],
|
],
|
||||||
"404": "No macros found"
|
"404": "لم يتم العثور على الماكروس"
|
||||||
},
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
"TOOLTIP": "Delete macro",
|
"TOOLTIP": "حذف الماكرو",
|
||||||
"CONFIRM": {
|
"CONFIRM": {
|
||||||
"MESSAGE": "هل أنت متأكد من الحذف ",
|
"MESSAGE": "هل أنت متأكد من الحذف ",
|
||||||
"YES": "نعم، احذف",
|
"YES": "نعم، احذف",
|
||||||
"NO": "لا"
|
"NO": "لا"
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"SUCCESS_MESSAGE": "Macro deleted successfully",
|
"SUCCESS_MESSAGE": "تم حذف الماكرو بنجاح",
|
||||||
"ERROR_MESSAGE": "There was an error deleting the macro. Please try again later"
|
"ERROR_MESSAGE": "حدث خطأ أثناء حذف الماكرو. الرجاء المحاولة مرة أخرى في وقت لاحق"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"EDIT": {
|
"EDIT": {
|
||||||
"TOOLTIP": "Edit macro",
|
"TOOLTIP": "تعديل الماكرو",
|
||||||
"API": {
|
"API": {
|
||||||
"SUCCESS_MESSAGE": "Macro updated successfully",
|
"SUCCESS_MESSAGE": "تم تحديث الماكرو بنجاح",
|
||||||
"ERROR_MESSAGE": "Could not update Macro, Please try again later"
|
"ERROR_MESSAGE": "تعذر تحديث الماكرو ، الرجاء المحاولة مرة أخرى لاحقاً"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"EDITOR": {
|
"EDITOR": {
|
||||||
"START_FLOW": "Start Flow",
|
"START_FLOW": "بداية الإجرائات",
|
||||||
"END_FLOW": "End Flow",
|
"END_FLOW": "نهاية الإجرائات",
|
||||||
"LOADING": "Fetching macro",
|
"LOADING": "جاري جلب الماكروس",
|
||||||
"ADD_BTN_TOOLTIP": "Add new action",
|
"ADD_BTN_TOOLTIP": "إضافة إجراء جديد",
|
||||||
"DELETE_BTN_TOOLTIP": "Delete Action",
|
"DELETE_BTN_TOOLTIP": "حذف الإجراء",
|
||||||
"VISIBILITY": {
|
"VISIBILITY": {
|
||||||
"LABEL": "Macro Visibility",
|
"LABEL": "الرؤية الخاصة بالماكرو",
|
||||||
"GLOBAL": {
|
"GLOBAL": {
|
||||||
"LABEL": "Public",
|
"LABEL": "عامة",
|
||||||
"DESCRIPTION": "This macro is available publicly for all agents in this account."
|
"DESCRIPTION": "هذا الماكرو متاح بشكل عام لجميع الوكلاء في هذا الحساب."
|
||||||
},
|
},
|
||||||
"PERSONAL": {
|
"PERSONAL": {
|
||||||
"LABEL": "Private",
|
"LABEL": "خاص",
|
||||||
"DESCRIPTION": "This macro will be private to you and not be available to others."
|
"DESCRIPTION": "هذا الماكرو سيكون خاصا لك ولن يكون متاحا للآخرين."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"EXECUTE": {
|
"EXECUTE": {
|
||||||
"BUTTON_TOOLTIP": "Execute",
|
"BUTTON_TOOLTIP": "تنفيذ",
|
||||||
"PREVIEW": "Preview Macro",
|
"PREVIEW": "معاينة الماكرو",
|
||||||
"EXECUTED_SUCCESSFULLY": "Macro executed successfully"
|
"EXECUTED_SUCCESSFULLY": "تم تنفيذ الماكرو بنجاح"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -59,18 +59,18 @@
|
|||||||
"TITLE": "الإشعارات الصوتية",
|
"TITLE": "الإشعارات الصوتية",
|
||||||
"NOTE": "تمكين التنبيهات الصوتية في لوحة التحكم للرسائل والمحادثات الجديدة.",
|
"NOTE": "تمكين التنبيهات الصوتية في لوحة التحكم للرسائل والمحادثات الجديدة.",
|
||||||
"ALERT_TYPE": {
|
"ALERT_TYPE": {
|
||||||
"TITLE": "Alert events:",
|
"TITLE": "أحداث التنبيه:",
|
||||||
"NONE": "لا شيء",
|
"NONE": "لا شيء",
|
||||||
"ASSIGNED": "المحادثات المسندة",
|
"ASSIGNED": "المحادثات المسندة",
|
||||||
"ALL_CONVERSATIONS": "كل المحادثات"
|
"ALL_CONVERSATIONS": "كل المحادثات"
|
||||||
},
|
},
|
||||||
"DEFAULT_TONE": {
|
"DEFAULT_TONE": {
|
||||||
"TITLE": "Alert tone:"
|
"TITLE": "نغمة التنبيه:"
|
||||||
},
|
},
|
||||||
"CONDITIONS": {
|
"CONDITIONS": {
|
||||||
"TITLE": "Alert conditions:",
|
"TITLE": "شروط التنبيه:",
|
||||||
"CONDITION_ONE": "Send audio alerts only if the browser window is not active",
|
"CONDITION_ONE": "إرسال تنبيهات صوتية فقط إذا كانت نافذة المتصفح غير نشطة",
|
||||||
"CONDITION_TWO": "Send alerts every 30s until all the assigned conversations are read"
|
"CONDITION_TWO": "إرسال تنبيهات كل 30 ثانية حتى يتم قراءة جميع المحادثات المعينة"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"EMAIL_NOTIFICATIONS_SECTION": {
|
"EMAIL_NOTIFICATIONS_SECTION": {
|
||||||
@ -115,8 +115,8 @@
|
|||||||
"مشغول",
|
"مشغول",
|
||||||
"غير متصل"
|
"غير متصل"
|
||||||
],
|
],
|
||||||
"SET_AVAILABILITY_SUCCESS": "Availability has been set successfully",
|
"SET_AVAILABILITY_SUCCESS": "تم تعيين التوافر بنجاح",
|
||||||
"SET_AVAILABILITY_ERROR": "Couldn't set availability, please try again"
|
"SET_AVAILABILITY_ERROR": "تعذر تعيين التوافر، الرجاء المحاولة مرة أخرى"
|
||||||
},
|
},
|
||||||
"EMAIL": {
|
"EMAIL": {
|
||||||
"LABEL": "عنوان البريد الإلكتروني الخاص بك",
|
"LABEL": "عنوان البريد الإلكتروني الخاص بك",
|
||||||
@ -147,7 +147,7 @@
|
|||||||
"SELECTOR_SUBTITLE": "اختر حساباً من القائمة التالية",
|
"SELECTOR_SUBTITLE": "اختر حساباً من القائمة التالية",
|
||||||
"PROFILE_SETTINGS": "إعدادات الملف الشخصي",
|
"PROFILE_SETTINGS": "إعدادات الملف الشخصي",
|
||||||
"KEYBOARD_SHORTCUTS": "اختصارات لوحة المفاتيح",
|
"KEYBOARD_SHORTCUTS": "اختصارات لوحة المفاتيح",
|
||||||
"SUPER_ADMIN_CONSOLE": "Super Admin Console",
|
"SUPER_ADMIN_CONSOLE": "وحدة تحكم المدير المتميز",
|
||||||
"LOGOUT": "تسجيل الخروج"
|
"LOGOUT": "تسجيل الخروج"
|
||||||
},
|
},
|
||||||
"APP_GLOBAL": {
|
"APP_GLOBAL": {
|
||||||
@ -173,7 +173,7 @@
|
|||||||
"UPLOADING": "جاري الرفع..."
|
"UPLOADING": "جاري الرفع..."
|
||||||
},
|
},
|
||||||
"LOCATION_BUBBLE": {
|
"LOCATION_BUBBLE": {
|
||||||
"SEE_ON_MAP": "See on map"
|
"SEE_ON_MAP": "مشاهدة على الخريطة"
|
||||||
},
|
},
|
||||||
"FORM_BUBBLE": {
|
"FORM_BUBBLE": {
|
||||||
"SUBMIT": "إرسال"
|
"SUBMIT": "إرسال"
|
||||||
@ -197,7 +197,7 @@
|
|||||||
"CONTACTS": "جهات الاتصال",
|
"CONTACTS": "جهات الاتصال",
|
||||||
"HOME": "الرئيسية",
|
"HOME": "الرئيسية",
|
||||||
"AGENTS": "موظف الدعم",
|
"AGENTS": "موظف الدعم",
|
||||||
"AGENT_BOTS": "Bots",
|
"AGENT_BOTS": "البوتات",
|
||||||
"INBOXES": "قنوات التواصل",
|
"INBOXES": "قنوات التواصل",
|
||||||
"NOTIFICATIONS": "الإشعارات",
|
"NOTIFICATIONS": "الإشعارات",
|
||||||
"CANNED_RESPONSES": "الردود السريعة",
|
"CANNED_RESPONSES": "الردود السريعة",
|
||||||
@ -208,7 +208,7 @@
|
|||||||
"LABELS": "الوسوم",
|
"LABELS": "الوسوم",
|
||||||
"CUSTOM_ATTRIBUTES": "سمات مخصصة",
|
"CUSTOM_ATTRIBUTES": "سمات مخصصة",
|
||||||
"AUTOMATION": "الأتمتة",
|
"AUTOMATION": "الأتمتة",
|
||||||
"MACROS": "Macros",
|
"MACROS": "ماكروس",
|
||||||
"TEAMS": "الفرق",
|
"TEAMS": "الفرق",
|
||||||
"BILLING": "الفواتير",
|
"BILLING": "الفواتير",
|
||||||
"CUSTOM_VIEWS_FOLDER": "المجلدات",
|
"CUSTOM_VIEWS_FOLDER": "المجلدات",
|
||||||
@ -241,8 +241,8 @@
|
|||||||
"CATEGORY_EMPTY_MESSAGE": "لم يتم العثور على فئات"
|
"CATEGORY_EMPTY_MESSAGE": "لم يتم العثور على فئات"
|
||||||
},
|
},
|
||||||
"SET_AUTO_OFFLINE": {
|
"SET_AUTO_OFFLINE": {
|
||||||
"TEXT": "Mark offline automatically",
|
"TEXT": "وضع علامة غير متصل تلقائيا",
|
||||||
"INFO_TEXT": "Let the system automatically mark you offline when you aren't using the app or dashboard."
|
"INFO_TEXT": "السماح للنظام بوضع علامة غير متصل أوتوماتيكياً عندما لا تستخدم التطبيق أو لوحة التحكم."
|
||||||
},
|
},
|
||||||
"DOCS": "قراءة المستندات"
|
"DOCS": "قراءة المستندات"
|
||||||
},
|
},
|
||||||
@ -282,6 +282,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"KEYBOARD_SHORTCUTS": {
|
"KEYBOARD_SHORTCUTS": {
|
||||||
|
"TOGGLE_MODAL": "عرض جميع الاختصارات",
|
||||||
"TITLE": {
|
"TITLE": {
|
||||||
"OPEN_CONVERSATION": "فتح المحادثة",
|
"OPEN_CONVERSATION": "فتح المحادثة",
|
||||||
"RESOLVE_AND_NEXT": "حل وانتقل إلى التالي",
|
"RESOLVE_AND_NEXT": "حل وانتقل إلى التالي",
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
"REGISTER": {
|
"REGISTER": {
|
||||||
"TRY_WOOT": "تسجيل حساب",
|
"TRY_WOOT": "تسجيل حساب",
|
||||||
"TITLE": "تسجيل",
|
"TITLE": "تسجيل",
|
||||||
"TESTIMONIAL_HEADER": "All it takes is one step to move forward",
|
"TESTIMONIAL_HEADER": "إن كل ما يلزم هو خطوة واحدة للمضي قدما",
|
||||||
"TESTIMONIAL_CONTENT": "You're one step away from engaging your customers, retaining them and finding new ones.",
|
"TESTIMONIAL_CONTENT": "You're one step away from engaging your customers, retaining them and finding new ones.",
|
||||||
"TERMS_ACCEPT": "من خلال التسجيل، فإنك توافق على <a href=\"https://www.chatwoot.com/terms\">شروط الخدمة</a> و <a href=\"https://www.chatwoot.com/privacy-policy\">سياسة الخصوصية</a>",
|
"TERMS_ACCEPT": "من خلال التسجيل، فإنك توافق على <a href=\"https://www.chatwoot.com/terms\">شروط الخدمة</a> و <a href=\"https://www.chatwoot.com/privacy-policy\">سياسة الخصوصية</a>",
|
||||||
"COMPANY_NAME": {
|
"COMPANY_NAME": {
|
||||||
|
|||||||
@ -24,8 +24,11 @@
|
|||||||
"TITLE": "Select an agent bot",
|
"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.",
|
"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": "Обновяване",
|
"SUBMIT": "Обновяване",
|
||||||
|
"DISCONNECT": "Disconnect Bot",
|
||||||
"SUCCESS_MESSAGE": "Successfully updated the agent 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",
|
"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"
|
"SELECT_PLACEHOLDER": "Select Bot"
|
||||||
},
|
},
|
||||||
"ADD": {
|
"ADD": {
|
||||||
|
|||||||
@ -42,8 +42,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"SUCCESS_MESSAGE": "Custom Attribute added successfully",
|
"SUCCESS_MESSAGE": "Custom Attribute added successfully!",
|
||||||
"ERROR_MESSAGE": "Could not able to create a custom attribute, Please try again later"
|
"ERROR_MESSAGE": "Could not create a Custom Attribute. Please try again later."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
|
|||||||
@ -53,6 +53,10 @@
|
|||||||
"ENABLE": "Create conversations from mentioned Tweets"
|
"ENABLE": "Create conversations from mentioned Tweets"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"MICROSOFT": {
|
||||||
|
"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"
|
||||||
|
},
|
||||||
"WEBSITE_CHANNEL": {
|
"WEBSITE_CHANNEL": {
|
||||||
"TITLE": "Website channel",
|
"TITLE": "Website channel",
|
||||||
"DESC": "Create a channel for your website and start supporting your customers via our website widget.",
|
"DESC": "Create a channel for your website and start supporting your customers via our website widget.",
|
||||||
@ -548,6 +552,10 @@
|
|||||||
},
|
},
|
||||||
"ENABLE_SSL": "Enable SSL"
|
"ENABLE_SSL": "Enable SSL"
|
||||||
},
|
},
|
||||||
|
"MICROSOFT": {
|
||||||
|
"TITLE": "Microsoft",
|
||||||
|
"SUBTITLE": "Reauthorize your MICROSOFT account"
|
||||||
|
},
|
||||||
"SMTP": {
|
"SMTP": {
|
||||||
"TITLE": "SMTP",
|
"TITLE": "SMTP",
|
||||||
"SUBTITLE": "Set your SMTP details",
|
"SUBTITLE": "Set your SMTP details",
|
||||||
|
|||||||
@ -76,6 +76,13 @@
|
|||||||
"BODY": "<br/><p>Chatwoot will now sync all the incoming conversations into the <b><i>customer-conversations</i></b> channel inside your slack workplace.</p><p>Replying to a conversation thread in <b><i>customer-conversations</i></b> slack channel will create a response back to the customer through chatwoot.</p><p>Start the replies with <b><i>note:</i></b> to create private notes instead of replies.</p><p>If the replier on slack has an agent profile in chatwoot under the same email, the replies will be associated accordingly.</p><p>When the replier doesn't have an associated agent profile, the replies will be made from the bot profile.</p>"
|
"BODY": "<br/><p>Chatwoot will now sync all the incoming conversations into the <b><i>customer-conversations</i></b> channel inside your slack workplace.</p><p>Replying to a conversation thread in <b><i>customer-conversations</i></b> slack channel will create a response back to the customer through chatwoot.</p><p>Start the replies with <b><i>note:</i></b> to create private notes instead of replies.</p><p>If the replier on slack has an agent profile in chatwoot under the same email, the replies will be associated accordingly.</p><p>When the replier doesn't have an associated agent profile, the replies will be made from the bot profile.</p>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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"
|
||||||
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
"BUTTON_TEXT": "Изтрий",
|
"BUTTON_TEXT": "Изтрий",
|
||||||
"API": {
|
"API": {
|
||||||
|
|||||||
@ -282,6 +282,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"KEYBOARD_SHORTCUTS": {
|
"KEYBOARD_SHORTCUTS": {
|
||||||
|
"TOGGLE_MODAL": "View all shortcuts",
|
||||||
"TITLE": {
|
"TITLE": {
|
||||||
"OPEN_CONVERSATION": "Open conversation",
|
"OPEN_CONVERSATION": "Open conversation",
|
||||||
"RESOLVE_AND_NEXT": "Resolve and move to next",
|
"RESOLVE_AND_NEXT": "Resolve and move to next",
|
||||||
|
|||||||
@ -24,8 +24,11 @@
|
|||||||
"TITLE": "Select an agent bot",
|
"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.",
|
"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": "Actualitza",
|
"SUBMIT": "Actualitza",
|
||||||
|
"DISCONNECT": "Disconnect Bot",
|
||||||
"SUCCESS_MESSAGE": "Successfully updated the agent 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",
|
"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"
|
"SELECT_PLACEHOLDER": "Select Bot"
|
||||||
},
|
},
|
||||||
"ADD": {
|
"ADD": {
|
||||||
|
|||||||
@ -42,8 +42,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"SUCCESS_MESSAGE": "Custom Attribute added successfully",
|
"SUCCESS_MESSAGE": "Custom Attribute added successfully!",
|
||||||
"ERROR_MESSAGE": "Could not able to create a custom attribute, Please try again later"
|
"ERROR_MESSAGE": "Could not create a Custom Attribute. Please try again later."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
|
|||||||
@ -53,6 +53,10 @@
|
|||||||
"ENABLE": "Create conversations from mentioned Tweets"
|
"ENABLE": "Create conversations from mentioned Tweets"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"MICROSOFT": {
|
||||||
|
"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"
|
||||||
|
},
|
||||||
"WEBSITE_CHANNEL": {
|
"WEBSITE_CHANNEL": {
|
||||||
"TITLE": "Canal Web",
|
"TITLE": "Canal Web",
|
||||||
"DESC": "Crea un canal per al vostre lloc web i comença a donar suport als vostres clients mitjançant el teu widget del lloc web.",
|
"DESC": "Crea un canal per al vostre lloc web i comença a donar suport als vostres clients mitjançant el teu widget del lloc web.",
|
||||||
@ -548,6 +552,10 @@
|
|||||||
},
|
},
|
||||||
"ENABLE_SSL": "Enable SSL"
|
"ENABLE_SSL": "Enable SSL"
|
||||||
},
|
},
|
||||||
|
"MICROSOFT": {
|
||||||
|
"TITLE": "Microsoft",
|
||||||
|
"SUBTITLE": "Reauthorize your MICROSOFT account"
|
||||||
|
},
|
||||||
"SMTP": {
|
"SMTP": {
|
||||||
"TITLE": "SMTP",
|
"TITLE": "SMTP",
|
||||||
"SUBTITLE": "Set your SMTP details",
|
"SUBTITLE": "Set your SMTP details",
|
||||||
|
|||||||
@ -76,6 +76,13 @@
|
|||||||
"BODY": "<br/><p>Chatwoot will now sync all the incoming conversations into the <b><i>customer-conversations</i></b> channel inside your slack workplace.</p><p>Replying to a conversation thread in <b><i>customer-conversations</i></b> slack channel will create a response back to the customer through chatwoot.</p><p>Start the replies with <b><i>note:</i></b> to create private notes instead of replies.</p><p>If the replier on slack has an agent profile in chatwoot under the same email, the replies will be associated accordingly.</p><p>When the replier doesn't have an associated agent profile, the replies will be made from the bot profile.</p>"
|
"BODY": "<br/><p>Chatwoot will now sync all the incoming conversations into the <b><i>customer-conversations</i></b> channel inside your slack workplace.</p><p>Replying to a conversation thread in <b><i>customer-conversations</i></b> slack channel will create a response back to the customer through chatwoot.</p><p>Start the replies with <b><i>note:</i></b> to create private notes instead of replies.</p><p>If the replier on slack has an agent profile in chatwoot under the same email, the replies will be associated accordingly.</p><p>When the replier doesn't have an associated agent profile, the replies will be made from the bot profile.</p>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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"
|
||||||
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
"BUTTON_TEXT": "Suprimeix",
|
"BUTTON_TEXT": "Suprimeix",
|
||||||
"API": {
|
"API": {
|
||||||
|
|||||||
@ -282,6 +282,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"KEYBOARD_SHORTCUTS": {
|
"KEYBOARD_SHORTCUTS": {
|
||||||
|
"TOGGLE_MODAL": "View all shortcuts",
|
||||||
"TITLE": {
|
"TITLE": {
|
||||||
"OPEN_CONVERSATION": "Open conversation",
|
"OPEN_CONVERSATION": "Open conversation",
|
||||||
"RESOLVE_AND_NEXT": "Resolve and move to next",
|
"RESOLVE_AND_NEXT": "Resolve and move to next",
|
||||||
|
|||||||
@ -24,8 +24,11 @@
|
|||||||
"TITLE": "Select an agent bot",
|
"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.",
|
"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": "Aktualizovat",
|
"SUBMIT": "Aktualizovat",
|
||||||
|
"DISCONNECT": "Disconnect Bot",
|
||||||
"SUCCESS_MESSAGE": "Successfully updated the agent 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",
|
"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"
|
"SELECT_PLACEHOLDER": "Select Bot"
|
||||||
},
|
},
|
||||||
"ADD": {
|
"ADD": {
|
||||||
|
|||||||
@ -42,8 +42,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"SUCCESS_MESSAGE": "Custom Attribute added successfully",
|
"SUCCESS_MESSAGE": "Custom Attribute added successfully!",
|
||||||
"ERROR_MESSAGE": "Could not able to create a custom attribute, Please try again later"
|
"ERROR_MESSAGE": "Could not create a Custom Attribute. Please try again later."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
|
|||||||
@ -53,6 +53,10 @@
|
|||||||
"ENABLE": "Create conversations from mentioned Tweets"
|
"ENABLE": "Create conversations from mentioned Tweets"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"MICROSOFT": {
|
||||||
|
"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"
|
||||||
|
},
|
||||||
"WEBSITE_CHANNEL": {
|
"WEBSITE_CHANNEL": {
|
||||||
"TITLE": "Kanál webové stránky",
|
"TITLE": "Kanál webové stránky",
|
||||||
"DESC": "Vytvořte si kanál pro vaše webové stránky a začněte podporovat své zákazníky prostřednictvím našeho widgetu.",
|
"DESC": "Vytvořte si kanál pro vaše webové stránky a začněte podporovat své zákazníky prostřednictvím našeho widgetu.",
|
||||||
@ -548,6 +552,10 @@
|
|||||||
},
|
},
|
||||||
"ENABLE_SSL": "Enable SSL"
|
"ENABLE_SSL": "Enable SSL"
|
||||||
},
|
},
|
||||||
|
"MICROSOFT": {
|
||||||
|
"TITLE": "Microsoft",
|
||||||
|
"SUBTITLE": "Reauthorize your MICROSOFT account"
|
||||||
|
},
|
||||||
"SMTP": {
|
"SMTP": {
|
||||||
"TITLE": "SMTP",
|
"TITLE": "SMTP",
|
||||||
"SUBTITLE": "Set your SMTP details",
|
"SUBTITLE": "Set your SMTP details",
|
||||||
|
|||||||
@ -76,6 +76,13 @@
|
|||||||
"BODY": "<br/><p>Chatwoot will now sync all the incoming conversations into the <b><i>customer-conversations</i></b> channel inside your slack workplace.</p><p>Replying to a conversation thread in <b><i>customer-conversations</i></b> slack channel will create a response back to the customer through chatwoot.</p><p>Start the replies with <b><i>note:</i></b> to create private notes instead of replies.</p><p>If the replier on slack has an agent profile in chatwoot under the same email, the replies will be associated accordingly.</p><p>When the replier doesn't have an associated agent profile, the replies will be made from the bot profile.</p>"
|
"BODY": "<br/><p>Chatwoot will now sync all the incoming conversations into the <b><i>customer-conversations</i></b> channel inside your slack workplace.</p><p>Replying to a conversation thread in <b><i>customer-conversations</i></b> slack channel will create a response back to the customer through chatwoot.</p><p>Start the replies with <b><i>note:</i></b> to create private notes instead of replies.</p><p>If the replier on slack has an agent profile in chatwoot under the same email, the replies will be associated accordingly.</p><p>When the replier doesn't have an associated agent profile, the replies will be made from the bot profile.</p>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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"
|
||||||
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
"BUTTON_TEXT": "Vymazat",
|
"BUTTON_TEXT": "Vymazat",
|
||||||
"API": {
|
"API": {
|
||||||
|
|||||||
@ -282,6 +282,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"KEYBOARD_SHORTCUTS": {
|
"KEYBOARD_SHORTCUTS": {
|
||||||
|
"TOGGLE_MODAL": "View all shortcuts",
|
||||||
"TITLE": {
|
"TITLE": {
|
||||||
"OPEN_CONVERSATION": "Open conversation",
|
"OPEN_CONVERSATION": "Open conversation",
|
||||||
"RESOLVE_AND_NEXT": "Resolve and move to next",
|
"RESOLVE_AND_NEXT": "Resolve and move to next",
|
||||||
|
|||||||
@ -24,8 +24,11 @@
|
|||||||
"TITLE": "Select an agent bot",
|
"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.",
|
"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": "Opdater",
|
"SUBMIT": "Opdater",
|
||||||
|
"DISCONNECT": "Disconnect Bot",
|
||||||
"SUCCESS_MESSAGE": "Successfully updated the agent 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",
|
"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": "Vælg bot"
|
"SELECT_PLACEHOLDER": "Vælg bot"
|
||||||
},
|
},
|
||||||
"ADD": {
|
"ADD": {
|
||||||
|
|||||||
@ -42,8 +42,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"SUCCESS_MESSAGE": "Brugerdefineret attribut blev tilføjet",
|
"SUCCESS_MESSAGE": "Brugerdefineret attribut blev tilføjet!",
|
||||||
"ERROR_MESSAGE": "Kunne ikke oprette en brugerdefineret attribut. Prøv igen senere"
|
"ERROR_MESSAGE": "Could not create a Custom Attribute. Please try again later."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
|
|||||||
@ -217,14 +217,14 @@
|
|||||||
"DOMAIN": {
|
"DOMAIN": {
|
||||||
"LABEL": "Tilpasset Domæne",
|
"LABEL": "Tilpasset Domæne",
|
||||||
"PLACEHOLDER": "Portal brugerdefineret domæne",
|
"PLACEHOLDER": "Portal brugerdefineret domæne",
|
||||||
"HELP_TEXT": "Add only If you want to use a custom domain for your portals. Eg: https://example.com",
|
"HELP_TEXT": "Tilføj kun hvis du vil bruge et brugerdefineret domæne, til dine portaler. Eksempelvis https://example.com",
|
||||||
"ERROR": "Indtast et gyldigt domæne URL"
|
"ERROR": "Indtast et gyldigt domæne URL"
|
||||||
},
|
},
|
||||||
"HOME_PAGE_LINK": {
|
"HOME_PAGE_LINK": {
|
||||||
"LABEL": "Link Til Hjemmeside",
|
"LABEL": "Link Til Hjemmeside",
|
||||||
"PLACEHOLDER": "Link til portalens hjemmeside",
|
"PLACEHOLDER": "Link til portalens hjemmeside",
|
||||||
"HELP_TEXT": "The link used to return from the portal to the home page. Eg: https://example.com",
|
"HELP_TEXT": "The link used to return from the portal to the home page. Eg: https://example.com",
|
||||||
"ERROR": "Enter a valid home page URL"
|
"ERROR": "Indtast en gyldig URL til startsiden"
|
||||||
},
|
},
|
||||||
"THEME_COLOR": {
|
"THEME_COLOR": {
|
||||||
"LABEL": "Portal tema farve",
|
"LABEL": "Portal tema farve",
|
||||||
|
|||||||
@ -53,6 +53,10 @@
|
|||||||
"ENABLE": "Opret samtaler fra nævnte Tweets"
|
"ENABLE": "Opret samtaler fra nævnte Tweets"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"MICROSOFT": {
|
||||||
|
"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"
|
||||||
|
},
|
||||||
"WEBSITE_CHANNEL": {
|
"WEBSITE_CHANNEL": {
|
||||||
"TITLE": "Hjemmesidekanal",
|
"TITLE": "Hjemmesidekanal",
|
||||||
"DESC": "Opret en kanal til din hjemmeside og begynde at supporte dine kunder via vores hjemmeside widget.",
|
"DESC": "Opret en kanal til din hjemmeside og begynde at supporte dine kunder via vores hjemmeside widget.",
|
||||||
@ -548,6 +552,10 @@
|
|||||||
},
|
},
|
||||||
"ENABLE_SSL": "Aktiver SSL"
|
"ENABLE_SSL": "Aktiver SSL"
|
||||||
},
|
},
|
||||||
|
"MICROSOFT": {
|
||||||
|
"TITLE": "Microsoft",
|
||||||
|
"SUBTITLE": "Reauthorize your MICROSOFT account"
|
||||||
|
},
|
||||||
"SMTP": {
|
"SMTP": {
|
||||||
"TITLE": "Smtp",
|
"TITLE": "Smtp",
|
||||||
"SUBTITLE": "Indstil dine IMAP-oplysninger",
|
"SUBTITLE": "Indstil dine IMAP-oplysninger",
|
||||||
|
|||||||
@ -76,6 +76,13 @@
|
|||||||
"BODY": "<br/><p>Chatwoot vil nu synkronisere alle indgående samtaler ind i <b><i>kundesamtaler</i></b> kanalen i din slack arbejdsplads.</p><p>Svar på en samtaletråd i <b><i>kunde-samtaler</i></b> slack kanal vil skabe et svar tilbage til kunden gennem chatwoot.</p><p>Start svarene med <b><i>note:</i></b> for at oprette private noter i stedet for svar.</p><p>Hvis replikatoren på slack har en agentprofil i chatwoot under samme e-mail, vil svarene blive tilknyttet i overensstemmelse hermed.</p><p>Når replikatoren ikke har en tilknyttet agentprofil, vil svarene blive fremsat fra bot-profilen.</p>"
|
"BODY": "<br/><p>Chatwoot vil nu synkronisere alle indgående samtaler ind i <b><i>kundesamtaler</i></b> kanalen i din slack arbejdsplads.</p><p>Svar på en samtaletråd i <b><i>kunde-samtaler</i></b> slack kanal vil skabe et svar tilbage til kunden gennem chatwoot.</p><p>Start svarene med <b><i>note:</i></b> for at oprette private noter i stedet for svar.</p><p>Hvis replikatoren på slack har en agentprofil i chatwoot under samme e-mail, vil svarene blive tilknyttet i overensstemmelse hermed.</p><p>Når replikatoren ikke har en tilknyttet agentprofil, vil svarene blive fremsat fra bot-profilen.</p>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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"
|
||||||
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
"BUTTON_TEXT": "Slet",
|
"BUTTON_TEXT": "Slet",
|
||||||
"API": {
|
"API": {
|
||||||
|
|||||||
@ -282,6 +282,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"KEYBOARD_SHORTCUTS": {
|
"KEYBOARD_SHORTCUTS": {
|
||||||
|
"TOGGLE_MODAL": "View all shortcuts",
|
||||||
"TITLE": {
|
"TITLE": {
|
||||||
"OPEN_CONVERSATION": "Åbn samtale",
|
"OPEN_CONVERSATION": "Åbn samtale",
|
||||||
"RESOLVE_AND_NEXT": "Løs og flyt til næste",
|
"RESOLVE_AND_NEXT": "Løs og flyt til næste",
|
||||||
|
|||||||
@ -24,8 +24,11 @@
|
|||||||
"TITLE": "Agenten-Bot auswählen",
|
"TITLE": "Agenten-Bot auswählen",
|
||||||
"DESC": "Sie können einen Agenten-Bot aus der Liste in diesen Posteingang setzen. Der Bot kann die Unterhaltung anfangs bearbeiten und bei Bedarf an einen Agenten übertragen.",
|
"DESC": "Sie können einen Agenten-Bot aus der Liste in diesen Posteingang setzen. Der Bot kann die Unterhaltung anfangs bearbeiten und bei Bedarf an einen Agenten übertragen.",
|
||||||
"SUBMIT": "Aktualisieren",
|
"SUBMIT": "Aktualisieren",
|
||||||
|
"DISCONNECT": "Disconnect Bot",
|
||||||
"SUCCESS_MESSAGE": "Agenten-Bot erfolgreich aktualisiert",
|
"SUCCESS_MESSAGE": "Agenten-Bot erfolgreich aktualisiert",
|
||||||
|
"DISCONNECTED_SUCCESS_MESSAGE": "Successfully disconnected the agent bot",
|
||||||
"ERROR_MESSAGE": "Konnte den Agenten-Bot nicht aktualisieren, bitte versuchen Sie es später erneut",
|
"ERROR_MESSAGE": "Konnte den Agenten-Bot nicht aktualisieren, bitte versuchen Sie es später erneut",
|
||||||
|
"DISCONNECTED_ERROR_MESSAGE": "Could not disconnect the agent bot, please try again later",
|
||||||
"SELECT_PLACEHOLDER": "Bot auswählen"
|
"SELECT_PLACEHOLDER": "Bot auswählen"
|
||||||
},
|
},
|
||||||
"ADD": {
|
"ADD": {
|
||||||
@ -37,29 +40,29 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"LIST": {
|
"LIST": {
|
||||||
"404": "No Bots found, you can create a bot by clicking the 'Configure new bot' Button ↗",
|
"404": "Keine Bots gefunden, Sie können einen Bot erstellen, indem Sie auf den 'Neuen Bot konfigurieren' Button klicken ↗",
|
||||||
"LOADING": "Fetching Bots...",
|
"LOADING": "Bots werden geladen...",
|
||||||
"TYPE": "Bot Type"
|
"TYPE": "Bot-Typ"
|
||||||
},
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
"BUTTON_TEXT": "Löschen",
|
"BUTTON_TEXT": "Löschen",
|
||||||
"TITLE": "Delete Bot",
|
"TITLE": "Bot löschen",
|
||||||
"SUBMIT": "Löschen",
|
"SUBMIT": "Löschen",
|
||||||
"CANCEL_BUTTON_TEXT": "Stornieren",
|
"CANCEL_BUTTON_TEXT": "Stornieren",
|
||||||
"DESCRIPTION": "Are you sure you want to delete this bot? This action is irreversible",
|
"DESCRIPTION": "Sind Sie sicher, dass Sie diesen Bot löschen wollen? Diese Aktion kann nicht rückgängig gemacht werden",
|
||||||
"API": {
|
"API": {
|
||||||
"SUCCESS_MESSAGE": "Bot deleted successfully",
|
"SUCCESS_MESSAGE": "Bot erfolgreich gelöscht",
|
||||||
"ERROR_MESSAGE": "Could not able to delete bot, Please try again later"
|
"ERROR_MESSAGE": "Could not able to delete bot, Please try again later"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"EDIT": {
|
"EDIT": {
|
||||||
"BUTTON_TEXT": "Bearbeiten",
|
"BUTTON_TEXT": "Bearbeiten",
|
||||||
"LOADING": "Fetching Bots...",
|
"LOADING": "Bots werden geladen...",
|
||||||
"TITLE": "Edit Bot",
|
"TITLE": "Bot bearbeiten",
|
||||||
"CANCEL_BUTTON_TEXT": "Stornieren",
|
"CANCEL_BUTTON_TEXT": "Stornieren",
|
||||||
"API": {
|
"API": {
|
||||||
"SUCCESS_MESSAGE": "Bot updated successfully",
|
"SUCCESS_MESSAGE": "Bot erfolgreich aktualisiert",
|
||||||
"ERROR_MESSAGE": "Could not update bot, Please try again later"
|
"ERROR_MESSAGE": "Bot konnte nicht aktualisiert werden, bitte versuchen Sie es später erneut"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"TYPES": {
|
"TYPES": {
|
||||||
|
|||||||
@ -42,8 +42,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"SUCCESS_MESSAGE": "Benutzerdefiniertes Attribut erfolgreich hinzugefügt",
|
"SUCCESS_MESSAGE": "Benutzerdefiniertes Attribut erfolgreich hinzugefügt!",
|
||||||
"ERROR_MESSAGE": "Konnte kein benutzerdefiniertes Attribut erstellen. Bitte versuchen Sie es später erneut"
|
"ERROR_MESSAGE": "Could not create a Custom Attribute. Please try again later."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
|
|||||||
@ -23,7 +23,7 @@
|
|||||||
"ERROR": "Bitte geben Sie einen gültigen Kontonamen ein"
|
"ERROR": "Bitte geben Sie einen gültigen Kontonamen ein"
|
||||||
},
|
},
|
||||||
"LANGUAGE": {
|
"LANGUAGE": {
|
||||||
"LABEL": "Site language",
|
"LABEL": "Sprache",
|
||||||
"PLACEHOLDER": "Ihr Kontoname",
|
"PLACEHOLDER": "Ihr Kontoname",
|
||||||
"ERROR": ""
|
"ERROR": ""
|
||||||
},
|
},
|
||||||
@ -55,7 +55,7 @@
|
|||||||
"ENTER_TO_SELECT": "Drücken Sie zur Auswahl die Eingabetaste",
|
"ENTER_TO_SELECT": "Drücken Sie zur Auswahl die Eingabetaste",
|
||||||
"ENTER_TO_REMOVE": "Drücken Sie zum Entfernen die Eingabetaste",
|
"ENTER_TO_REMOVE": "Drücken Sie zum Entfernen die Eingabetaste",
|
||||||
"SELECT_ONE": "Eines wählen",
|
"SELECT_ONE": "Eines wählen",
|
||||||
"SELECT": "Select"
|
"SELECT": "Auswählen"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"NOTIFICATIONS_PAGE": {
|
"NOTIFICATIONS_PAGE": {
|
||||||
@ -139,6 +139,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DASHBOARD_APPS": {
|
"DASHBOARD_APPS": {
|
||||||
"LOADING_MESSAGE": "Loading Dashboard App..."
|
"LOADING_MESSAGE": "Dashboard-App wird geladen..."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -53,6 +53,10 @@
|
|||||||
"ENABLE": "Konversationen aus erwähnten Tweets erstellen"
|
"ENABLE": "Konversationen aus erwähnten Tweets erstellen"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"MICROSOFT": {
|
||||||
|
"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"
|
||||||
|
},
|
||||||
"WEBSITE_CHANNEL": {
|
"WEBSITE_CHANNEL": {
|
||||||
"TITLE": "Website-Kanal",
|
"TITLE": "Website-Kanal",
|
||||||
"DESC": "Erstellen Sie einen Kanal für Ihre Website und unterstützen Sie Ihre Kunden über unser Website-Widget.",
|
"DESC": "Erstellen Sie einen Kanal für Ihre Website und unterstützen Sie Ihre Kunden über unser Website-Widget.",
|
||||||
@ -134,7 +138,7 @@
|
|||||||
"PHONE_NUMBER": {
|
"PHONE_NUMBER": {
|
||||||
"LABEL": "Telefonnummer",
|
"LABEL": "Telefonnummer",
|
||||||
"PLACEHOLDER": "Bitte geben Sie die Telefonnummer ein, von der die Nachricht gesendet wird.",
|
"PLACEHOLDER": "Bitte geben Sie die Telefonnummer ein, von der die Nachricht gesendet wird.",
|
||||||
"ERROR": "Please provide a valid phone number that starts with a `+` sign and does not contain any spaces."
|
"ERROR": "Bitte geben Sie eine gültige Telefonnummer an, die mit einem `+` Zeichen beginnt und keine Leerzeichen enthält."
|
||||||
},
|
},
|
||||||
"API_CALLBACK": {
|
"API_CALLBACK": {
|
||||||
"TITLE": "Callback URL",
|
"TITLE": "Callback URL",
|
||||||
@ -185,7 +189,7 @@
|
|||||||
"PHONE_NUMBER": {
|
"PHONE_NUMBER": {
|
||||||
"LABEL": "Telefonnummer",
|
"LABEL": "Telefonnummer",
|
||||||
"PLACEHOLDER": "Bitte geben Sie die Telefonnummer ein, von der die Nachricht gesendet wird.",
|
"PLACEHOLDER": "Bitte geben Sie die Telefonnummer ein, von der die Nachricht gesendet wird.",
|
||||||
"ERROR": "Please provide a valid phone number that starts with a `+` sign and does not contain any spaces."
|
"ERROR": "Bitte geben Sie eine gültige Telefonnummer an, die mit einem `+` Zeichen beginnt und keine Leerzeichen enthält."
|
||||||
},
|
},
|
||||||
"SUBMIT_BUTTON": "Bitte geben Sie Ihre Bandbreitenanwendungs-ID ein",
|
"SUBMIT_BUTTON": "Bitte geben Sie Ihre Bandbreitenanwendungs-ID ein",
|
||||||
"API": {
|
"API": {
|
||||||
@ -214,7 +218,7 @@
|
|||||||
"PHONE_NUMBER": {
|
"PHONE_NUMBER": {
|
||||||
"LABEL": "Telefonnummer",
|
"LABEL": "Telefonnummer",
|
||||||
"PLACEHOLDER": "Bitte geben Sie die Telefonnummer ein, von der die Nachricht gesendet wird.",
|
"PLACEHOLDER": "Bitte geben Sie die Telefonnummer ein, von der die Nachricht gesendet wird.",
|
||||||
"ERROR": "Please provide a valid phone number that starts with a `+` sign and does not contain any spaces."
|
"ERROR": "Bitte geben Sie eine gültige Telefonnummer an, die mit einem `+` Zeichen beginnt und keine Leerzeichen enthält."
|
||||||
},
|
},
|
||||||
"PHONE_NUMBER_ID": {
|
"PHONE_NUMBER_ID": {
|
||||||
"LABEL": "Telefonnummer-ID",
|
"LABEL": "Telefonnummer-ID",
|
||||||
@ -548,6 +552,10 @@
|
|||||||
},
|
},
|
||||||
"ENABLE_SSL": "SSL aktivieren"
|
"ENABLE_SSL": "SSL aktivieren"
|
||||||
},
|
},
|
||||||
|
"MICROSOFT": {
|
||||||
|
"TITLE": "Microsoft",
|
||||||
|
"SUBTITLE": "Reauthorize your MICROSOFT account"
|
||||||
|
},
|
||||||
"SMTP": {
|
"SMTP": {
|
||||||
"TITLE": "SMTP",
|
"TITLE": "SMTP",
|
||||||
"SUBTITLE": "Setzen Sie Ihre SMTP-Details",
|
"SUBTITLE": "Setzen Sie Ihre SMTP-Details",
|
||||||
|
|||||||
@ -76,6 +76,13 @@
|
|||||||
"BODY": "<br/><p>Chatwoot wird nun alle eingehenden Konversationen in den <b><i>Kundengespräche</i></b> Channel innerhalb Ihres Slack Arbeitsplatzes synchronisieren.</p><p>Wenn Sie in <b><i>Kunden-Konversationen</i></b> antworten, wird der Slack Kanal eine Antwort an den Kunden durch Chat erzeugen.</p><p>Starten Sie die Antworten mit <b><i>Notiz:</i></b> um private Notizen anstatt Antworten zu erstellen.</p><p>Wenn der Replier auf Slack ein Agentenprofil im Chatwoot unter der gleichen E-Mail hat, werden die Antworten entsprechend assoziiert.</p><p>Wenn der Replier kein Agentenprofil hat, werden die Antworten aus dem Bot-Profil getätigt.</p>"
|
"BODY": "<br/><p>Chatwoot wird nun alle eingehenden Konversationen in den <b><i>Kundengespräche</i></b> Channel innerhalb Ihres Slack Arbeitsplatzes synchronisieren.</p><p>Wenn Sie in <b><i>Kunden-Konversationen</i></b> antworten, wird der Slack Kanal eine Antwort an den Kunden durch Chat erzeugen.</p><p>Starten Sie die Antworten mit <b><i>Notiz:</i></b> um private Notizen anstatt Antworten zu erstellen.</p><p>Wenn der Replier auf Slack ein Agentenprofil im Chatwoot unter der gleichen E-Mail hat, werden die Antworten entsprechend assoziiert.</p><p>Wenn der Replier kein Agentenprofil hat, werden die Antworten aus dem Bot-Profil getätigt.</p>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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"
|
||||||
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
"BUTTON_TEXT": "Löschen",
|
"BUTTON_TEXT": "Löschen",
|
||||||
"API": {
|
"API": {
|
||||||
|
|||||||
@ -282,6 +282,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"KEYBOARD_SHORTCUTS": {
|
"KEYBOARD_SHORTCUTS": {
|
||||||
|
"TOGGLE_MODAL": "View all shortcuts",
|
||||||
"TITLE": {
|
"TITLE": {
|
||||||
"OPEN_CONVERSATION": "Unterhaltung öffnen",
|
"OPEN_CONVERSATION": "Unterhaltung öffnen",
|
||||||
"RESOLVE_AND_NEXT": "Lösen und zum Nächsten gehen",
|
"RESOLVE_AND_NEXT": "Lösen und zum Nächsten gehen",
|
||||||
|
|||||||
@ -24,8 +24,11 @@
|
|||||||
"TITLE": "Επιλέξτε ενός Agent Bot",
|
"TITLE": "Επιλέξτε ενός Agent Bot",
|
||||||
"DESC": "Μπορείτε να ορίσετε ένα agent bot από τη λίστα σε αυτά τα εισερχόμενα. Το bot μπορεί αρχικά να χειριστεί τη συνομιλία και να την μεταφέρει σε έναν πράκτορα όταν χρειάζεται.",
|
"DESC": "Μπορείτε να ορίσετε ένα agent bot από τη λίστα σε αυτά τα εισερχόμενα. Το bot μπορεί αρχικά να χειριστεί τη συνομιλία και να την μεταφέρει σε έναν πράκτορα όταν χρειάζεται.",
|
||||||
"SUBMIT": "Ενημέρωση",
|
"SUBMIT": "Ενημέρωση",
|
||||||
|
"DISCONNECT": "Disconnect Bot",
|
||||||
"SUCCESS_MESSAGE": "Επιτυχής ενημέρωση του agent bot",
|
"SUCCESS_MESSAGE": "Επιτυχής ενημέρωση του agent bot",
|
||||||
|
"DISCONNECTED_SUCCESS_MESSAGE": "Successfully disconnected the agent bot",
|
||||||
"ERROR_MESSAGE": "Δεν ήταν δυνατή η ενημέρωση του agent bot, δοκιμάστε ξανά αργότερα",
|
"ERROR_MESSAGE": "Δεν ήταν δυνατή η ενημέρωση του agent bot, δοκιμάστε ξανά αργότερα",
|
||||||
|
"DISCONNECTED_ERROR_MESSAGE": "Could not disconnect the agent bot, please try again later",
|
||||||
"SELECT_PLACEHOLDER": "Επιλογή Bot"
|
"SELECT_PLACEHOLDER": "Επιλογή Bot"
|
||||||
},
|
},
|
||||||
"ADD": {
|
"ADD": {
|
||||||
|
|||||||
@ -42,8 +42,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"SUCCESS_MESSAGE": "Η ιδιότητα προστέθηκε με επιτυχία",
|
"SUCCESS_MESSAGE": "Η ιδιότητα προστέθηκε με επιτυχία!",
|
||||||
"ERROR_MESSAGE": "Δεν ήταν δυνατή η δημιουργία Ιδιότητας, Παρακαλώ δοκιμάστε ξανά αργότερα"
|
"ERROR_MESSAGE": "Δεν ήταν δυνατή η δημιουργία Ιδιότητας, Παρακαλώ δοκιμάστε ξανά αργότερα."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
|
|||||||
@ -53,6 +53,10 @@
|
|||||||
"ENABLE": "Δημιουργία συνομιλιών από τα αναφερόμενα Tweets"
|
"ENABLE": "Δημιουργία συνομιλιών από τα αναφερόμενα Tweets"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"MICROSOFT": {
|
||||||
|
"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"
|
||||||
|
},
|
||||||
"WEBSITE_CHANNEL": {
|
"WEBSITE_CHANNEL": {
|
||||||
"TITLE": "Κανάλι Ιστοσελίδας",
|
"TITLE": "Κανάλι Ιστοσελίδας",
|
||||||
"DESC": "Δημιουργήστε ένα κανάλι Ιστοσελίδα για να υποστηρίξετε τους πελάτες σας μέσω του πρόσθετου επικοινωνίας (widget) που θα εγκαταστήσετε στην ιστοσελίδα σας.",
|
"DESC": "Δημιουργήστε ένα κανάλι Ιστοσελίδα για να υποστηρίξετε τους πελάτες σας μέσω του πρόσθετου επικοινωνίας (widget) που θα εγκαταστήσετε στην ιστοσελίδα σας.",
|
||||||
@ -548,6 +552,10 @@
|
|||||||
},
|
},
|
||||||
"ENABLE_SSL": "Ενεργοποίηση SSL"
|
"ENABLE_SSL": "Ενεργοποίηση SSL"
|
||||||
},
|
},
|
||||||
|
"MICROSOFT": {
|
||||||
|
"TITLE": "Microsoft",
|
||||||
|
"SUBTITLE": "Reauthorize your MICROSOFT account"
|
||||||
|
},
|
||||||
"SMTP": {
|
"SMTP": {
|
||||||
"TITLE": "SMTP",
|
"TITLE": "SMTP",
|
||||||
"SUBTITLE": "Ορισμός λεπτομερειών SMTP",
|
"SUBTITLE": "Ορισμός λεπτομερειών SMTP",
|
||||||
|
|||||||
@ -76,6 +76,13 @@
|
|||||||
"BODY": "<br/><p>Το Chatwoot θα συγχρονίσει τώρα όλες τις εισερχόμενες συνομιλίες στο κανάλι <b><i>πελατών-συνομιλιών</i></b> μέσα στο slack χώρο εργασίας σας.</p><p>Απάντηση σε μια συνομιλία από <b><i>συνομιλίες πελατών</i></b> το κανάλι slack θα δημιουργήσει μια απάντηση για στον πελάτη μέσω chatwoot.</p><p>Ξεκινήστε τις απαντήσεις με το <b><i>note:</i></b> για να δημιουργήσετε ιδιωτικές σημειώσεις αντί για απαντήσεις.</p><p>Αν ο χρήστης στο slack έχει προφίλ πράκτορα στο chatwoot με το ίδιο email, οι απαντήσεις θα συσχετιστούν ανάλογα.</p><p>Εφόσον δεν έχει προφίλ συνδεδεμένου πράκτορα, οι απαντήσεις θα γίνουν από το προφίλ bot.</p>"
|
"BODY": "<br/><p>Το Chatwoot θα συγχρονίσει τώρα όλες τις εισερχόμενες συνομιλίες στο κανάλι <b><i>πελατών-συνομιλιών</i></b> μέσα στο slack χώρο εργασίας σας.</p><p>Απάντηση σε μια συνομιλία από <b><i>συνομιλίες πελατών</i></b> το κανάλι slack θα δημιουργήσει μια απάντηση για στον πελάτη μέσω chatwoot.</p><p>Ξεκινήστε τις απαντήσεις με το <b><i>note:</i></b> για να δημιουργήσετε ιδιωτικές σημειώσεις αντί για απαντήσεις.</p><p>Αν ο χρήστης στο slack έχει προφίλ πράκτορα στο chatwoot με το ίδιο email, οι απαντήσεις θα συσχετιστούν ανάλογα.</p><p>Εφόσον δεν έχει προφίλ συνδεδεμένου πράκτορα, οι απαντήσεις θα γίνουν από το προφίλ bot.</p>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"DYTE": {
|
||||||
|
"CLICK_HERE_TO_JOIN": "Κάντε κλικ εδώ για να συμμετάσχετε",
|
||||||
|
"LEAVE_THE_ROOM": "Αποχώρηση",
|
||||||
|
"START_VIDEO_CALL_HELP_TEXT": "Ξεκινήστε μια νέα βιντεοκλήση με τον πελάτη",
|
||||||
|
"JOIN_ERROR": "Παρουσιάστηκε σφάλμα κατά τη σύνδεση της κλήσης, παρακαλώ προσπαθήστε ξανά",
|
||||||
|
"CREATE_ERROR": "Παρουσιάστηκε σφάλμα κατά τη δημιουργία ενός συνδέσμου συνάντησης, παρακαλώ προσπαθήστε ξανά"
|
||||||
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
"BUTTON_TEXT": "Διαγραφή",
|
"BUTTON_TEXT": "Διαγραφή",
|
||||||
"API": {
|
"API": {
|
||||||
|
|||||||
@ -282,6 +282,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"KEYBOARD_SHORTCUTS": {
|
"KEYBOARD_SHORTCUTS": {
|
||||||
|
"TOGGLE_MODAL": "Εμφάνιση όλων των συντομεύσεων",
|
||||||
"TITLE": {
|
"TITLE": {
|
||||||
"OPEN_CONVERSATION": "Άνοιγμα συνομιλίας",
|
"OPEN_CONVERSATION": "Άνοιγμα συνομιλίας",
|
||||||
"RESOLVE_AND_NEXT": "Επίλυση και μετακίνηση στην επόμενη",
|
"RESOLVE_AND_NEXT": "Επίλυση και μετακίνηση στην επόμενη",
|
||||||
|
|||||||
@ -24,8 +24,11 @@
|
|||||||
"TITLE": "Select an agent bot",
|
"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.",
|
"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",
|
"SUBMIT": "Update",
|
||||||
|
"DISCONNECT": "Disconnect Bot",
|
||||||
"SUCCESS_MESSAGE": "Successfully updated the agent 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",
|
"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"
|
"SELECT_PLACEHOLDER": "Select Bot"
|
||||||
},
|
},
|
||||||
"ADD": {
|
"ADD": {
|
||||||
|
|||||||
@ -42,8 +42,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"SUCCESS_MESSAGE": "Custom Attribute added successfully",
|
"SUCCESS_MESSAGE": "Custom Attribute added successfully!",
|
||||||
"ERROR_MESSAGE": "Could not able to create a custom attribute, Please try again later"
|
"ERROR_MESSAGE": "Could not create a Custom Attribute. Please try again later."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
|
|||||||
@ -214,7 +214,7 @@
|
|||||||
"PHONE_NUMBER": {
|
"PHONE_NUMBER": {
|
||||||
"LABEL": "Phone number",
|
"LABEL": "Phone number",
|
||||||
"PLACEHOLDER": "Please enter the phone number from which message will be sent.",
|
"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."
|
"ERROR": "Please provide a valid phone number that starts with a `+` sign and does not contain any spaces."
|
||||||
},
|
},
|
||||||
"PHONE_NUMBER_ID": {
|
"PHONE_NUMBER_ID": {
|
||||||
"LABEL": "Phone number ID",
|
"LABEL": "Phone number ID",
|
||||||
@ -344,6 +344,17 @@
|
|||||||
"FINISH": {
|
"FINISH": {
|
||||||
"TITLE": "Nailed It!",
|
"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 :)"
|
"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": {
|
"DETAILS": {
|
||||||
@ -548,6 +559,10 @@
|
|||||||
},
|
},
|
||||||
"ENABLE_SSL": "Enable SSL"
|
"ENABLE_SSL": "Enable SSL"
|
||||||
},
|
},
|
||||||
|
"MICROSOFT": {
|
||||||
|
"TITLE": "Microsoft",
|
||||||
|
"SUBTITLE": "Reauthorize your MICROSOFT account"
|
||||||
|
},
|
||||||
"SMTP": {
|
"SMTP": {
|
||||||
"TITLE": "SMTP",
|
"TITLE": "SMTP",
|
||||||
"SUBTITLE": "Set your SMTP details",
|
"SUBTITLE": "Set your SMTP details",
|
||||||
@ -666,6 +681,10 @@
|
|||||||
},
|
},
|
||||||
"BRANDING_TEXT": "Powered by Chatwoot",
|
"BRANDING_TEXT": "Powered by Chatwoot",
|
||||||
"SCRIPT_SETTINGS": "\n window.chatwootSettings = {options};"
|
"SCRIPT_SETTINGS": "\n window.chatwootSettings = {options};"
|
||||||
|
},
|
||||||
|
"EMAIL_PROVIDERS": {
|
||||||
|
"MICROSOFT": "Microsoft",
|
||||||
|
"OTHER_PROVIDERS": "Other Providers"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,10 +35,7 @@
|
|||||||
"LIST": {
|
"LIST": {
|
||||||
"404": "There are no webhooks configured for this account.",
|
"404": "There are no webhooks configured for this account.",
|
||||||
"TITLE": "Manage webhooks",
|
"TITLE": "Manage webhooks",
|
||||||
"TABLE_HEADER": [
|
"TABLE_HEADER": ["Webhook endpoint", "Actions"]
|
||||||
"Webhook endpoint",
|
|
||||||
"Actions"
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"EDIT": {
|
"EDIT": {
|
||||||
"BUTTON_TEXT": "Edit",
|
"BUTTON_TEXT": "Edit",
|
||||||
@ -76,6 +73,13 @@
|
|||||||
"BODY": "<br/><p>Chatwoot will now sync all the incoming conversations into the <b><i>customer-conversations</i></b> channel inside your slack workplace.</p><p>Replying to a conversation thread in <b><i>customer-conversations</i></b> slack channel will create a response back to the customer through chatwoot.</p><p>Start the replies with <b><i>note:</i></b> to create private notes instead of replies.</p><p>If the replier on slack has an agent profile in chatwoot under the same email, the replies will be associated accordingly.</p><p>When the replier doesn't have an associated agent profile, the replies will be made from the bot profile.</p>"
|
"BODY": "<br/><p>Chatwoot will now sync all the incoming conversations into the <b><i>customer-conversations</i></b> channel inside your slack workplace.</p><p>Replying to a conversation thread in <b><i>customer-conversations</i></b> slack channel will create a response back to the customer through chatwoot.</p><p>Start the replies with <b><i>note:</i></b> to create private notes instead of replies.</p><p>If the replier on slack has an agent profile in chatwoot under the same email, the replies will be associated accordingly.</p><p>When the replier doesn't have an associated agent profile, the replies will be made from the bot profile.</p>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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"
|
||||||
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
"BUTTON_TEXT": "Delete",
|
"BUTTON_TEXT": "Delete",
|
||||||
"API": {
|
"API": {
|
||||||
@ -93,10 +97,7 @@
|
|||||||
"LIST": {
|
"LIST": {
|
||||||
"404": "There are no dashboard apps configured on this account yet",
|
"404": "There are no dashboard apps configured on this account yet",
|
||||||
"LOADING": "Fetching dashboard apps...",
|
"LOADING": "Fetching dashboard apps...",
|
||||||
"TABLE_HEADER": [
|
"TABLE_HEADER": ["Name", "Endpoint"],
|
||||||
"Name",
|
|
||||||
"Endpoint"
|
|
||||||
],
|
|
||||||
"EDIT_TOOLTIP": "Edit app",
|
"EDIT_TOOLTIP": "Edit app",
|
||||||
"DELETE_TOOLTIP": "Delete app"
|
"DELETE_TOOLTIP": "Delete app"
|
||||||
},
|
},
|
||||||
|
|||||||
@ -158,7 +158,7 @@
|
|||||||
"COMPONENTS": {
|
"COMPONENTS": {
|
||||||
"CODE": {
|
"CODE": {
|
||||||
"BUTTON_TEXT": "Copy",
|
"BUTTON_TEXT": "Copy",
|
||||||
"COPY_SUCCESSFUL": "Code copied to clipboard successfully"
|
"COPY_SUCCESSFUL": "Copied to clipboard"
|
||||||
},
|
},
|
||||||
"SHOW_MORE_BLOCK": {
|
"SHOW_MORE_BLOCK": {
|
||||||
"SHOW_MORE": "Show More",
|
"SHOW_MORE": "Show More",
|
||||||
|
|||||||
@ -24,8 +24,11 @@
|
|||||||
"TITLE": "Seleccione un bot de agente",
|
"TITLE": "Seleccione un bot de agente",
|
||||||
"DESC": "Puedes establecer un bot de agente desde la lista a esta bandeja de entrada. El bot puede inicialmente manejar la conversación y transferirla a un agente cuando sea necesario.",
|
"DESC": "Puedes establecer un bot de agente desde la lista a esta bandeja de entrada. El bot puede inicialmente manejar la conversación y transferirla a un agente cuando sea necesario.",
|
||||||
"SUBMIT": "Actualizar",
|
"SUBMIT": "Actualizar",
|
||||||
|
"DISCONNECT": "Desconectar Bot",
|
||||||
"SUCCESS_MESSAGE": "El bot del agente se ha actualizado con éxito",
|
"SUCCESS_MESSAGE": "El bot del agente se ha actualizado con éxito",
|
||||||
|
"DISCONNECTED_SUCCESS_MESSAGE": "Desconectado correctamente el bot agente",
|
||||||
"ERROR_MESSAGE": "No se pudo actualizar el bot de agente, por favor inténtalo de nuevo más tarde",
|
"ERROR_MESSAGE": "No se pudo actualizar el bot de agente, por favor inténtalo de nuevo más tarde",
|
||||||
|
"DISCONNECTED_ERROR_MESSAGE": "No se pudo desconectar el bot de agente, por favor inténtalo de nuevo más tarde",
|
||||||
"SELECT_PLACEHOLDER": "Seleccionar bot"
|
"SELECT_PLACEHOLDER": "Seleccionar bot"
|
||||||
},
|
},
|
||||||
"ADD": {
|
"ADD": {
|
||||||
|
|||||||
@ -42,8 +42,8 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"API": {
|
"API": {
|
||||||
"SUCCESS_MESSAGE": "Atributo personalizado añadido correctamente",
|
"SUCCESS_MESSAGE": "Atributo personalizado añadido correctamente!",
|
||||||
"ERROR_MESSAGE": "No se pudo crear un atributo personalizado, por favor inténtalo de nuevo"
|
"ERROR_MESSAGE": "Could not create a Custom Attribute. Please try again later."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
|
|||||||
@ -53,6 +53,10 @@
|
|||||||
"ENABLE": "Crear conversaciones de los Tweets mencionados"
|
"ENABLE": "Crear conversaciones de los Tweets mencionados"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"MICROSOFT": {
|
||||||
|
"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"
|
||||||
|
},
|
||||||
"WEBSITE_CHANNEL": {
|
"WEBSITE_CHANNEL": {
|
||||||
"TITLE": "Canal del sitio web",
|
"TITLE": "Canal del sitio web",
|
||||||
"DESC": "Cree un canal para su sitio web y comience a apoyar a sus clientes a través de nuestro widget de sitio web.",
|
"DESC": "Cree un canal para su sitio web y comience a apoyar a sus clientes a través de nuestro widget de sitio web.",
|
||||||
@ -548,6 +552,10 @@
|
|||||||
},
|
},
|
||||||
"ENABLE_SSL": "Activar SSL"
|
"ENABLE_SSL": "Activar SSL"
|
||||||
},
|
},
|
||||||
|
"MICROSOFT": {
|
||||||
|
"TITLE": "Microsoft",
|
||||||
|
"SUBTITLE": "Reauthorize your MICROSOFT account"
|
||||||
|
},
|
||||||
"SMTP": {
|
"SMTP": {
|
||||||
"TITLE": "SMTP",
|
"TITLE": "SMTP",
|
||||||
"SUBTITLE": "Configura tus detalles de SMTP",
|
"SUBTITLE": "Configura tus detalles de SMTP",
|
||||||
|
|||||||
@ -76,6 +76,13 @@
|
|||||||
"BODY": "<br/><p>Chatwoot ahora sincronizará todas las conversaciones entrantes en el canal <b><i>de conversaciones del cliente</i></b> dentro de tu lugar de trabajo slack.</p><p>Respondiendo a un tema de conversación en <b><i>conversaciones de clientes</i></b> canal de slack creará una respuesta al cliente a través de chatwoot.</p><p>Inicie las respuestas con <b><i>nota:</i></b> para crear notas privadas en lugar de respuestas.</p><p>Si el respondente de slack tiene un perfil de agente en el chatwoot bajo el mismo correo electrónico, las respuestas se asociarán en consecuencia.</p><p>Cuando el replicador no tiene un perfil de agente asociado, las respuestas se harán con el perfil del bot.</p>"
|
"BODY": "<br/><p>Chatwoot ahora sincronizará todas las conversaciones entrantes en el canal <b><i>de conversaciones del cliente</i></b> dentro de tu lugar de trabajo slack.</p><p>Respondiendo a un tema de conversación en <b><i>conversaciones de clientes</i></b> canal de slack creará una respuesta al cliente a través de chatwoot.</p><p>Inicie las respuestas con <b><i>nota:</i></b> para crear notas privadas en lugar de respuestas.</p><p>Si el respondente de slack tiene un perfil de agente en el chatwoot bajo el mismo correo electrónico, las respuestas se asociarán en consecuencia.</p><p>Cuando el replicador no tiene un perfil de agente asociado, las respuestas se harán con el perfil del bot.</p>"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"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"
|
||||||
|
},
|
||||||
"DELETE": {
|
"DELETE": {
|
||||||
"BUTTON_TEXT": "Eliminar",
|
"BUTTON_TEXT": "Eliminar",
|
||||||
"API": {
|
"API": {
|
||||||
|
|||||||
@ -282,6 +282,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"KEYBOARD_SHORTCUTS": {
|
"KEYBOARD_SHORTCUTS": {
|
||||||
|
"TOGGLE_MODAL": "View all shortcuts",
|
||||||
"TITLE": {
|
"TITLE": {
|
||||||
"OPEN_CONVERSATION": "Abrir conversación",
|
"OPEN_CONVERSATION": "Abrir conversación",
|
||||||
"RESOLVE_AND_NEXT": "Resolver y pasar al siguiente",
|
"RESOLVE_AND_NEXT": "Resolver y pasar al siguiente",
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user