Compare commits
14
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0ef3b3b5b5 | ||
|
|
af084af774 | ||
|
|
5a682135f2 | ||
|
|
a72dba1769 | ||
|
|
cc653e072a | ||
|
|
7e64671a27 | ||
|
|
43bca252f9 | ||
|
|
5dc74ff40f | ||
|
|
8dd735f3ea | ||
|
|
ce69614662 | ||
|
|
8a6b13fd85 | ||
|
|
2692dba5bd | ||
|
|
0095254e65 | ||
|
|
3b34be5740 |
@@ -57,6 +57,13 @@ POSTGRES_PASSWORD=
|
||||
RAILS_ENV=development
|
||||
# Changes the Postgres query timeout limit. The default is 14 seconds. Modify only when required.
|
||||
# POSTGRES_STATEMENT_TIMEOUT=14s
|
||||
|
||||
# read replica configuration for production
|
||||
# POSTGRES_HOST_RR=postgres_rr
|
||||
# create a new user with readonly permissions
|
||||
# POSTGRES_USERNAME_RR=postgres_readonly
|
||||
# POSTGRES_PASSWORD_RR=
|
||||
|
||||
RAILS_MAX_THREADS=5
|
||||
|
||||
# The email from which all outgoing emails are sent
|
||||
|
||||
@@ -45,7 +45,6 @@ jobs:
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.ref }}
|
||||
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
||||
|
||||
- uses: ruby/setup-ruby@v1
|
||||
with:
|
||||
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
||||
|
||||
@@ -77,7 +77,7 @@ gem 'jwt'
|
||||
gem 'pundit'
|
||||
# super admin
|
||||
gem 'administrate', '>= 0.20.1'
|
||||
gem 'administrate-field-active_storage', '>= 1.0.3'
|
||||
gem 'administrate-field-active_storage', '>= 1.0.2'
|
||||
gem 'administrate-field-belongs_to_search', '>= 0.9.0'
|
||||
|
||||
##--- gems for pubsub service ---##
|
||||
|
||||
+57
-59
@@ -33,70 +33,70 @@ GIT
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actioncable (7.0.8.3)
|
||||
actionpack (= 7.0.8.3)
|
||||
activesupport (= 7.0.8.3)
|
||||
actioncable (7.0.8.1)
|
||||
actionpack (= 7.0.8.1)
|
||||
activesupport (= 7.0.8.1)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (>= 0.6.1)
|
||||
actionmailbox (7.0.8.3)
|
||||
actionpack (= 7.0.8.3)
|
||||
activejob (= 7.0.8.3)
|
||||
activerecord (= 7.0.8.3)
|
||||
activestorage (= 7.0.8.3)
|
||||
activesupport (= 7.0.8.3)
|
||||
actionmailbox (7.0.8.1)
|
||||
actionpack (= 7.0.8.1)
|
||||
activejob (= 7.0.8.1)
|
||||
activerecord (= 7.0.8.1)
|
||||
activestorage (= 7.0.8.1)
|
||||
activesupport (= 7.0.8.1)
|
||||
mail (>= 2.7.1)
|
||||
net-imap
|
||||
net-pop
|
||||
net-smtp
|
||||
actionmailer (7.0.8.3)
|
||||
actionpack (= 7.0.8.3)
|
||||
actionview (= 7.0.8.3)
|
||||
activejob (= 7.0.8.3)
|
||||
activesupport (= 7.0.8.3)
|
||||
actionmailer (7.0.8.1)
|
||||
actionpack (= 7.0.8.1)
|
||||
actionview (= 7.0.8.1)
|
||||
activejob (= 7.0.8.1)
|
||||
activesupport (= 7.0.8.1)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
net-imap
|
||||
net-pop
|
||||
net-smtp
|
||||
rails-dom-testing (~> 2.0)
|
||||
actionpack (7.0.8.3)
|
||||
actionview (= 7.0.8.3)
|
||||
activesupport (= 7.0.8.3)
|
||||
actionpack (7.0.8.1)
|
||||
actionview (= 7.0.8.1)
|
||||
activesupport (= 7.0.8.1)
|
||||
rack (~> 2.0, >= 2.2.4)
|
||||
rack-test (>= 0.6.3)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
||||
actiontext (7.0.8.3)
|
||||
actionpack (= 7.0.8.3)
|
||||
activerecord (= 7.0.8.3)
|
||||
activestorage (= 7.0.8.3)
|
||||
activesupport (= 7.0.8.3)
|
||||
actiontext (7.0.8.1)
|
||||
actionpack (= 7.0.8.1)
|
||||
activerecord (= 7.0.8.1)
|
||||
activestorage (= 7.0.8.1)
|
||||
activesupport (= 7.0.8.1)
|
||||
globalid (>= 0.6.0)
|
||||
nokogiri (>= 1.8.5)
|
||||
actionview (7.0.8.3)
|
||||
activesupport (= 7.0.8.3)
|
||||
actionview (7.0.8.1)
|
||||
activesupport (= 7.0.8.1)
|
||||
builder (~> 3.1)
|
||||
erubi (~> 1.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
||||
active_record_query_trace (1.8)
|
||||
activejob (7.0.8.3)
|
||||
activesupport (= 7.0.8.3)
|
||||
activejob (7.0.8.1)
|
||||
activesupport (= 7.0.8.1)
|
||||
globalid (>= 0.3.6)
|
||||
activemodel (7.0.8.3)
|
||||
activesupport (= 7.0.8.3)
|
||||
activerecord (7.0.8.3)
|
||||
activemodel (= 7.0.8.3)
|
||||
activesupport (= 7.0.8.3)
|
||||
activemodel (7.0.8.1)
|
||||
activesupport (= 7.0.8.1)
|
||||
activerecord (7.0.8.1)
|
||||
activemodel (= 7.0.8.1)
|
||||
activesupport (= 7.0.8.1)
|
||||
activerecord-import (1.4.1)
|
||||
activerecord (>= 4.2)
|
||||
activestorage (7.0.8.3)
|
||||
actionpack (= 7.0.8.3)
|
||||
activejob (= 7.0.8.3)
|
||||
activerecord (= 7.0.8.3)
|
||||
activesupport (= 7.0.8.3)
|
||||
activestorage (7.0.8.1)
|
||||
actionpack (= 7.0.8.1)
|
||||
activejob (= 7.0.8.1)
|
||||
activerecord (= 7.0.8.1)
|
||||
activesupport (= 7.0.8.1)
|
||||
marcel (~> 1.0)
|
||||
mini_mime (>= 1.1.0)
|
||||
activesupport (7.0.8.3)
|
||||
activesupport (7.0.8.1)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
@@ -113,7 +113,7 @@ GEM
|
||||
kaminari (~> 1.2.2)
|
||||
sassc-rails (~> 2.1)
|
||||
selectize-rails (~> 0.6)
|
||||
administrate-field-active_storage (1.0.3)
|
||||
administrate-field-active_storage (1.0.2)
|
||||
administrate (>= 0.2.2)
|
||||
rails (>= 7.0)
|
||||
administrate-field-belongs_to_search (0.9.0)
|
||||
@@ -461,7 +461,7 @@ GEM
|
||||
mini_magick (4.12.0)
|
||||
mini_mime (1.1.5)
|
||||
mini_portile2 (2.8.6)
|
||||
minitest (5.23.0)
|
||||
minitest (5.22.3)
|
||||
mock_redis (0.36.0)
|
||||
ruby2_keywords
|
||||
msgpack (1.7.0)
|
||||
@@ -569,20 +569,20 @@ GEM
|
||||
rack-test (2.1.0)
|
||||
rack (>= 1.3)
|
||||
rack-timeout (0.6.3)
|
||||
rails (7.0.8.3)
|
||||
actioncable (= 7.0.8.3)
|
||||
actionmailbox (= 7.0.8.3)
|
||||
actionmailer (= 7.0.8.3)
|
||||
actionpack (= 7.0.8.3)
|
||||
actiontext (= 7.0.8.3)
|
||||
actionview (= 7.0.8.3)
|
||||
activejob (= 7.0.8.3)
|
||||
activemodel (= 7.0.8.3)
|
||||
activerecord (= 7.0.8.3)
|
||||
activestorage (= 7.0.8.3)
|
||||
activesupport (= 7.0.8.3)
|
||||
rails (7.0.8.1)
|
||||
actioncable (= 7.0.8.1)
|
||||
actionmailbox (= 7.0.8.1)
|
||||
actionmailer (= 7.0.8.1)
|
||||
actionpack (= 7.0.8.1)
|
||||
actiontext (= 7.0.8.1)
|
||||
actionview (= 7.0.8.1)
|
||||
activejob (= 7.0.8.1)
|
||||
activemodel (= 7.0.8.1)
|
||||
activerecord (= 7.0.8.1)
|
||||
activestorage (= 7.0.8.1)
|
||||
activesupport (= 7.0.8.1)
|
||||
bundler (>= 1.15.0)
|
||||
railties (= 7.0.8.3)
|
||||
railties (= 7.0.8.1)
|
||||
rails-dom-testing (2.2.0)
|
||||
activesupport (>= 5.0.0)
|
||||
minitest
|
||||
@@ -590,9 +590,9 @@ GEM
|
||||
rails-html-sanitizer (1.6.0)
|
||||
loofah (~> 2.21)
|
||||
nokogiri (~> 1.14)
|
||||
railties (7.0.8.3)
|
||||
actionpack (= 7.0.8.3)
|
||||
activesupport (= 7.0.8.3)
|
||||
railties (7.0.8.1)
|
||||
actionpack (= 7.0.8.1)
|
||||
activesupport (= 7.0.8.1)
|
||||
method_source
|
||||
rake (>= 12.2)
|
||||
thor (~> 1.0)
|
||||
@@ -628,8 +628,7 @@ GEM
|
||||
retriable (3.1.2)
|
||||
reverse_markdown (2.1.1)
|
||||
nokogiri
|
||||
rexml (3.2.8)
|
||||
strscan (>= 3.0.9)
|
||||
rexml (3.2.5)
|
||||
rspec-core (3.12.2)
|
||||
rspec-support (~> 3.12.0)
|
||||
rspec-expectations (3.12.3)
|
||||
@@ -759,7 +758,6 @@ GEM
|
||||
stackprof (0.2.25)
|
||||
statsd-ruby (1.5.0)
|
||||
stripe (8.5.0)
|
||||
strscan (3.1.0)
|
||||
telephone_number (1.4.20)
|
||||
test-prof (1.2.1)
|
||||
thor (1.3.1)
|
||||
@@ -839,7 +837,7 @@ DEPENDENCIES
|
||||
activerecord-import
|
||||
acts-as-taggable-on
|
||||
administrate (>= 0.20.1)
|
||||
administrate-field-active_storage (>= 1.0.3)
|
||||
administrate-field-active_storage (>= 1.0.2)
|
||||
administrate-field-belongs_to_search (>= 0.9.0)
|
||||
annotate
|
||||
attr_extras
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
class V2::Reports::Conversations::BaseReportBuilder
|
||||
pattr_initialize :account, :params
|
||||
|
||||
private
|
||||
|
||||
AVG_METRICS = %w[avg_first_response_time avg_resolution_time reply_time].freeze
|
||||
COUNT_METRICS = %w[
|
||||
conversations_count
|
||||
incoming_messages_count
|
||||
outgoing_messages_count
|
||||
resolutions_count
|
||||
bot_resolutions_count
|
||||
bot_handoffs_count
|
||||
].freeze
|
||||
|
||||
def builder_class(metric)
|
||||
case metric
|
||||
when *AVG_METRICS
|
||||
V2::Reports::Timeseries::AverageReportBuilder
|
||||
when *COUNT_METRICS
|
||||
V2::Reports::Timeseries::CountReportBuilder
|
||||
end
|
||||
end
|
||||
|
||||
def log_invalid_metric
|
||||
Rails.logger.error "ReportBuilder: Invalid metric - #{params[:metric]}"
|
||||
|
||||
{}
|
||||
end
|
||||
end
|
||||
@@ -1,30 +0,0 @@
|
||||
class V2::Reports::Conversations::MetricBuilder < V2::Reports::Conversations::BaseReportBuilder
|
||||
def summary
|
||||
{
|
||||
conversations_count: count('conversations_count'),
|
||||
incoming_messages_count: count('incoming_messages_count'),
|
||||
outgoing_messages_count: count('outgoing_messages_count'),
|
||||
avg_first_response_time: count('avg_first_response_time'),
|
||||
avg_resolution_time: count('avg_resolution_time'),
|
||||
resolutions_count: count('resolutions_count'),
|
||||
reply_time: count('reply_time')
|
||||
}
|
||||
end
|
||||
|
||||
def bot_summary
|
||||
{
|
||||
bot_resolutions_count: count('bot_resolutions_count'),
|
||||
bot_handoffs_count: count('bot_handoffs_count')
|
||||
}
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def count(metric)
|
||||
builder_class(metric).new(account, builder_params(metric)).aggregate_value
|
||||
end
|
||||
|
||||
def builder_params(metric)
|
||||
params.merge({ metric: metric })
|
||||
end
|
||||
end
|
||||
@@ -1,21 +0,0 @@
|
||||
class V2::Reports::Conversations::ReportBuilder < V2::Reports::Conversations::BaseReportBuilder
|
||||
def timeseries
|
||||
perform_action(:timeseries)
|
||||
end
|
||||
|
||||
def aggregate_value
|
||||
perform_action(:aggregate_value)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def perform_action(method_name)
|
||||
return builder.new(account, params).public_send(method_name) if builder.present?
|
||||
|
||||
log_invalid_metric
|
||||
end
|
||||
|
||||
def builder
|
||||
builder_class(params[:metric])
|
||||
end
|
||||
end
|
||||
@@ -1,48 +0,0 @@
|
||||
class V2::Reports::Timeseries::AverageReportBuilder < V2::Reports::Timeseries::BaseTimeseriesBuilder
|
||||
def timeseries
|
||||
grouped_average_time = reporting_events.average(average_value_key)
|
||||
grouped_event_count = reporting_events.count
|
||||
grouped_average_time.each_with_object([]) do |element, arr|
|
||||
event_date, average_time = element
|
||||
arr << {
|
||||
value: average_time,
|
||||
timestamp: event_date.in_time_zone(timezone).to_i,
|
||||
count: grouped_event_count[event_date]
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
def aggregate_value
|
||||
object_scope.average(average_value_key)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def event_name
|
||||
metric_to_event_name = {
|
||||
avg_first_response_time: :first_response,
|
||||
avg_resolution_time: :conversation_resolved,
|
||||
reply_time: :reply_time
|
||||
}
|
||||
metric_to_event_name[params[:metric].to_sym]
|
||||
end
|
||||
|
||||
def object_scope
|
||||
scope.reporting_events.where(name: event_name, created_at: range)
|
||||
end
|
||||
|
||||
def reporting_events
|
||||
@grouped_values = object_scope.group_by_period(
|
||||
group_by,
|
||||
:created_at,
|
||||
default_value: 0,
|
||||
range: range,
|
||||
permit: %w[day week month year hour],
|
||||
time_zone: timezone
|
||||
)
|
||||
end
|
||||
|
||||
def average_value_key
|
||||
@average_value_key ||= params[:business_hours].present? ? :value_in_business_hours : :value
|
||||
end
|
||||
end
|
||||
@@ -1,46 +0,0 @@
|
||||
class V2::Reports::Timeseries::BaseTimeseriesBuilder
|
||||
include TimezoneHelper
|
||||
include DateRangeHelper
|
||||
DEFAULT_GROUP_BY = 'day'.freeze
|
||||
|
||||
pattr_initialize :account, :params
|
||||
|
||||
def scope
|
||||
case params[:type].to_sym
|
||||
when :account
|
||||
account
|
||||
when :inbox
|
||||
inbox
|
||||
when :agent
|
||||
user
|
||||
when :label
|
||||
label
|
||||
when :team
|
||||
team
|
||||
end
|
||||
end
|
||||
|
||||
def inbox
|
||||
@inbox ||= account.inboxes.find(params[:id])
|
||||
end
|
||||
|
||||
def user
|
||||
@user ||= account.users.find(params[:id])
|
||||
end
|
||||
|
||||
def label
|
||||
@label ||= account.labels.find(params[:id])
|
||||
end
|
||||
|
||||
def team
|
||||
@team ||= account.teams.find(params[:id])
|
||||
end
|
||||
|
||||
def group_by
|
||||
@group_by ||= %w[day week month year hour].include?(params[:group_by]) ? params[:group_by] : DEFAULT_GROUP_BY
|
||||
end
|
||||
|
||||
def timezone
|
||||
@timezone ||= timezone_name_from_offset(params[:timezone_offset])
|
||||
end
|
||||
end
|
||||
@@ -1,71 +0,0 @@
|
||||
class V2::Reports::Timeseries::CountReportBuilder < V2::Reports::Timeseries::BaseTimeseriesBuilder
|
||||
def timeseries
|
||||
grouped_count.each_with_object([]) do |element, arr|
|
||||
event_date, event_count = element
|
||||
|
||||
# The `event_date` is in Date format (without time), such as "Wed, 15 May 2024".
|
||||
# We need a timestamp for the start of the day. However, we can't use `event_date.to_time.to_i`
|
||||
# because it converts the date to 12:00 AM server timezone.
|
||||
# The desired output should be 12:00 AM in the specified timezone.
|
||||
arr << { value: event_count, timestamp: event_date.in_time_zone(timezone).to_i }
|
||||
end
|
||||
end
|
||||
|
||||
def aggregate_value
|
||||
object_scope.count
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def metric
|
||||
@metric ||= params[:metric]
|
||||
end
|
||||
|
||||
def object_scope
|
||||
send("scope_for_#{metric}")
|
||||
end
|
||||
|
||||
def scope_for_conversations_count
|
||||
scope.conversations.where(account_id: account.id, created_at: range)
|
||||
end
|
||||
|
||||
def scope_for_incoming_messages_count
|
||||
scope.messages.where(account_id: account.id, created_at: range).incoming.unscope(:order)
|
||||
end
|
||||
|
||||
def scope_for_outgoing_messages_count
|
||||
scope.messages.where(account_id: account.id, created_at: range).outgoing.unscope(:order)
|
||||
end
|
||||
|
||||
def scope_for_resolutions_count
|
||||
scope.reporting_events.joins(:conversation).select(:conversation_id).where(
|
||||
name: :conversation_resolved,
|
||||
conversations: { status: :resolved }, created_at: range
|
||||
).distinct
|
||||
end
|
||||
|
||||
def scope_for_bot_resolutions_count
|
||||
scope.reporting_events.joins(:conversation).select(:conversation_id).where(
|
||||
name: :conversation_bot_resolved,
|
||||
conversations: { status: :resolved }, created_at: range
|
||||
).distinct
|
||||
end
|
||||
|
||||
def scope_for_bot_handoffs_count
|
||||
scope.reporting_events.joins(:conversation).select(:conversation_id).where(
|
||||
name: :conversation_bot_handoff,
|
||||
created_at: range
|
||||
).distinct
|
||||
end
|
||||
|
||||
def grouped_count
|
||||
@grouped_values = object_scope.group_by_period(
|
||||
group_by,
|
||||
:created_at,
|
||||
default_value: 0,
|
||||
range: range,
|
||||
permit: %w[day week month year hour],
|
||||
time_zone: timezone
|
||||
).count
|
||||
end
|
||||
end
|
||||
@@ -1,93 +0,0 @@
|
||||
class Api::V1::Accounts::Integrations::LinearController < Api::V1::Accounts::BaseController
|
||||
before_action :fetch_conversation, only: [:link_issue, :linked_issues]
|
||||
|
||||
def teams
|
||||
teams = linear_processor_service.teams
|
||||
if teams[:error]
|
||||
render json: { error: teams[:error] }, status: :unprocessable_entity
|
||||
else
|
||||
render json: teams[:data], status: :ok
|
||||
end
|
||||
end
|
||||
|
||||
def team_entities
|
||||
team_id = permitted_params[:team_id]
|
||||
team_entities = linear_processor_service.team_entities(team_id)
|
||||
if team_entities[:error]
|
||||
render json: { error: team_entities[:error] }, status: :unprocessable_entity
|
||||
else
|
||||
render json: team_entities[:data], status: :ok
|
||||
end
|
||||
end
|
||||
|
||||
def create_issue
|
||||
issue = linear_processor_service.create_issue(permitted_params)
|
||||
if issue[:error]
|
||||
render json: { error: issue[:error] }, status: :unprocessable_entity
|
||||
else
|
||||
render json: issue[:data], status: :ok
|
||||
end
|
||||
end
|
||||
|
||||
def link_issue
|
||||
issue_id = permitted_params[:issue_id]
|
||||
title = permitted_params[:title]
|
||||
issue = linear_processor_service.link_issue(conversation_link, issue_id, title)
|
||||
if issue[:error]
|
||||
render json: { error: issue[:error] }, status: :unprocessable_entity
|
||||
else
|
||||
render json: issue[:data], status: :ok
|
||||
end
|
||||
end
|
||||
|
||||
def unlink_issue
|
||||
link_id = permitted_params[:link_id]
|
||||
issue = linear_processor_service.unlink_issue(link_id)
|
||||
|
||||
if issue[:error]
|
||||
render json: { error: issue[:error] }, status: :unprocessable_entity
|
||||
else
|
||||
render json: issue[:data], status: :ok
|
||||
end
|
||||
end
|
||||
|
||||
def linked_issues
|
||||
issues = linear_processor_service.linked_issues(conversation_link)
|
||||
|
||||
if issues[:error]
|
||||
render json: { error: issues[:error] }, status: :unprocessable_entity
|
||||
else
|
||||
render json: issues[:data], status: :ok
|
||||
end
|
||||
end
|
||||
|
||||
def search_issue
|
||||
render json: { error: 'Specify search string with parameter q' }, status: :unprocessable_entity if params[:q].blank? && return
|
||||
|
||||
term = params[:q]
|
||||
issues = linear_processor_service.search_issue(term)
|
||||
if issues[:error]
|
||||
render json: { error: issues[:error] }, status: :unprocessable_entity
|
||||
else
|
||||
render json: issues[:data], status: :ok
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def conversation_link
|
||||
"#{ENV.fetch('FRONTEND_URL', nil)}/app/accounts/#{Current.account.id}/conversations/#{@conversation.display_id}"
|
||||
end
|
||||
|
||||
def fetch_conversation
|
||||
@conversation = Current.account.conversations.find_by!(display_id: permitted_params[:conversation_id])
|
||||
end
|
||||
|
||||
def linear_processor_service
|
||||
Integrations::Linear::ProcessorService.new(account: Current.account)
|
||||
end
|
||||
|
||||
def permitted_params
|
||||
params.permit(:team_id, :conversation_id, :issue_id, :link_id, :title, :description, :assignee_id, :priority, label_ids: [])
|
||||
end
|
||||
end
|
||||
@@ -5,17 +5,19 @@ class Api::V2::Accounts::ReportsController < Api::V1::Accounts::BaseController
|
||||
before_action :check_authorization
|
||||
|
||||
def index
|
||||
builder = V2::Reports::Conversations::ReportBuilder.new(Current.account, report_params)
|
||||
data = builder.timeseries
|
||||
builder = V2::ReportBuilder.new(Current.account, report_params)
|
||||
data = builder.build
|
||||
render json: data
|
||||
end
|
||||
|
||||
def summary
|
||||
render json: build_summary(:summary)
|
||||
render json: summary_metrics
|
||||
end
|
||||
|
||||
def bot_summary
|
||||
render json: build_summary(:bot_summary)
|
||||
summary = V2::ReportBuilder.new(Current.account, current_summary_params).bot_summary
|
||||
summary[:previous] = V2::ReportBuilder.new(Current.account, previous_summary_params).bot_summary
|
||||
render json: summary
|
||||
end
|
||||
|
||||
def agents
|
||||
@@ -124,11 +126,10 @@ class Api::V2::Accounts::ReportsController < Api::V1::Accounts::BaseController
|
||||
}
|
||||
end
|
||||
|
||||
def build_summary(method)
|
||||
builder = V2::Reports::Conversations::MetricBuilder
|
||||
current_summary = builder.new(Current.account, current_summary_params).send(method)
|
||||
previous_summary = builder.new(Current.account, previous_summary_params).send(method)
|
||||
current_summary.merge(previous: previous_summary)
|
||||
def summary_metrics
|
||||
summary = V2::ReportBuilder.new(Current.account, current_summary_params).summary
|
||||
summary[:previous] = V2::ReportBuilder.new(Current.account, previous_summary_params).summary
|
||||
summary
|
||||
end
|
||||
|
||||
def conversation_metrics
|
||||
|
||||
@@ -2,10 +2,7 @@ module MicrosoftConcern
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
def microsoft_client
|
||||
app_id = GlobalConfigService.load('AZURE_APP_ID', nil)
|
||||
app_secret = GlobalConfigService.load('AZURE_APP_SECRET', nil)
|
||||
|
||||
::OAuth2::Client.new(app_id, app_secret,
|
||||
::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',
|
||||
|
||||
@@ -58,7 +58,7 @@ class DashboardController < ActionController::Base
|
||||
FB_APP_ID: GlobalConfigService.load('FB_APP_ID', ''),
|
||||
FACEBOOK_API_VERSION: GlobalConfigService.load('FACEBOOK_API_VERSION', 'v17.0'),
|
||||
IS_ENTERPRISE: ChatwootApp.enterprise?,
|
||||
AZURE_APP_ID: GlobalConfigService.load('AZURE_APP_ID', ''),
|
||||
AZURE_APP_ID: ENV.fetch('AZURE_APP_ID', ''),
|
||||
GIT_SHA: GIT_HASH
|
||||
}
|
||||
end
|
||||
|
||||
@@ -12,6 +12,6 @@ class MicrosoftController < ApplicationController
|
||||
end
|
||||
|
||||
def microsoft_indentity
|
||||
@identity_json = GlobalConfigService.load('AZURE_APP_ID', nil)
|
||||
@identity_json = ENV.fetch('AZURE_APP_ID', nil)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -35,8 +35,6 @@ class SuperAdmin::AppConfigsController < SuperAdmin::ApplicationController
|
||||
@allowed_configs = case @config
|
||||
when 'facebook'
|
||||
%w[FB_APP_ID FB_VERIFY_TOKEN FB_APP_SECRET IG_VERIFY_TOKEN FACEBOOK_API_VERSION ENABLE_MESSENGER_CHANNEL_HUMAN_AGENT]
|
||||
when 'microsoft'
|
||||
%w[AZURE_APP_ID AZURE_APP_SECRET]
|
||||
when 'email'
|
||||
['MAILER_INBOUND_EMAIL_DOMAIN']
|
||||
else
|
||||
|
||||
@@ -47,8 +47,10 @@ class WidgetsController < ActionController::Base
|
||||
def build_contact
|
||||
return if @contact.present?
|
||||
|
||||
@contact_inbox, @token = build_contact_inbox_with_token(@web_widget, additional_attributes)
|
||||
@contact = @contact_inbox.contact
|
||||
ActiveRecord::Base.connected_to(role: :writing) do
|
||||
@contact_inbox, @token = build_contact_inbox_with_token(@web_widget, additional_attributes)
|
||||
@contact = @contact_inbox.contact
|
||||
end
|
||||
end
|
||||
|
||||
def ensure_account_is_active
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
module TimezoneHelper
|
||||
# ActiveSupport TimeZone is not aware of the current time, so ActiveSupport::Timezone[offset]
|
||||
# would return the timezone without considering day light savings. To get the correct timezone,
|
||||
# this method uses zone.now.utc_offset for comparison as referenced in the issues below
|
||||
#
|
||||
# https://github.com/rails/rails/pull/22243
|
||||
# https://github.com/rails/rails/issues/21501
|
||||
# https://github.com/rails/rails/issues/7297
|
||||
def timezone_name_from_offset(offset)
|
||||
return 'UTC' if offset.blank?
|
||||
|
||||
offset_in_seconds = offset.to_f * 3600
|
||||
matching_zone = ActiveSupport::TimeZone.all.find do |zone|
|
||||
zone.now.utc_offset == offset_in_seconds
|
||||
end
|
||||
|
||||
return matching_zone.name if matching_zone
|
||||
end
|
||||
end
|
||||
@@ -7,17 +7,79 @@
|
||||
]"
|
||||
>
|
||||
<slot />
|
||||
<chat-list-header
|
||||
:page-title="pageTitle"
|
||||
:has-applied-filters="hasAppliedFilters"
|
||||
:has-active-folders="hasActiveFolders"
|
||||
:active-status="activeStatus"
|
||||
@add-folders="onClickOpenAddFoldersModal"
|
||||
@delete-folders="onClickOpenDeleteFoldersModal"
|
||||
@filters-modal="onToggleAdvanceFiltersModal"
|
||||
@reset-filters="resetAndFetchData"
|
||||
@basic-filter-change="onBasicFilterChange"
|
||||
/>
|
||||
<div
|
||||
class="flex items-center justify-between px-4 py-0"
|
||||
:class="{
|
||||
'pb-3 border-b border-slate-75 dark:border-slate-700':
|
||||
hasAppliedFiltersOrActiveFolders,
|
||||
}"
|
||||
>
|
||||
<div class="flex max-w-[85%] justify-center items-center">
|
||||
<h1
|
||||
class="text-xl font-medium break-words truncate text-black-900 dark:text-slate-100"
|
||||
:title="pageTitle"
|
||||
>
|
||||
{{ pageTitle }}
|
||||
</h1>
|
||||
<span
|
||||
v-if="!hasAppliedFiltersOrActiveFolders"
|
||||
class="p-1 my-0.5 mx-1 rounded-md capitalize bg-slate-50 dark:bg-slate-800 text-xxs text-slate-600 dark:text-slate-300"
|
||||
>
|
||||
{{ $t(`CHAT_LIST.CHAT_STATUS_FILTER_ITEMS.${activeStatus}.TEXT`) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1">
|
||||
<div v-if="hasAppliedFilters && !hasActiveFolders">
|
||||
<woot-button
|
||||
v-tooltip.top-end="$t('FILTER.CUSTOM_VIEWS.ADD.SAVE_BUTTON')"
|
||||
size="tiny"
|
||||
variant="smooth"
|
||||
color-scheme="secondary"
|
||||
icon="save"
|
||||
@click="onClickOpenAddFoldersModal"
|
||||
/>
|
||||
<woot-button
|
||||
v-tooltip.top-end="$t('FILTER.CLEAR_BUTTON_LABEL')"
|
||||
size="tiny"
|
||||
variant="smooth"
|
||||
color-scheme="alert"
|
||||
icon="dismiss-circle"
|
||||
@click="resetAndFetchData"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="hasActiveFolders">
|
||||
<woot-button
|
||||
v-tooltip.top-end="$t('FILTER.CUSTOM_VIEWS.EDIT.EDIT_BUTTON')"
|
||||
size="tiny"
|
||||
variant="smooth"
|
||||
color-scheme="secondary"
|
||||
icon="edit"
|
||||
@click="onToggleAdvanceFiltersModal"
|
||||
/>
|
||||
<woot-button
|
||||
v-tooltip.top-end="$t('FILTER.CUSTOM_VIEWS.DELETE.DELETE_BUTTON')"
|
||||
size="tiny"
|
||||
variant="smooth"
|
||||
color-scheme="alert"
|
||||
icon="delete"
|
||||
@click="onClickOpenDeleteFoldersModal"
|
||||
/>
|
||||
</div>
|
||||
<woot-button
|
||||
v-else
|
||||
v-tooltip.right="$t('FILTER.TOOLTIP_LABEL')"
|
||||
variant="smooth"
|
||||
color-scheme="secondary"
|
||||
icon="filter"
|
||||
size="tiny"
|
||||
@click="onToggleAdvanceFiltersModal"
|
||||
/>
|
||||
<conversation-basic-filter
|
||||
v-if="!hasAppliedFiltersOrActiveFolders"
|
||||
@changeFilter="onBasicFilterChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<add-custom-views
|
||||
v-if="showAddFoldersModal"
|
||||
@@ -111,15 +173,6 @@
|
||||
@updateFolder="onUpdateSavedFilter"
|
||||
/>
|
||||
</woot-modal>
|
||||
<woot-modal
|
||||
:show.sync="showCustomSnoozeModal"
|
||||
:on-close="hideCustomSnoozeModal"
|
||||
>
|
||||
<custom-snooze-modal
|
||||
@close="hideCustomSnoozeModal"
|
||||
@choose-time="chooseSnoozeTime"
|
||||
/>
|
||||
</woot-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -127,8 +180,8 @@
|
||||
import { mapGetters } from 'vuex';
|
||||
import VirtualList from 'vue-virtual-scroll-list';
|
||||
|
||||
import ChatListHeader from './ChatListHeader.vue';
|
||||
import ConversationAdvancedFilter from './widgets/conversation/ConversationAdvancedFilter.vue';
|
||||
import ConversationBasicFilter from './widgets/conversation/ConversationBasicFilter.vue';
|
||||
import ChatTypeTabs from './widgets/ChatTypeTabs.vue';
|
||||
import ConversationItem from './ConversationItem.vue';
|
||||
import timeMixin from '../mixins/time';
|
||||
@@ -152,15 +205,10 @@ import {
|
||||
isOnUnattendedView,
|
||||
} from '../store/modules/conversations/helpers/actionHelpers';
|
||||
import { CONVERSATION_EVENTS } from '../helper/AnalyticsHelper/events';
|
||||
import { CMD_SNOOZE_CONVERSATION } from 'dashboard/routes/dashboard/commands/commandBarBusEvents';
|
||||
import { findSnoozeTime } from 'dashboard/helper/snoozeHelpers';
|
||||
import { getUnixTime } from 'date-fns';
|
||||
import CustomSnoozeModal from 'dashboard/components/CustomSnoozeModal.vue';
|
||||
import IntersectionObserver from './IntersectionObserver.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ChatListHeader,
|
||||
AddCustomViews,
|
||||
ChatTypeTabs,
|
||||
// eslint-disable-next-line vue/no-unused-components
|
||||
@@ -168,9 +216,9 @@ export default {
|
||||
ConversationAdvancedFilter,
|
||||
DeleteCustomViews,
|
||||
ConversationBulkActions,
|
||||
ConversationBasicFilter,
|
||||
IntersectionObserver,
|
||||
VirtualList,
|
||||
CustomSnoozeModal,
|
||||
},
|
||||
mixins: [
|
||||
timeMixin,
|
||||
@@ -247,7 +295,6 @@ export default {
|
||||
root: this.$refs.conversationList,
|
||||
rootMargin: '100px 0px 100px 0px',
|
||||
},
|
||||
showCustomSnoozeModal: false,
|
||||
|
||||
itemComponent: ConversationItem,
|
||||
// virtualListExtraProps is to pass the props to the conversationItem component.
|
||||
@@ -282,13 +329,12 @@ export default {
|
||||
campaigns: 'campaigns/getAllCampaigns',
|
||||
labels: 'labels/getLabels',
|
||||
selectedConversations: 'bulkActions/getSelectedConversationIds',
|
||||
contextMenuChatId: 'getContextMenuChatId',
|
||||
}),
|
||||
hasAppliedFilters() {
|
||||
return this.appliedFilters.length !== 0;
|
||||
},
|
||||
hasActiveFolders() {
|
||||
return Boolean(this.activeFolder && this.foldersId !== 0);
|
||||
return this.activeFolder && this.foldersId !== 0;
|
||||
},
|
||||
hasAppliedFiltersOrActiveFolders() {
|
||||
return this.hasAppliedFilters || this.hasActiveFolders;
|
||||
@@ -512,11 +558,6 @@ export default {
|
||||
bus.$on('fetch_conversation_stats', () => {
|
||||
this.$store.dispatch('conversationStats/get', this.conversationFilters);
|
||||
});
|
||||
|
||||
bus.$on(CMD_SNOOZE_CONVERSATION, this.onCmdSnoozeConversation);
|
||||
},
|
||||
beforeDestroy() {
|
||||
bus.$off(CMD_SNOOZE_CONVERSATION, this.onCmdSnoozeConversation);
|
||||
},
|
||||
methods: {
|
||||
updateVirtualListProps(key, value) {
|
||||
@@ -987,49 +1028,12 @@ export default {
|
||||
allSelectedConversationsStatus(status) {
|
||||
if (!this.selectedConversations.length) return false;
|
||||
return this.selectedConversations.every(item => {
|
||||
return this.$store.getters.getConversationById(item)?.status === status;
|
||||
return this.$store.getters.getConversationById(item).status === status;
|
||||
});
|
||||
},
|
||||
onContextMenuToggle(state) {
|
||||
this.isContextMenuOpen = state;
|
||||
},
|
||||
onCmdSnoozeConversation(snoozeType) {
|
||||
if (snoozeType === wootConstants.SNOOZE_OPTIONS.UNTIL_CUSTOM_TIME) {
|
||||
this.showCustomSnoozeModal = true;
|
||||
} else {
|
||||
this.toggleStatus(
|
||||
wootConstants.STATUS_TYPE.SNOOZED,
|
||||
findSnoozeTime(snoozeType) || null
|
||||
);
|
||||
}
|
||||
},
|
||||
chooseSnoozeTime(customSnoozeTime) {
|
||||
this.showCustomSnoozeModal = false;
|
||||
if (customSnoozeTime) {
|
||||
this.toggleStatus(
|
||||
wootConstants.STATUS_TYPE.SNOOZED,
|
||||
getUnixTime(customSnoozeTime)
|
||||
);
|
||||
}
|
||||
},
|
||||
toggleStatus(status, snoozedUntil) {
|
||||
this.$store
|
||||
.dispatch('toggleStatus', {
|
||||
conversationId: this.currentChat?.id || this.contextMenuChatId,
|
||||
status,
|
||||
snoozedUntil,
|
||||
})
|
||||
.then(() => {
|
||||
this.$store.dispatch('setContextMenuChatId', null);
|
||||
this.showAlert(this.$t('CONVERSATION.CHANGE_STATUS'));
|
||||
});
|
||||
},
|
||||
hideCustomSnoozeModal() {
|
||||
// if we select custom snooze and then the custom snooze modal is open
|
||||
// Then if the custom snooze modal is closed and set the context menu chat id to null
|
||||
this.$store.dispatch('setContextMenuChatId', null);
|
||||
this.showCustomSnoozeModal = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
<script setup>
|
||||
import { computed } from 'vue';
|
||||
import ConversationBasicFilter from './widgets/conversation/ConversationBasicFilter.vue';
|
||||
|
||||
const props = defineProps({
|
||||
pageTitle: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
hasAppliedFilters: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
hasActiveFolders: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
},
|
||||
activeStatus: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
});
|
||||
|
||||
const emits = defineEmits([
|
||||
'add-folders',
|
||||
'delete-folders',
|
||||
'reset-filters',
|
||||
'basic-filter-change',
|
||||
'filters-modal',
|
||||
]);
|
||||
|
||||
const onBasicFilterChange = (value, type) => {
|
||||
emits('basic-filter-change', value, type);
|
||||
};
|
||||
|
||||
const hasAppliedFiltersOrActiveFolders = computed(() => {
|
||||
return props.hasAppliedFilters || props.hasActiveFolders;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="flex items-center justify-between px-4 py-0"
|
||||
:class="{
|
||||
'pb-3 border-b border-slate-75 dark:border-slate-700':
|
||||
hasAppliedFiltersOrActiveFolders,
|
||||
}"
|
||||
>
|
||||
<div class="flex max-w-[85%] justify-center items-center">
|
||||
<h1
|
||||
class="text-xl font-medium break-words truncate text-black-900 dark:text-slate-100"
|
||||
:title="pageTitle"
|
||||
>
|
||||
{{ pageTitle }}
|
||||
</h1>
|
||||
<span
|
||||
v-if="!hasAppliedFiltersOrActiveFolders"
|
||||
class="p-1 my-0.5 mx-1 rounded-md capitalize bg-slate-50 dark:bg-slate-800 text-xxs text-slate-600 dark:text-slate-300"
|
||||
>
|
||||
{{ $t(`CHAT_LIST.CHAT_STATUS_FILTER_ITEMS.${activeStatus}.TEXT`) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="flex items-center gap-1">
|
||||
<div v-if="hasAppliedFilters && !hasActiveFolders">
|
||||
<woot-button
|
||||
v-tooltip.top-end="$t('FILTER.CUSTOM_VIEWS.ADD.SAVE_BUTTON')"
|
||||
size="tiny"
|
||||
variant="smooth"
|
||||
color-scheme="secondary"
|
||||
icon="save"
|
||||
@click="emits('add-folders')"
|
||||
/>
|
||||
<woot-button
|
||||
v-tooltip.top-end="$t('FILTER.CLEAR_BUTTON_LABEL')"
|
||||
size="tiny"
|
||||
variant="smooth"
|
||||
color-scheme="alert"
|
||||
icon="dismiss-circle"
|
||||
@click="emits('reset-filters')"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="hasActiveFolders">
|
||||
<woot-button
|
||||
v-tooltip.top-end="$t('FILTER.CUSTOM_VIEWS.EDIT.EDIT_BUTTON')"
|
||||
size="tiny"
|
||||
variant="smooth"
|
||||
color-scheme="secondary"
|
||||
icon="edit"
|
||||
@click="emits('filters-modal')"
|
||||
/>
|
||||
<woot-button
|
||||
v-tooltip.top-end="$t('FILTER.CUSTOM_VIEWS.DELETE.DELETE_BUTTON')"
|
||||
size="tiny"
|
||||
variant="smooth"
|
||||
color-scheme="alert"
|
||||
icon="delete"
|
||||
@click="emits('delete-folders')"
|
||||
/>
|
||||
</div>
|
||||
<woot-button
|
||||
v-else
|
||||
v-tooltip.right="$t('FILTER.TOOLTIP_LABEL')"
|
||||
variant="smooth"
|
||||
color-scheme="secondary"
|
||||
icon="filter"
|
||||
size="tiny"
|
||||
@click="emits('filters-modal')"
|
||||
/>
|
||||
<conversation-basic-filter
|
||||
v-if="!hasAppliedFiltersOrActiveFolders"
|
||||
@changeFilter="onBasicFilterChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -73,13 +73,25 @@
|
||||
</woot-dropdown-item>
|
||||
</woot-dropdown-menu>
|
||||
</div>
|
||||
<woot-modal
|
||||
:show.sync="showCustomSnoozeModal"
|
||||
:on-close="hideCustomSnoozeModal"
|
||||
>
|
||||
<custom-snooze-modal
|
||||
@close="hideCustomSnoozeModal"
|
||||
@choose-time="chooseSnoozeTime"
|
||||
/>
|
||||
</woot-modal>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { getUnixTime } from 'date-fns';
|
||||
import { mapGetters } from 'vuex';
|
||||
import alertMixin from 'shared/mixins/alertMixin';
|
||||
import CustomSnoozeModal from 'dashboard/components/CustomSnoozeModal.vue';
|
||||
import keyboardEventListenerMixins from 'shared/mixins/keyboardEventListenerMixins';
|
||||
import { findSnoozeTime } from 'dashboard/helper/snoozeHelpers';
|
||||
import WootDropdownItem from 'shared/components/ui/dropdown/DropdownItem.vue';
|
||||
import WootDropdownMenu from 'shared/components/ui/dropdown/DropdownMenu.vue';
|
||||
|
||||
@@ -87,12 +99,14 @@ import wootConstants from 'dashboard/constants/globals';
|
||||
import {
|
||||
CMD_REOPEN_CONVERSATION,
|
||||
CMD_RESOLVE_CONVERSATION,
|
||||
CMD_SNOOZE_CONVERSATION,
|
||||
} from '../../routes/dashboard/commands/commandBarBusEvents';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
WootDropdownItem,
|
||||
WootDropdownMenu,
|
||||
CustomSnoozeModal,
|
||||
},
|
||||
mixins: [alertMixin, keyboardEventListenerMixins],
|
||||
props: { conversationId: { type: [String, Number], required: true } },
|
||||
@@ -101,6 +115,7 @@ export default {
|
||||
isLoading: false,
|
||||
showActionsDropdown: false,
|
||||
STATUS_TYPE: wootConstants.STATUS_TYPE,
|
||||
showCustomSnoozeModal: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
@@ -128,10 +143,12 @@ export default {
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
bus.$on(CMD_SNOOZE_CONVERSATION, this.onCmdSnoozeConversation);
|
||||
bus.$on(CMD_REOPEN_CONVERSATION, this.onCmdOpenConversation);
|
||||
bus.$on(CMD_RESOLVE_CONVERSATION, this.onCmdResolveConversation);
|
||||
},
|
||||
destroyed() {
|
||||
bus.$off(CMD_SNOOZE_CONVERSATION, this.onCmdSnoozeConversation);
|
||||
bus.$off(CMD_REOPEN_CONVERSATION, this.onCmdOpenConversation);
|
||||
bus.$off(CMD_RESOLVE_CONVERSATION, this.onCmdResolveConversation);
|
||||
},
|
||||
@@ -184,6 +201,28 @@ export default {
|
||||
// error
|
||||
}
|
||||
},
|
||||
onCmdSnoozeConversation(snoozeType) {
|
||||
if (snoozeType === wootConstants.SNOOZE_OPTIONS.UNTIL_CUSTOM_TIME) {
|
||||
this.showCustomSnoozeModal = true;
|
||||
} else {
|
||||
this.toggleStatus(
|
||||
this.STATUS_TYPE.SNOOZED,
|
||||
findSnoozeTime(snoozeType) || null
|
||||
);
|
||||
}
|
||||
},
|
||||
chooseSnoozeTime(customSnoozeTime) {
|
||||
this.showCustomSnoozeModal = false;
|
||||
if (customSnoozeTime) {
|
||||
this.toggleStatus(
|
||||
this.STATUS_TYPE.SNOOZED,
|
||||
getUnixTime(customSnoozeTime)
|
||||
);
|
||||
}
|
||||
},
|
||||
hideCustomSnoozeModal() {
|
||||
this.showCustomSnoozeModal = false;
|
||||
},
|
||||
onCmdOpenConversation() {
|
||||
this.toggleStatus(this.STATUS_TYPE.OPEN);
|
||||
},
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
:header-title="$t('SIDEBAR_ITEMS.CHANGE_ACCOUNTS')"
|
||||
:header-content="$t('SIDEBAR_ITEMS.SELECTOR_SUBTITLE')"
|
||||
/>
|
||||
<div class="px-8 py-4">
|
||||
<div class="px-8 pt-4 pb-8">
|
||||
<div
|
||||
v-for="account in currentUser.accounts"
|
||||
:id="`account-${account.id}`"
|
||||
@@ -45,10 +45,10 @@
|
||||
|
||||
<div
|
||||
v-if="globalConfig.createNewAccountFromDashboard"
|
||||
class="flex justify-end items-center px-8 pb-8 pt-4 gap-2"
|
||||
class="flex justify-end items-center p-8 gap-2"
|
||||
>
|
||||
<button
|
||||
class="button success large expanded nice w-full"
|
||||
class="button success large expanded nice"
|
||||
@click="$emit('show-create-account-modal')"
|
||||
>
|
||||
{{ $t('CREATE_ACCOUNT.NEW_ACCOUNT') }}
|
||||
|
||||
@@ -103,7 +103,6 @@
|
||||
:status="chat.status"
|
||||
:inbox-id="inbox.id"
|
||||
:priority="chat.priority"
|
||||
:chat-id="chat.id"
|
||||
:has-unread-messages="hasUnread"
|
||||
@update-conversation="onUpdateConversation"
|
||||
@assign-agent="onAssignAgent"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
/>
|
||||
</template>
|
||||
<menu-item
|
||||
v-if="showSnooze"
|
||||
v-if="show(snoozeOption.key)"
|
||||
:option="snoozeOption"
|
||||
variant="icon"
|
||||
@click="snoozeConversation()"
|
||||
@@ -86,10 +86,6 @@ export default {
|
||||
},
|
||||
mixins: [agentMixin],
|
||||
props: {
|
||||
chatId: {
|
||||
type: Number,
|
||||
default: null,
|
||||
},
|
||||
status: {
|
||||
type: String,
|
||||
default: '',
|
||||
@@ -209,10 +205,6 @@ export default {
|
||||
...this.filteredAgentOnAvailability,
|
||||
];
|
||||
},
|
||||
showSnooze() {
|
||||
// Don't show snooze if the conversation is already snoozed/resolved/pending
|
||||
return this.status === wootConstants.STATUS_TYPE.OPEN;
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$store.dispatch('inboxAssignableAgents/fetch', [this.inboxId]);
|
||||
@@ -221,8 +213,7 @@ export default {
|
||||
toggleStatus(status, snoozedUntil) {
|
||||
this.$emit('update-conversation', status, snoozedUntil);
|
||||
},
|
||||
async snoozeConversation() {
|
||||
await this.$store.dispatch('setContextMenuChatId', this.chatId);
|
||||
snoozeConversation() {
|
||||
const ninja = document.querySelector('ninja-keys');
|
||||
ninja.open({ parent: 'snooze_conversation' });
|
||||
},
|
||||
|
||||
@@ -1,16 +1,9 @@
|
||||
<template>
|
||||
<div class="phone-input--wrap relative">
|
||||
<div
|
||||
class="flex items-center dark:bg-slate-900 justify-start rounded-md border border-solid"
|
||||
:class="
|
||||
error
|
||||
? 'border border-solid border-red-400 dark:border-red-400 mb-1'
|
||||
: 'mb-4 border-slate-200 dark:border-slate-600'
|
||||
"
|
||||
>
|
||||
<div class="phone-input" :class="{ 'has-error': error }">
|
||||
<div
|
||||
class="cursor-pointer py-2 pr-1.5 pl-2 rounded-tl-md rounded-bl-md flex items-center justify-center gap-1.5 bg-slate-25 dark:bg-slate-700 h-10 w-14"
|
||||
@click.prevent="toggleCountryDropdown"
|
||||
@click="toggleCountryDropdown"
|
||||
>
|
||||
<h5 v-if="activeCountry" class="mb-0">
|
||||
{{ activeCountry.emoji }}
|
||||
@@ -20,15 +13,14 @@
|
||||
</div>
|
||||
<span
|
||||
v-if="activeDialCode"
|
||||
class="flex bg-white dark:bg-slate-900 text-slate-800 dark:text-slate-100 font-normal text-base leading-normal py-2 pl-2 pr-0"
|
||||
class="flex bg-white dark:bg-slate-900 font-medium text-slate-800 dark:text-slate-100 font-normal text-base leading-normal py-2 pl-2 pr-0"
|
||||
>
|
||||
{{ activeDialCode }}
|
||||
</span>
|
||||
<input
|
||||
ref="phoneNumberInput"
|
||||
:value="phoneNumber"
|
||||
type="tel"
|
||||
class="!mb-0 !rounded-tl-none !rounded-bl-none !border-0 font-normal !w-full dark:!bg-slate-900 text-base !px-1.5 placeholder:font-normal"
|
||||
class="phone-input--field"
|
||||
:placeholder="placeholder"
|
||||
:readonly="readonly"
|
||||
:style="styles"
|
||||
@@ -36,36 +28,24 @@
|
||||
@blur="onBlur"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="showDropdown"
|
||||
ref="dropdown"
|
||||
v-on-clickaway="onOutsideClick"
|
||||
tabindex="0"
|
||||
class="z-10 absolute h-60 w-[12.5rem] shadow-md overflow-y-auto top-10 rounded px-0 pt-0 pb-1 bg-white dark:bg-slate-900"
|
||||
@keydown.prevent.up="moveUp"
|
||||
@keydown.prevent.down="moveDown"
|
||||
@keydown.prevent.enter="
|
||||
onSelectCountry(filteredCountriesBySearch[selectedIndex])
|
||||
"
|
||||
>
|
||||
<div class="top-0 sticky bg-white dark:bg-slate-900 p-1">
|
||||
<div v-if="showDropdown" ref="dropdown" class="country-dropdown">
|
||||
<div class="dropdown-search--wrap">
|
||||
<input
|
||||
ref="searchbar"
|
||||
v-model="searchCountry"
|
||||
type="text"
|
||||
placeholder="Search"
|
||||
class="!h-8 !mb-0 !text-sm !border !border-solid !border-slate-200 dark:!border-slate-600"
|
||||
@input="onSearchCountry"
|
||||
class="dropdown-search"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-for="(country, index) in filteredCountriesBySearch"
|
||||
ref="dropdownItem"
|
||||
:key="index"
|
||||
class="flex items-center h-7 py-0 px-1 cursor-pointer hover:bg-slate-50 dark:hover:bg-slate-700"
|
||||
class="country-dropdown--item"
|
||||
:class="{
|
||||
'bg-slate-50 dark:bg-slate-700': country.id === activeCountryCode,
|
||||
'bg-slate-25 dark:bg-slate-800': index === selectedIndex,
|
||||
active: country.id === activeCountryCode,
|
||||
focus: index === selectedIndex,
|
||||
}"
|
||||
@click="onSelectCountry(country)"
|
||||
>
|
||||
@@ -94,8 +74,10 @@
|
||||
<script>
|
||||
import countries from 'shared/constants/countries.js';
|
||||
import parsePhoneNumber from 'libphonenumber-js';
|
||||
import keyboardEventListenerMixins from 'shared/mixins/keyboardEventListenerMixins';
|
||||
|
||||
export default {
|
||||
mixins: [keyboardEventListenerMixins],
|
||||
props: {
|
||||
value: {
|
||||
type: [String, Number],
|
||||
@@ -120,6 +102,15 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
countries: [
|
||||
{
|
||||
name: 'Select Country',
|
||||
dial_code: '',
|
||||
emoji: '',
|
||||
id: '',
|
||||
},
|
||||
...countries,
|
||||
],
|
||||
selectedIndex: -1,
|
||||
showDropdown: false,
|
||||
searchCountry: '',
|
||||
@@ -129,20 +120,6 @@ export default {
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
countries() {
|
||||
return [
|
||||
{
|
||||
name: this.dropdownFirstItemName,
|
||||
dial_code: '',
|
||||
emoji: '',
|
||||
id: '',
|
||||
},
|
||||
...countries,
|
||||
];
|
||||
},
|
||||
dropdownFirstItemName() {
|
||||
return this.activeCountryCode ? 'Clear selection' : 'Select Country';
|
||||
},
|
||||
filteredCountriesBySearch() {
|
||||
return this.countries.filter(country => {
|
||||
const { name, dial_code, id } = country;
|
||||
@@ -177,8 +154,12 @@ export default {
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
window.addEventListener('mouseup', this.onOutsideClick);
|
||||
this.setActiveCountry();
|
||||
},
|
||||
beforeDestroy() {
|
||||
window.removeEventListener('mouseup', this.onOutsideClick);
|
||||
},
|
||||
methods: {
|
||||
onOutsideClick(e) {
|
||||
if (
|
||||
@@ -196,14 +177,28 @@ export default {
|
||||
onBlur(e) {
|
||||
this.$emit('blur', e.target.value);
|
||||
},
|
||||
onSearchCountry() {
|
||||
// Reset selected index to 0
|
||||
this.selectedIndex = 0;
|
||||
dropdownItem() {
|
||||
if (!this.showDropdown) return [];
|
||||
return Array.from(
|
||||
this.$refs.dropdown.querySelectorAll(
|
||||
'div.country-dropdown div.country-dropdown--item'
|
||||
)
|
||||
);
|
||||
},
|
||||
focusedItem() {
|
||||
if (!this.showDropdown) return [];
|
||||
return Array.from(
|
||||
this.$refs.dropdown.querySelectorAll('div.country-dropdown div.focus')
|
||||
);
|
||||
},
|
||||
focusedItemIndex() {
|
||||
if (!this.showDropdown) return -1;
|
||||
return Array.from(this.dropdownItem()).indexOf(this.focusedItem()[0]);
|
||||
},
|
||||
moveUp() {
|
||||
if (!this.showDropdown) return;
|
||||
this.selectedIndex = Math.max(this.selectedIndex - 1, 0);
|
||||
this.scrollToSelected();
|
||||
this.$refs.dropdown.scrollTop = this.focusedItemIndex() * 28 - 56;
|
||||
},
|
||||
moveDown() {
|
||||
if (!this.showDropdown) return;
|
||||
@@ -211,27 +206,14 @@ export default {
|
||||
this.selectedIndex + 1,
|
||||
this.filteredCountriesBySearch.length - 1
|
||||
);
|
||||
this.scrollToSelected();
|
||||
},
|
||||
scrollToSelected() {
|
||||
this.$nextTick(() => {
|
||||
const dropdown = this.$refs.dropdown;
|
||||
const selectedItem = this.$refs.dropdownItem[this.selectedIndex];
|
||||
const dropdownSearchbarHeight = 40;
|
||||
if (selectedItem) {
|
||||
const selectedItemTop = selectedItem.offsetTop;
|
||||
dropdown.scrollTop = selectedItemTop - dropdownSearchbarHeight;
|
||||
}
|
||||
});
|
||||
this.$refs.dropdown.scrollTop = this.focusedItemIndex() * 28 - 56;
|
||||
},
|
||||
onSelectCountry(country) {
|
||||
if (!country || !this.showDropdown) return;
|
||||
this.activeCountryCode = country.id;
|
||||
this.searchCountry = '';
|
||||
this.activeDialCode = country.dial_code;
|
||||
this.$emit('setCode', country.dial_code);
|
||||
this.closeDropdown();
|
||||
this.$refs.phoneNumberInput.focus();
|
||||
},
|
||||
setActiveCountry() {
|
||||
const { phoneNumber } = this;
|
||||
@@ -242,6 +224,33 @@ export default {
|
||||
this.activeDialCode = number.countryCallingCode;
|
||||
}
|
||||
},
|
||||
getKeyboardEvents() {
|
||||
return {
|
||||
ArrowUp: {
|
||||
action: e => {
|
||||
e.preventDefault();
|
||||
this.moveUp();
|
||||
},
|
||||
allowOnFocusedInput: true,
|
||||
},
|
||||
ArrowDown: {
|
||||
action: e => {
|
||||
e.preventDefault();
|
||||
this.moveDown();
|
||||
},
|
||||
allowOnFocusedInput: true,
|
||||
},
|
||||
Enter: {
|
||||
action: e => {
|
||||
e.preventDefault();
|
||||
this.onSelectCountry(
|
||||
this.filteredCountriesBySearch[this.selectedIndex]
|
||||
);
|
||||
},
|
||||
allowOnFocusedInput: true,
|
||||
},
|
||||
};
|
||||
},
|
||||
toggleCountryDropdown() {
|
||||
this.showDropdown = !this.showDropdown;
|
||||
this.selectedIndex = -1;
|
||||
@@ -258,3 +267,46 @@ export default {
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
.phone-input--wrap {
|
||||
.phone-input {
|
||||
@apply flex items-center dark:bg-slate-900 justify-start mb-4 rounded-md border border-solid border-slate-200 dark:border-slate-600;
|
||||
|
||||
&.has-error {
|
||||
@apply border border-solid border-red-400 dark:border-red-400;
|
||||
}
|
||||
}
|
||||
|
||||
.phone-input--field {
|
||||
@apply mb-0 rounded-tl-none rounded-bl-none border-0 w-full dark:bg-slate-900 text-base px-1.5;
|
||||
|
||||
&::placeholder {
|
||||
@apply font-normal;
|
||||
}
|
||||
}
|
||||
|
||||
.country-dropdown {
|
||||
@apply z-10 absolute h-60 w-[12.5rem] shadow-md overflow-y-auto top-10 rounded px-0 pt-0 pb-1 bg-white dark:bg-slate-900;
|
||||
|
||||
.dropdown-search--wrap {
|
||||
@apply top-0 sticky bg-white dark:bg-slate-900 p-1;
|
||||
|
||||
.dropdown-search {
|
||||
@apply h-8 mb-0 text-sm border border-solid border-slate-200 dark:border-slate-600;
|
||||
}
|
||||
}
|
||||
|
||||
.country-dropdown--item {
|
||||
@apply flex items-center h-7 py-0 px-1 cursor-pointer hover:bg-slate-50 dark:hover:bg-slate-700;
|
||||
|
||||
&.active {
|
||||
@apply bg-slate-50 dark:bg-slate-700;
|
||||
}
|
||||
|
||||
&.focus {
|
||||
@apply bg-slate-25 dark:bg-slate-800;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -52,22 +52,8 @@ export const validateLoggedInRoutes = (to, user, roleWiseRoutes) => {
|
||||
return null;
|
||||
};
|
||||
|
||||
export const isAConversationRoute = (
|
||||
routeName,
|
||||
includeBase = false,
|
||||
includeExtended = true
|
||||
) => {
|
||||
const baseRoutes = [
|
||||
'home',
|
||||
'conversation_mentions',
|
||||
'conversation_unattended',
|
||||
'inbox_dashboard',
|
||||
'label_conversations',
|
||||
'team_conversations',
|
||||
'folder_conversations',
|
||||
'conversation_participating',
|
||||
];
|
||||
const extendedRoutes = [
|
||||
export const isAConversationRoute = routeName =>
|
||||
[
|
||||
'inbox_conversation',
|
||||
'conversation_through_mentions',
|
||||
'conversation_through_unattended',
|
||||
@@ -76,15 +62,7 @@ export const isAConversationRoute = (
|
||||
'conversations_through_team',
|
||||
'conversations_through_folders',
|
||||
'conversation_through_participating',
|
||||
];
|
||||
|
||||
const routes = [
|
||||
...(includeBase ? baseRoutes : []),
|
||||
...(includeExtended ? extendedRoutes : []),
|
||||
];
|
||||
|
||||
return routes.includes(routeName);
|
||||
};
|
||||
].includes(routeName);
|
||||
|
||||
export const getConversationDashboardRoute = routeName => {
|
||||
switch (routeName) {
|
||||
|
||||
@@ -66,29 +66,3 @@ export const snoozedReopenTime = snoozedUntil => {
|
||||
}
|
||||
return snoozedUntil ? format(date, 'd MMM, h.mmaaa') : null;
|
||||
};
|
||||
export const snoozedReopenTimeToTimestamp = snoozedUntil => {
|
||||
return snoozedUntil ? getUnixTime(new Date(snoozedUntil)) : null;
|
||||
};
|
||||
export const shortenSnoozeTime = snoozedUntil => {
|
||||
if (!snoozedUntil) {
|
||||
return null;
|
||||
}
|
||||
const unitMap = {
|
||||
minutes: 'm',
|
||||
minute: 'm',
|
||||
hours: 'h',
|
||||
hour: 'h',
|
||||
days: 'd',
|
||||
day: 'd',
|
||||
months: 'mo',
|
||||
month: 'mo',
|
||||
years: 'y',
|
||||
year: 'y',
|
||||
};
|
||||
const shortenTime = snoozedUntil.replace(
|
||||
/\s(minute|hour|day|month|year)s?\b/gi,
|
||||
(match, unit) => unitMap[unit.toLowerCase()] || match
|
||||
);
|
||||
|
||||
return shortenTime;
|
||||
};
|
||||
|
||||
@@ -106,51 +106,6 @@ describe('isAConversationRoute', () => {
|
||||
expect(isAConversationRoute('conversations_through_team')).toBe(true);
|
||||
expect(isAConversationRoute('dashboard')).toBe(false);
|
||||
});
|
||||
|
||||
it('returns true if base conversation route name is provided and includeBase is true', () => {
|
||||
expect(isAConversationRoute('home', true)).toBe(true);
|
||||
expect(isAConversationRoute('conversation_mentions', true)).toBe(true);
|
||||
expect(isAConversationRoute('conversation_unattended', true)).toBe(true);
|
||||
expect(isAConversationRoute('inbox_dashboard', true)).toBe(true);
|
||||
expect(isAConversationRoute('label_conversations', true)).toBe(true);
|
||||
expect(isAConversationRoute('team_conversations', true)).toBe(true);
|
||||
expect(isAConversationRoute('folder_conversations', true)).toBe(true);
|
||||
expect(isAConversationRoute('conversation_participating', true)).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false if base conversation route name is provided and includeBase is false', () => {
|
||||
expect(isAConversationRoute('home', false)).toBe(false);
|
||||
expect(isAConversationRoute('conversation_mentions', false)).toBe(false);
|
||||
expect(isAConversationRoute('conversation_unattended', false)).toBe(false);
|
||||
expect(isAConversationRoute('inbox_dashboard', false)).toBe(false);
|
||||
expect(isAConversationRoute('label_conversations', false)).toBe(false);
|
||||
expect(isAConversationRoute('team_conversations', false)).toBe(false);
|
||||
expect(isAConversationRoute('folder_conversations', false)).toBe(false);
|
||||
expect(isAConversationRoute('conversation_participating', false)).toBe(
|
||||
false
|
||||
);
|
||||
});
|
||||
|
||||
it('returns true if base conversation route name is provided and includeBase and includeExtended is true', () => {
|
||||
expect(isAConversationRoute('home', true, true)).toBe(true);
|
||||
expect(isAConversationRoute('conversation_mentions', true, true)).toBe(
|
||||
true
|
||||
);
|
||||
expect(isAConversationRoute('conversation_unattended', true, true)).toBe(
|
||||
true
|
||||
);
|
||||
expect(isAConversationRoute('inbox_dashboard', true, true)).toBe(true);
|
||||
expect(isAConversationRoute('label_conversations', true, true)).toBe(true);
|
||||
expect(isAConversationRoute('team_conversations', true, true)).toBe(true);
|
||||
expect(isAConversationRoute('folder_conversations', true, true)).toBe(true);
|
||||
expect(isAConversationRoute('conversation_participating', true, true)).toBe(
|
||||
true
|
||||
);
|
||||
});
|
||||
|
||||
it('returns false if base conversation route name is not provided', () => {
|
||||
expect(isAConversationRoute('')).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getConversationDashboardRoute', () => {
|
||||
|
||||
@@ -5,8 +5,6 @@ import {
|
||||
findStartOfNextMonth,
|
||||
findNextDay,
|
||||
setHoursToNine,
|
||||
snoozedReopenTimeToTimestamp,
|
||||
shortenSnoozeTime,
|
||||
} from '../snoozeHelpers';
|
||||
|
||||
describe('#Snooze Helpers', () => {
|
||||
@@ -109,41 +107,4 @@ describe('#Snooze Helpers', () => {
|
||||
expect(findNextDay(today)).toEqual(nextDay);
|
||||
});
|
||||
});
|
||||
|
||||
describe('snoozedReopenTimeToTimestamp', () => {
|
||||
it('should return timestamp if snoozedUntil is not nil', () => {
|
||||
expect(snoozedReopenTimeToTimestamp('2023-06-07T09:00:00.000Z')).toEqual(
|
||||
1686128400
|
||||
);
|
||||
});
|
||||
it('should return nil if snoozedUntil is nil', () => {
|
||||
expect(snoozedReopenTimeToTimestamp(null)).toEqual(null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('shortenSnoozeTime', () => {
|
||||
it('should return shortened time if snoozedUntil is not nil and day is passed', () => {
|
||||
expect(shortenSnoozeTime('1 day')).toEqual('1d');
|
||||
});
|
||||
|
||||
it('should return shortened time if snoozedUntil is not nil and month is passed', () => {
|
||||
expect(shortenSnoozeTime('1 month')).toEqual('1mo');
|
||||
});
|
||||
|
||||
it('should return shortened time if snoozedUntil is not nil and year is passed', () => {
|
||||
expect(shortenSnoozeTime('1 year')).toEqual('1y');
|
||||
});
|
||||
|
||||
it('should return shortened time if snoozedUntil is not nil and hour is passed', () => {
|
||||
expect(shortenSnoozeTime('1 hour')).toEqual('1h');
|
||||
});
|
||||
|
||||
it('should return shortened time if snoozedUntil is not nil and minutes is passed', () => {
|
||||
expect(shortenSnoozeTime('1 minutes')).toEqual('1m');
|
||||
});
|
||||
|
||||
it('should return nil if snoozedUntil is nil', () => {
|
||||
expect(shortenSnoozeTime(null)).toEqual(null);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"AGENT_LIST_LOADING": "Loading agents",
|
||||
"UPDATE": {
|
||||
"CHANGE_STATUS": "Change status",
|
||||
"SNOOZE_UNTIL": "Snooze",
|
||||
"SNOOZE_UNTIL_NEXT_REPLY": "Snooze until next reply.",
|
||||
"UPDATE_SUCCESFUL": "Conversation status updated successfully.",
|
||||
"UPDATE_FAILED": "Failed to update conversations. Please try again."
|
||||
},
|
||||
|
||||
@@ -84,7 +84,6 @@
|
||||
"CONFIRM": {
|
||||
"TITLE": "Export Contacts",
|
||||
"MESSAGE": "Are you sure you want to export all contacts?",
|
||||
"FILTERED_MESSAGE": "Are you sure you want to export all the filtered contacts?",
|
||||
"YES": "Yes, Export",
|
||||
"NO": "No, Cancel"
|
||||
}
|
||||
|
||||
@@ -107,7 +107,6 @@
|
||||
"GENERAL": "General",
|
||||
"REPORTS": "Reports",
|
||||
"CONVERSATION": "Conversation",
|
||||
"BULK_ACTIONS": "Bulk Actions",
|
||||
"CHANGE_ASSIGNEE": "Change Assignee",
|
||||
"CHANGE_PRIORITY": "Change Priority",
|
||||
"CHANGE_TEAM": "Change Team",
|
||||
|
||||
@@ -109,8 +109,7 @@
|
||||
"SLA_MISSED_FIRST_RESPONSE": "A conversation misses first response SLA",
|
||||
"SLA_MISSED_NEXT_RESPONSE": "A conversation misses next response SLA",
|
||||
"SLA_MISSED_RESOLUTION": "A conversation misses resolution SLA"
|
||||
},
|
||||
"BROWSER_PERMISSION": "Enable push notifications for your browser so you’re able to receive them"
|
||||
}
|
||||
},
|
||||
"API": {
|
||||
"UPDATE_SUCCESS": "Your notification preferences are updated successfully",
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"AGENT_LIST_LOADING": "جاري تحميل الوكلاء",
|
||||
"UPDATE": {
|
||||
"CHANGE_STATUS": "تغيير الحالة",
|
||||
"SNOOZE_UNTIL": "غفوة",
|
||||
"SNOOZE_UNTIL_NEXT_REPLY": "غفوة حتى الرد القادم.",
|
||||
"UPDATE_SUCCESFUL": "تم تحديث حالة المحادثة بنجاح.",
|
||||
"UPDATE_FAILED": "Failed to update conversations. Please try again."
|
||||
},
|
||||
|
||||
@@ -84,7 +84,6 @@
|
||||
"CONFIRM": {
|
||||
"TITLE": "تصدير جهات الاتصال",
|
||||
"MESSAGE": "Are you sure you want to export all contacts?",
|
||||
"FILTERED_MESSAGE": "Are you sure you want to export all the filtered contacts?",
|
||||
"YES": "نعم, قم بالتصدير",
|
||||
"NO": "نعم, إلغاء"
|
||||
}
|
||||
|
||||
@@ -107,7 +107,6 @@
|
||||
"GENERAL": "عام",
|
||||
"REPORTS": "التقارير",
|
||||
"CONVERSATION": "المحادثات",
|
||||
"BULK_ACTIONS": "Bulk Actions",
|
||||
"CHANGE_ASSIGNEE": "تغيير المحال إليه",
|
||||
"CHANGE_PRIORITY": "تغيير الأولوية",
|
||||
"CHANGE_TEAM": "تغيير الفريق",
|
||||
|
||||
@@ -109,8 +109,7 @@
|
||||
"SLA_MISSED_FIRST_RESPONSE": "A conversation misses first response SLA",
|
||||
"SLA_MISSED_NEXT_RESPONSE": "A conversation misses next response SLA",
|
||||
"SLA_MISSED_RESOLUTION": "A conversation misses resolution SLA"
|
||||
},
|
||||
"BROWSER_PERMISSION": "Enable push notifications for your browser so you’re able to receive them"
|
||||
}
|
||||
},
|
||||
"API": {
|
||||
"UPDATE_SUCCESS": "يتم تحديث إعدادات الإشعارات بنجاح",
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"AGENT_LIST_LOADING": "Loading agents",
|
||||
"UPDATE": {
|
||||
"CHANGE_STATUS": "Change status",
|
||||
"SNOOZE_UNTIL": "Snooze",
|
||||
"SNOOZE_UNTIL_NEXT_REPLY": "Snooze until next reply.",
|
||||
"UPDATE_SUCCESFUL": "Conversation status updated successfully.",
|
||||
"UPDATE_FAILED": "Failed to update conversations. Please try again."
|
||||
},
|
||||
|
||||
@@ -84,7 +84,6 @@
|
||||
"CONFIRM": {
|
||||
"TITLE": "Export Contacts",
|
||||
"MESSAGE": "Are you sure you want to export all contacts?",
|
||||
"FILTERED_MESSAGE": "Are you sure you want to export all the filtered contacts?",
|
||||
"YES": "Yes, Export",
|
||||
"NO": "No, Cancel"
|
||||
}
|
||||
|
||||
@@ -107,7 +107,6 @@
|
||||
"GENERAL": "General",
|
||||
"REPORTS": "Reports",
|
||||
"CONVERSATION": "Разговор",
|
||||
"BULK_ACTIONS": "Bulk Actions",
|
||||
"CHANGE_ASSIGNEE": "Change Assignee",
|
||||
"CHANGE_PRIORITY": "Change Priority",
|
||||
"CHANGE_TEAM": "Change Team",
|
||||
|
||||
@@ -109,8 +109,7 @@
|
||||
"SLA_MISSED_FIRST_RESPONSE": "A conversation misses first response SLA",
|
||||
"SLA_MISSED_NEXT_RESPONSE": "A conversation misses next response SLA",
|
||||
"SLA_MISSED_RESOLUTION": "A conversation misses resolution SLA"
|
||||
},
|
||||
"BROWSER_PERMISSION": "Enable push notifications for your browser so you’re able to receive them"
|
||||
}
|
||||
},
|
||||
"API": {
|
||||
"UPDATE_SUCCESS": "Your notification preferences are updated successfully",
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
{
|
||||
"FILTER": {
|
||||
"TITLE": "Filtre de converses",
|
||||
"SUBTITLE": "Afegiu els vostres filtres a continuació i premeu 'Aplicar filtres' per eliminar el desordre del xat.",
|
||||
"EDIT_CUSTOM_FILTER": "Edita la carpeta",
|
||||
"CUSTOM_VIEWS_SUBTITLE": "Afegeix o elimina filtres i actualitza la teva carpeta.",
|
||||
"ADD_NEW_FILTER": "Afegeix un filtre",
|
||||
"FILTER_DELETE_ERROR": "Vaja, sembla que no podem desar res! Afegiu almenys un filtre per desar-lo.",
|
||||
"SUBTITLE": "Add your filters below and hit 'Apply filters' to cut through the chat clutter.",
|
||||
"EDIT_CUSTOM_FILTER": "Edit Folder",
|
||||
"CUSTOM_VIEWS_SUBTITLE": "Add or remove filters and update your folder.",
|
||||
"ADD_NEW_FILTER": "Add filter",
|
||||
"FILTER_DELETE_ERROR": "Oops, looks like we can't save nothing! Please add at least one filter to save it.",
|
||||
"SUBMIT_BUTTON_LABEL": "Aplicar filtres",
|
||||
"UPDATE_BUTTON_LABEL": "Actualitza la carpeta",
|
||||
"UPDATE_BUTTON_LABEL": "Update folder",
|
||||
"CANCEL_BUTTON_LABEL": "Cancel·la",
|
||||
"CLEAR_BUTTON_LABEL": "Esborra els filtres",
|
||||
"FOLDER_LABEL": "Nom de la carpeta",
|
||||
"FOLDER_QUERY_LABEL": "Consulta de carpeta",
|
||||
"CLEAR_BUTTON_LABEL": "Clear filters",
|
||||
"FOLDER_LABEL": "Folder Name",
|
||||
"FOLDER_QUERY_LABEL": "Folder Query",
|
||||
"EMPTY_VALUE_ERROR": "El valor és necessari.",
|
||||
"TOOLTIP_LABEL": "Filtre de converses",
|
||||
"QUERY_DROPDOWN_LABELS": {
|
||||
@@ -27,8 +27,8 @@
|
||||
"is_not_present": "No és present",
|
||||
"is_greater_than": "És més gran que",
|
||||
"is_less_than": "És més petit que",
|
||||
"days_before": "És x dies abans",
|
||||
"starts_with": "Comença amb"
|
||||
"days_before": "Is x days before",
|
||||
"starts_with": "Starts with"
|
||||
},
|
||||
"ATTRIBUTE_LABELS": {
|
||||
"TRUE": "Cert",
|
||||
@@ -36,66 +36,66 @@
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"STATUS": "Estat",
|
||||
"ASSIGNEE_NAME": "Nom assignat",
|
||||
"INBOX_NAME": "Nom de la safata d'entrada",
|
||||
"TEAM_NAME": "Nom de l'equip",
|
||||
"CONVERSATION_IDENTIFIER": "Identificador de conversa",
|
||||
"CAMPAIGN_NAME": "Nom de la campanya",
|
||||
"ASSIGNEE_NAME": "Assignee name",
|
||||
"INBOX_NAME": "Inbox name",
|
||||
"TEAM_NAME": "Team name",
|
||||
"CONVERSATION_IDENTIFIER": "Conversation identifier",
|
||||
"CAMPAIGN_NAME": "Campaign name",
|
||||
"LABELS": "Etiquetes",
|
||||
"BROWSER_LANGUAGE": "Idioma del navegador",
|
||||
"PRIORITY": "Prioritat",
|
||||
"COUNTRY_NAME": "Nom del país",
|
||||
"REFERER_LINK": "Enllaç de referència",
|
||||
"CUSTOM_ATTRIBUTE_LIST": "Llista",
|
||||
"BROWSER_LANGUAGE": "Browser language",
|
||||
"PRIORITY": "Priority",
|
||||
"COUNTRY_NAME": "Country name",
|
||||
"REFERER_LINK": "Referer link",
|
||||
"CUSTOM_ATTRIBUTE_LIST": "List",
|
||||
"CUSTOM_ATTRIBUTE_TEXT": "Llista",
|
||||
"CUSTOM_ATTRIBUTE_NUMBER": "Número",
|
||||
"CUSTOM_ATTRIBUTE_LINK": "Enllaç",
|
||||
"CUSTOM_ATTRIBUTE_CHECKBOX": "Casella de selecció",
|
||||
"CREATED_AT": "Creat a",
|
||||
"LAST_ACTIVITY": "Última activitat"
|
||||
"CUSTOM_ATTRIBUTE_CHECKBOX": "Checkbox",
|
||||
"CREATED_AT": "Created at",
|
||||
"LAST_ACTIVITY": "Last activity"
|
||||
},
|
||||
"GROUPS": {
|
||||
"STANDARD_FILTERS": "Filtres estàndard",
|
||||
"ADDITIONAL_FILTERS": "Filtres addicionals",
|
||||
"CUSTOM_ATTRIBUTES": "Atributs personalitzats"
|
||||
"STANDARD_FILTERS": "Standard filters",
|
||||
"ADDITIONAL_FILTERS": "Additional filters",
|
||||
"CUSTOM_ATTRIBUTES": "Custom attributes"
|
||||
},
|
||||
"CUSTOM_VIEWS": {
|
||||
"ADD": {
|
||||
"TITLE": "Vols desar aquest filtre?",
|
||||
"LABEL": "Anomena aquest filtre",
|
||||
"PLACEHOLDER": "Anomena el teu filtre per referir-lo més endavant.",
|
||||
"ERROR_MESSAGE": "El nom és obligatori.",
|
||||
"SAVE_BUTTON": "Desa el filtre",
|
||||
"TITLE": "Do you want to save this filter?",
|
||||
"LABEL": "Name this filter",
|
||||
"PLACEHOLDER": "Name your filter to refer it later.",
|
||||
"ERROR_MESSAGE": "Name is required.",
|
||||
"SAVE_BUTTON": "Save filter",
|
||||
"CANCEL_BUTTON": "Cancel·la",
|
||||
"API_FOLDERS": {
|
||||
"SUCCESS_MESSAGE": "Carpeta creada correctament.",
|
||||
"ERROR_MESSAGE": "S'ha produït un error en crear la carpeta."
|
||||
"SUCCESS_MESSAGE": "Folder created successfully.",
|
||||
"ERROR_MESSAGE": "Error while creating folder."
|
||||
},
|
||||
"API_SEGMENTS": {
|
||||
"SUCCESS_MESSAGE": "Segment creat correctament.",
|
||||
"ERROR_MESSAGE": "S'ha produït un error en crear el segment."
|
||||
"SUCCESS_MESSAGE": "Segment created successfully.",
|
||||
"ERROR_MESSAGE": "Error while creating segment."
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"EDIT_BUTTON": "Editar la carpeta"
|
||||
"EDIT_BUTTON": "Edit folder"
|
||||
},
|
||||
"DELETE": {
|
||||
"DELETE_BUTTON": "Suprimir el filtre",
|
||||
"DELETE_BUTTON": "Delete filter",
|
||||
"MODAL": {
|
||||
"CONFIRM": {
|
||||
"TITLE": "Confirmar la supressió",
|
||||
"MESSAGE": "Esteu segur que suprimiu el filtre ",
|
||||
"YES": "Sí, esborra",
|
||||
"NO": "No, guarda-ho"
|
||||
"TITLE": "Confirm deletion",
|
||||
"MESSAGE": "Are you sure to delete the filter ",
|
||||
"YES": "Yes, delete",
|
||||
"NO": "No, keep it"
|
||||
}
|
||||
},
|
||||
"API_FOLDERS": {
|
||||
"SUCCESS_MESSAGE": "La carpeta s'ha suprimit correctament.",
|
||||
"ERROR_MESSAGE": "S'ha produït un error en suprimir la carpeta."
|
||||
"SUCCESS_MESSAGE": "Folder deleted successfully.",
|
||||
"ERROR_MESSAGE": "Error while deleting folder."
|
||||
},
|
||||
"API_SEGMENTS": {
|
||||
"SUCCESS_MESSAGE": "El segment s'ha suprimit correctament.",
|
||||
"ERROR_MESSAGE": "S'ha produït un error en suprimir el segment."
|
||||
"SUCCESS_MESSAGE": "Segment deleted successfully.",
|
||||
"ERROR_MESSAGE": "Error while deleting segment."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"AGENT_BOTS": {
|
||||
"HEADER": "Bots",
|
||||
"LOADING_EDITOR": "S'està carregant l'editor...",
|
||||
"LOADING_EDITOR": "Loading editor...",
|
||||
"HEADER_BTN_TXT": "Add bot configuration",
|
||||
"SIDEBAR_TXT": "<p><b>Agent Bots</b> <p>Agent Bots are like the most fabulous members of your team. They can handle the small stuff, so you can focus on the stuff that matters. Give them a try.</p> <p> You can manage your bots from this page or create new ones using the 'Add bot configuraton' button.</p> <p> Open the <a href=\"https://www.chatwoot.com/hc/chatwoot-user-guide-cloud-version/articles/1677497472-how-to-use-agent-bots\" target=\"blank\">Agent bots handbook</a> in another tab for a helping hand.</p>",
|
||||
"CSML_BOT_EDITOR": {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"HEADER": "Agents",
|
||||
"HEADER_BTN_TXT": "Afegir Agent",
|
||||
"LOADING": "S'està recollint la llista d'agents",
|
||||
"SIDEBAR_TXT": "<p><b>Agents</b></p> <p> Un <b>Agent</b> és membre del vostre equip d’atenció al client. </p><p> Els agents podran veure i respondre missatges dels teus usuaris. La llista mostra tots els agents que hi ha actualment al teu compte.</p><p> Fer clic a <b>Afegeix Agent</b> per afegir un agent nou. L´agent que afegeixes rebrà un correu electrònic amb un enllaç de confirmació per activar el seu compte, després del qual podrà accedir a Chatwoot i respondre als missatges. </p><p> L´accés a les funcions de Chatwoot es basa en els següents rols.</p><p> <b>Agent</b> - Els agents amb aquesta funció només poden accedir a les bústies d´entrada, als informes i a les converses. Poden assignar converses a altres agents o a ells mateixos i resoldre converses.</p><p> <b>Administrador</b> - L´administrador tindrà accés a totes les funcions de Chatwoot habilitades per al teu compte, inclosa la configuració, juntament amb tots els privilegis dels agents normals.</p>",
|
||||
"SIDEBAR_TXT": "<p><b>Agents</b></p> <p> Un <b>Agent</b> és membre del vostre equip d’atenció al client. </p><p> Els agents podran veure i respondre missatges dels teus usuaris. La llista mostra tots els agents que hi ha actualment al teu compte.</p><p> Fer clic a <b>Afegeix Agent</b> per afegir un agent nou. L’agent que afegeixes rebrà un correu electrònic amb un enllaç de confirmació per activar el seu compte, després del qual podrà accedir a Chatwoot i respondre als missatges. </p><p> L’accés a les funcions de Chatwoot es basa en els següents rols.</p><p> <b>Agent</b> - Els agents amb aquesta funció només poden accedir a les bústies d’entrada, als informes i a les converses. Poden assignar converses a altres agents o a ells mateixos i resoldre converses.</p><p> <b>Administrador</b> - L'administrador tindrà accés a totes les funcions de Chatwoot habilitades per al teu compte, inclosa la configuració, juntament amb tots els privilegis dels agents normals.</p>",
|
||||
"AGENT_TYPES": {
|
||||
"ADMINISTRATOR": "Administrador/a",
|
||||
"AGENT": "Agent"
|
||||
@@ -31,7 +31,7 @@
|
||||
"AGENT_TYPE": {
|
||||
"LABEL": "Tipus d'Agent",
|
||||
"PLACEHOLDER": "Selecciona un tipus",
|
||||
"ERROR": "El rol és necessari"
|
||||
"ERROR": "El tipus d'Agent és necessari"
|
||||
},
|
||||
"EMAIL": {
|
||||
"LABEL": "Adreça de correu electrònic",
|
||||
@@ -76,8 +76,8 @@
|
||||
},
|
||||
"AGENT_AVAILABILITY": {
|
||||
"LABEL": "Disponibilitat",
|
||||
"PLACEHOLDER": "Seleccioneu un estat de disponibilitat",
|
||||
"ERROR": "Es requereix disponibilitat"
|
||||
"PLACEHOLDER": "Please select an availability status",
|
||||
"ERROR": "Availability is required"
|
||||
},
|
||||
"SUBMIT": "Editar l'agent"
|
||||
},
|
||||
@@ -111,7 +111,7 @@
|
||||
"PLACEHOLDER": {
|
||||
"AGENT": "Cerca agents",
|
||||
"TEAM": "Cerca equips",
|
||||
"INPUT": "Cerca agents"
|
||||
"INPUT": "Search for agents"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"DESC": "Audit Logs are trails for events and actions in a Chatwoot System.",
|
||||
"TABLE_HEADER": [
|
||||
"User",
|
||||
"Temps",
|
||||
"Action",
|
||||
"Adreça IP"
|
||||
]
|
||||
},
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"AGENT_LIST_LOADING": "Loading agents",
|
||||
"UPDATE": {
|
||||
"CHANGE_STATUS": "Change status",
|
||||
"SNOOZE_UNTIL": "Snooze",
|
||||
"SNOOZE_UNTIL_NEXT_REPLY": "Snooze until next reply.",
|
||||
"UPDATE_SUCCESFUL": "Conversation status updated successfully.",
|
||||
"UPDATE_FAILED": "Failed to update conversations. Please try again."
|
||||
},
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
"CREATED_AT": "Created at"
|
||||
},
|
||||
"BUTTONS": {
|
||||
"ADD": "Afegir",
|
||||
"ADD": "Add",
|
||||
"EDIT": "Edita",
|
||||
"DELETE": "Esborrar"
|
||||
},
|
||||
|
||||
@@ -1,75 +1,75 @@
|
||||
{
|
||||
"CANNED_MGMT": {
|
||||
"HEADER": "Respostes predeterminades",
|
||||
"HEADER_BTN_TXT": "Afegir resposta predeterminada",
|
||||
"LOADING": "S'estan recollint les respostes predeterminades...",
|
||||
"HEADER_BTN_TXT": "Add canned response",
|
||||
"LOADING": "Fetching canned responses...",
|
||||
"SEARCH_404": "No hi ha cap resposta que coincideixi amb aquesta consulta.",
|
||||
"SIDEBAR_TXT": "<p><b>Respostes predeterminades</b> </p><p> Les respostes predeterminades són plantilles de respostes escrites prèviament que us ajuden a respondre ràpidament a una conversa. Per inserir una resposta predefinida durant un xat, els agents poden escriure un codi curt precedit d'un caràcter '/'. </p><p> Pots gestionar les teves respostes predefinides des d'aquesta pàgina o crear-ne de noves mitjançant el botó \"Afegeix una resposta predefinida\".</p><p>Obre el <a target=\"_blank\" href=\"https: //www.chatwoot.com/hc/chatwoot-user-guide-cloud-version/articles/1677501325-how-to-create-saved-reply-templates-with-canned-responses\">Manual de respostes llaunes</a> en una altra pestanya per ajudar-te.</p><p>També, fes una ullada al nou <a href=\"https://www.chatwoot.com/tools/canned-responses-library\" target=\"_blank \">Biblioteca de respostes predeterminades</a>.</p>",
|
||||
"SIDEBAR_TXT": "<p><b>Canned Responses</b> </p><p> Canned Responses are pre-written reply templates that help you quickly respond to a conversation. To insert a canned response during a chat, agents can type a short code preceded by a '/' character. </p><p> You can manage your canned responses from this page or create new ones using the \"Add canned response\" button.</p><p>Open the <a target=\"_blank\" href=\"https://www.chatwoot.com/hc/chatwoot-user-guide-cloud-version/articles/1677501325-how-to-create-saved-reply-templates-with-canned-responses\">Canned Responses handbook</a> in another tab for a helping hand.</p><p>Also, check out the all-new <a href=\"https://www.chatwoot.com/tools/canned-responses-library\" target=\"_blank\">Canned Responses Library</a>.</p>",
|
||||
"LIST": {
|
||||
"404": "No hi ha respostes predeterminades disponibles en aquest compte.",
|
||||
"TITLE": "Gestiona les respostes predeterminades",
|
||||
"DESC": "Les respostes predeterminades són plantilles de resposta predefinides que es poden utilitzar per enviar ràpidament respostes a les converses.",
|
||||
"DESC": "Canned Responses are predefined reply templates which can be used to quickly send out replies to conversations.",
|
||||
"TABLE_HEADER": [
|
||||
"Codi curt",
|
||||
"Short code",
|
||||
"Contingut",
|
||||
"Accions"
|
||||
]
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Afegir resposta predeterminada",
|
||||
"DESC": "Les respostes predeterminades són plantilles de resposta predefinides que es poden utilitzar per enviar ràpidament respostes a les converses.",
|
||||
"TITLE": "Add canned response",
|
||||
"DESC": "Canned Responses are predefined reply templates which can be used to quickly send out replies to conversations.",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel·la",
|
||||
"FORM": {
|
||||
"SHORT_CODE": {
|
||||
"LABEL": "Codi curt",
|
||||
"PLACEHOLDER": "Introduïu un codi curt.",
|
||||
"ERROR": "És necessari el codi curt."
|
||||
"LABEL": "Short code",
|
||||
"PLACEHOLDER": "Please enter a short code.",
|
||||
"ERROR": "Short Code is required."
|
||||
},
|
||||
"CONTENT": {
|
||||
"LABEL": "Missatge",
|
||||
"PLACEHOLDER": "Escriviu el missatge que voleu desar com a plantilla per utilitzar-lo més tard.",
|
||||
"ERROR": "El missatge és obligatori."
|
||||
"PLACEHOLDER": "Please write the message you want to save as a template to use later.",
|
||||
"ERROR": "Message is required."
|
||||
},
|
||||
"SUBMIT": "Envia"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Resposta predeterminada afegida correctament.",
|
||||
"SUCCESS_MESSAGE": "Canned response added successfully.",
|
||||
"ERROR_MESSAGE": "No s'ha pogut connectar amb el servidor Woot. Torna-ho a provar més endavant"
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Edita la resposta predeterminada",
|
||||
"TITLE": "Edit canned response",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel·la",
|
||||
"FORM": {
|
||||
"SHORT_CODE": {
|
||||
"LABEL": "Codi curt",
|
||||
"PLACEHOLDER": "Introduïu un codi curt.",
|
||||
"ERROR": "És necessari el codi curt."
|
||||
"LABEL": "Short code",
|
||||
"PLACEHOLDER": "Please enter a shortcode.",
|
||||
"ERROR": "Short code is required."
|
||||
},
|
||||
"CONTENT": {
|
||||
"LABEL": "Missatge",
|
||||
"PLACEHOLDER": "Escriviu el missatge que voleu desar com a plantilla per utilitzar-lo més tard.",
|
||||
"ERROR": "El missatge és obligatori."
|
||||
"PLACEHOLDER": "Please write the message you want to save as a template to use later.",
|
||||
"ERROR": "Message is required."
|
||||
},
|
||||
"SUBMIT": "Envia"
|
||||
},
|
||||
"BUTTON_TEXT": "Edita",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Resposta predeterminada actualitzada correctament.",
|
||||
"SUCCESS_MESSAGE": "Canned response is updated successfully.",
|
||||
"ERROR_MESSAGE": "No s'ha pogut connectar amb el servidor Woot. Torna-ho a provar més endavant"
|
||||
}
|
||||
},
|
||||
"DELETE": {
|
||||
"BUTTON_TEXT": "Esborra",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Resposta predeterminada eliminada correctament.",
|
||||
"SUCCESS_MESSAGE": "Canned response deleted successfully.",
|
||||
"ERROR_MESSAGE": "No s'ha pogut connectar amb el servidor Woot. Torna-ho a provar més endavant"
|
||||
},
|
||||
"CONFIRM": {
|
||||
"TITLE": "Confirma l'esborrat",
|
||||
"TITLE": "Confirm deletion",
|
||||
"MESSAGE": "N'estas segur ",
|
||||
"YES": "Sí, esborra ",
|
||||
"NO": "No, mantén-la "
|
||||
"YES": "Yes, delete ",
|
||||
"NO": "No, keep "
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
},
|
||||
"TAB_HEADING": "Converses",
|
||||
"MENTION_HEADING": "Mencions",
|
||||
"UNATTENDED_HEADING": "Sense assistència",
|
||||
"UNATTENDED_HEADING": "Unattended",
|
||||
"SEARCH": {
|
||||
"INPUT": "Cerca persones, xats, respostes desades .."
|
||||
},
|
||||
@@ -36,27 +36,27 @@
|
||||
}
|
||||
},
|
||||
"VIEW_FILTER": "Veure",
|
||||
"SORT_TOOLTIP_LABEL": "Ordena les converses",
|
||||
"SORT_TOOLTIP_LABEL": "Sort conversations",
|
||||
"CHAT_SORT": {
|
||||
"STATUS": "Estat",
|
||||
"ORDER_BY": "Ordena per"
|
||||
"ORDER_BY": "Order by"
|
||||
},
|
||||
"CHAT_TIME_STAMP": {
|
||||
"CREATED": {
|
||||
"LATEST": "Creat",
|
||||
"OLDEST": "Creat per:"
|
||||
"LATEST": "Created",
|
||||
"OLDEST": "Created at:"
|
||||
},
|
||||
"LAST_ACTIVITY": {
|
||||
"NOT_ACTIVE": "Darrera activitat:",
|
||||
"ACTIVE": "Darrera activitat"
|
||||
"NOT_ACTIVE": "Last activity:",
|
||||
"ACTIVE": "Last activity"
|
||||
}
|
||||
},
|
||||
"SORT_ORDER_ITEMS": {
|
||||
"last_activity_at_asc": {
|
||||
"TEXT": "Última activitat: Més antic primer"
|
||||
"TEXT": "Last activity: Oldest first"
|
||||
},
|
||||
"last_activity_at_desc": {
|
||||
"TEXT": "Última activitat: La més nova primer"
|
||||
"TEXT": "Last activity: Newest first"
|
||||
},
|
||||
"created_at_desc": {
|
||||
"TEXT": "Created at: Newest first"
|
||||
@@ -99,15 +99,15 @@
|
||||
},
|
||||
"CHAT_SORT_BY_FILTER": {
|
||||
"TITLE": "Sort conversation",
|
||||
"DROPDOWN_TITLE": "Ordenat per",
|
||||
"DROPDOWN_TITLE": "Sort by",
|
||||
"ITEMS": {
|
||||
"LATEST": {
|
||||
"NAME": "Last activity at",
|
||||
"LABEL": "Last activity"
|
||||
},
|
||||
"CREATED_AT": {
|
||||
"NAME": "Creat per",
|
||||
"LABEL": "Creat per"
|
||||
"NAME": "Created at",
|
||||
"LABEL": "Created at"
|
||||
},
|
||||
"LAST_USER_MESSAGE_AT": {
|
||||
"NAME": "Last user message at",
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"INITIATED_FROM": "Iniciada des de",
|
||||
"INITIATED_AT": "Iniciada a les",
|
||||
"IP_ADDRESS": "Adreça IP",
|
||||
"CREATED_AT_LABEL": "Creat",
|
||||
"CREATED_AT_LABEL": "Created",
|
||||
"NEW_MESSAGE": "Nou missatge",
|
||||
"CONVERSATIONS": {
|
||||
"NO_RECORDS_FOUND": "No hi han converses prèvies associades a aquest contacte.",
|
||||
@@ -49,7 +49,7 @@
|
||||
"CUSTOM_ATTRIBUTES": "Atributs personalitzats",
|
||||
"CONTACT_LABELS": "Etiquetes de contactes",
|
||||
"PREVIOUS_CONVERSATIONS": "Converses prèvies",
|
||||
"NO_RECORDS_FOUND": "No s'han trobat atributs"
|
||||
"NO_RECORDS_FOUND": "No attributes found"
|
||||
}
|
||||
},
|
||||
"EDIT_CONTACT": {
|
||||
@@ -76,17 +76,16 @@
|
||||
"ERROR_MESSAGE": "S'ha produït un error; tornau-ho a provar"
|
||||
},
|
||||
"EXPORT_CONTACTS": {
|
||||
"BUTTON_LABEL": "Exporta",
|
||||
"TITLE": "Exporta contactes",
|
||||
"DESC": "Exporta contactes a través d'un fitxer CSV.",
|
||||
"BUTTON_LABEL": "Export",
|
||||
"TITLE": "Export Contacts",
|
||||
"DESC": "Export contacts to a CSV file.",
|
||||
"SUCCESS_MESSAGE": "Export is in progress, You will be notified via email when export file is ready to dowanlod.",
|
||||
"ERROR_MESSAGE": "S'ha produït un error; tornau-ho a provar",
|
||||
"CONFIRM": {
|
||||
"TITLE": "Exporta contactes",
|
||||
"MESSAGE": "Esteu segur que voleu exportar tots els contactes?",
|
||||
"FILTERED_MESSAGE": "Esteu segur que voleu exportar tots els contactes filtrats?",
|
||||
"YES": "Sí, Exporta",
|
||||
"NO": "No, cancel·la"
|
||||
"TITLE": "Export Contacts",
|
||||
"MESSAGE": "Are you sure you want to export all contacts?",
|
||||
"YES": "Yes, Export",
|
||||
"NO": "No, Cancel"
|
||||
}
|
||||
},
|
||||
"DELETE_NOTE": {
|
||||
@@ -152,13 +151,13 @@
|
||||
"COUNTRY": {
|
||||
"PLACEHOLDER": "Enter the country name",
|
||||
"LABEL": "Nom del país",
|
||||
"SELECT_PLACEHOLDER": "Selecciona",
|
||||
"SELECT_PLACEHOLDER": "Select",
|
||||
"REMOVE": "Suprimeix",
|
||||
"SELECT_COUNTRY": "Selecciona país"
|
||||
"SELECT_COUNTRY": "Select Country"
|
||||
},
|
||||
"CITY": {
|
||||
"PLACEHOLDER": "Introdueix el nom de la ciutat",
|
||||
"LABEL": "Nom de la ciutat"
|
||||
"PLACEHOLDER": "Enter the city name",
|
||||
"LABEL": "City Name"
|
||||
},
|
||||
"SOCIAL_PROFILES": {
|
||||
"FACEBOOK": {
|
||||
@@ -181,8 +180,8 @@
|
||||
},
|
||||
"DELETE_AVATAR": {
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "L'avatar del contacte s'ha suprimit correctament",
|
||||
"ERROR_MESSAGE": "No s'ha pogut esborrar l'avatar de contacte. Torneu-ho a provar."
|
||||
"SUCCESS_MESSAGE": "Contact avatar deleted successfully",
|
||||
"ERROR_MESSAGE": "Could not delete the contact avatar. Please try again later."
|
||||
}
|
||||
},
|
||||
"SUCCESS_MESSAGE": "Contacte guardat correctament",
|
||||
@@ -191,30 +190,30 @@
|
||||
"NEW_CONVERSATION": {
|
||||
"BUTTON_LABEL": "Inicia la conversa",
|
||||
"TITLE": "Nova conversació",
|
||||
"DESC": "Inicia una conversa nova enviant un missatge nou.",
|
||||
"DESC": "Start a new conversation by sending a new message.",
|
||||
"NO_INBOX": "Couldn't find an inbox to initiate a new conversation with this contact.",
|
||||
"FORM": {
|
||||
"TO": {
|
||||
"LABEL": "Per"
|
||||
"LABEL": "To"
|
||||
},
|
||||
"INBOX": {
|
||||
"LABEL": "Inbox",
|
||||
"PLACEHOLDER": "Trieu la safata d'entrada d'origen",
|
||||
"PLACEHOLDER": "Choose source inbox",
|
||||
"ERROR": "Select an inbox"
|
||||
},
|
||||
"SUBJECT": {
|
||||
"LABEL": "Assumpte",
|
||||
"PLACEHOLDER": "Assumpte",
|
||||
"LABEL": "Subject",
|
||||
"PLACEHOLDER": "Subject",
|
||||
"ERROR": "Subject can't be empty"
|
||||
},
|
||||
"MESSAGE": {
|
||||
"LABEL": "Missatge",
|
||||
"PLACEHOLDER": "Write your message here",
|
||||
"ERROR": "El missatge no pot estar buit"
|
||||
"ERROR": "Message can't be empty"
|
||||
},
|
||||
"ATTACHMENTS": {
|
||||
"SELECT": "Trieu fitxers",
|
||||
"HELP_TEXT": "Arrossegueu i deixeu anar fitxers aquí o trieu fitxers per adjuntar"
|
||||
"SELECT": "Choose files",
|
||||
"HELP_TEXT": "Drag and drop files here or choose files to attach"
|
||||
},
|
||||
"SUBMIT": "Send message",
|
||||
"CANCEL": "Cancel·la",
|
||||
@@ -228,10 +227,10 @@
|
||||
"FIELDS": "Contact fields",
|
||||
"SEARCH_BUTTON": "Cercar",
|
||||
"SEARCH_INPUT_PLACEHOLDER": "Cerca de contactes",
|
||||
"FILTER_CONTACTS": "Filtre",
|
||||
"FILTER_CONTACTS_SAVE": "Desa el filtre",
|
||||
"FILTER_CONTACTS_DELETE": "Suprimir el filtre",
|
||||
"FILTER_CONTACTS_EDIT": "Edita segment",
|
||||
"FILTER_CONTACTS": "Filter",
|
||||
"FILTER_CONTACTS_SAVE": "Save filter",
|
||||
"FILTER_CONTACTS_DELETE": "Delete filter",
|
||||
"FILTER_CONTACTS_EDIT": "Edit segment",
|
||||
"LIST": {
|
||||
"LOADING_MESSAGE": "Carregant contactes...",
|
||||
"404": "No hi ha cap contacte que coincideixi amb la vostra cerca 🔍",
|
||||
@@ -242,8 +241,8 @@
|
||||
"CONVERSATIONS": "Converses",
|
||||
"LAST_ACTIVITY": "Last Activity",
|
||||
"CREATED_AT": "Created At",
|
||||
"COUNTRY": "País",
|
||||
"CITY": "Ciutat",
|
||||
"COUNTRY": "Country",
|
||||
"CITY": "City",
|
||||
"SOCIAL_PROFILES": "Social Profiles",
|
||||
"COMPANY": "Companyia",
|
||||
"EMAIL_ADDRESS": "Adreça de correu electrònic"
|
||||
@@ -257,93 +256,93 @@
|
||||
},
|
||||
"REMINDER": {
|
||||
"ADD_BUTTON": {
|
||||
"BUTTON": "Afegir",
|
||||
"TITLE": "Shift + Enter per crear una tasca"
|
||||
"BUTTON": "Add",
|
||||
"TITLE": "Shift + Enter to create a task"
|
||||
},
|
||||
"FOOTER": {
|
||||
"DUE_DATE": "Data de venciment",
|
||||
"LABEL_TITLE": "Establir tipus"
|
||||
"DUE_DATE": "Due date",
|
||||
"LABEL_TITLE": "Set type"
|
||||
}
|
||||
},
|
||||
"NOTES": {
|
||||
"FETCHING_NOTES": "S'estan obtenint notes...",
|
||||
"FETCHING_NOTES": "Fetching notes...",
|
||||
"NOT_AVAILABLE": "There are no notes created for this contact",
|
||||
"HEADER": {
|
||||
"TITLE": "Notes"
|
||||
},
|
||||
"LIST": {
|
||||
"LABEL": "afegeix una nota"
|
||||
"LABEL": "added a note"
|
||||
},
|
||||
"ADD": {
|
||||
"BUTTON": "Afegir",
|
||||
"PLACEHOLDER": "Afegeix una nota",
|
||||
"TITLE": "Shift + Enter per crear una nota"
|
||||
"BUTTON": "Add",
|
||||
"PLACEHOLDER": "Add a note",
|
||||
"TITLE": "Shift + Enter to create a note"
|
||||
},
|
||||
"CONTENT_HEADER": {
|
||||
"DELETE": "Suprimeix la nota"
|
||||
"DELETE": "Delete note"
|
||||
}
|
||||
},
|
||||
"EVENTS": {
|
||||
"HEADER": {
|
||||
"TITLE": "Activitats"
|
||||
"TITLE": "Activities"
|
||||
},
|
||||
"BUTTON": {
|
||||
"PILL_BUTTON_NOTES": "notes",
|
||||
"PILL_BUTTON_EVENTS": "esdeveniment",
|
||||
"PILL_BUTTON_EVENTS": "events",
|
||||
"PILL_BUTTON_CONVO": "converses"
|
||||
}
|
||||
},
|
||||
"CUSTOM_ATTRIBUTES": {
|
||||
"ADD_BUTTON_TEXT": "Afegir atributs",
|
||||
"BUTTON": "Afegir atributs personalitzats",
|
||||
"NOT_AVAILABLE": "No hi ha atributs personalitzats disponibles per a aquest contacte.",
|
||||
"ADD_BUTTON_TEXT": "Add attributes",
|
||||
"BUTTON": "Add custom attribute",
|
||||
"NOT_AVAILABLE": "There are no custom attributes available for this contact.",
|
||||
"COPY_SUCCESSFUL": "S'ha copiat al porta-retalls amb èxit",
|
||||
"SHOW_MORE": "Mostra tots els atributs",
|
||||
"SHOW_LESS": "Mostra menys atributs",
|
||||
"SHOW_MORE": "Show all attributes",
|
||||
"SHOW_LESS": "Show less attributes",
|
||||
"ACTIONS": {
|
||||
"COPY": "Copia l'atribut",
|
||||
"DELETE": "Suprimeix l'atribut",
|
||||
"EDIT": "Edita l'atribut"
|
||||
"COPY": "Copy attribute",
|
||||
"DELETE": "Delete attribute",
|
||||
"EDIT": "Edit attribute"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Crear atribut personalitzat",
|
||||
"DESC": "Afegeix informació personalitzada a aquest contacte."
|
||||
"TITLE": "Create custom attribute",
|
||||
"DESC": "Add custom information to this contact."
|
||||
},
|
||||
"FORM": {
|
||||
"CREATE": "Afegir atribut",
|
||||
"CREATE": "Add attribute",
|
||||
"CANCEL": "Cancel·la",
|
||||
"NAME": {
|
||||
"LABEL": "Personalitza el nom de l'atribut",
|
||||
"PLACEHOLDER": "P. ex.: identificador de Shopify",
|
||||
"ERROR": "El nom de l'atribut personalitzat no és vàlid"
|
||||
"LABEL": "Custom attribute name",
|
||||
"PLACEHOLDER": "Eg: shopify id",
|
||||
"ERROR": "Invalid custom attribute name"
|
||||
},
|
||||
"VALUE": {
|
||||
"LABEL": "Attribute value",
|
||||
"PLACEHOLDER": "Eg: 11901 "
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Crear nou atribut ",
|
||||
"SUCCESS": "Atribut afegit correctament",
|
||||
"ERROR": "No es pot afegir l'atribut. Si us plau, intenta-ho més tard"
|
||||
"TITLE": "Create new attribute ",
|
||||
"SUCCESS": "Attribute added successfully",
|
||||
"ERROR": "Unable to add attribute. Please try again later"
|
||||
},
|
||||
"UPDATE": {
|
||||
"SUCCESS": "Atribut actualitzat correctament",
|
||||
"ERROR": "No es pot actualitzar l'atribut. Si us plau, intenta-ho més tard"
|
||||
"SUCCESS": "Attribute updated successfully",
|
||||
"ERROR": "Unable to update attribute. Please try again later"
|
||||
},
|
||||
"DELETE": {
|
||||
"SUCCESS": "Atribut esborrat correctament",
|
||||
"ERROR": "No es pot esborrar l'atribut. Si us plau, intenta-ho més tard"
|
||||
"SUCCESS": "Attribute deleted successfully",
|
||||
"ERROR": "Unable to delete attribute. Please try again later"
|
||||
},
|
||||
"ATTRIBUTE_SELECT": {
|
||||
"TITLE": "Afegir atributs",
|
||||
"PLACEHOLDER": "Cerca atributs",
|
||||
"NO_RESULT": "No s'han trobat atributs"
|
||||
"TITLE": "Add attributes",
|
||||
"PLACEHOLDER": "Search attributes",
|
||||
"NO_RESULT": "No attributes found"
|
||||
},
|
||||
"ATTRIBUTE_TYPE": {
|
||||
"LIST": {
|
||||
"PLACEHOLDER": "Selecciona valor",
|
||||
"SEARCH_INPUT_PLACEHOLDER": "Cerca valor",
|
||||
"NO_RESULT": "No s'ha trobat cap resultat"
|
||||
"PLACEHOLDER": "Select value",
|
||||
"SEARCH_INPUT_PLACEHOLDER": "Search value",
|
||||
"NO_RESULT": "No result found"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -366,7 +365,7 @@
|
||||
"HELP_LABEL": "To be kept"
|
||||
},
|
||||
"SUMMARY": {
|
||||
"TITLE": "Resum",
|
||||
"TITLE": "Summary",
|
||||
"DELETE_WARNING": "Contact of <strong>%{primaryContactName}</strong> will be deleted.",
|
||||
"ATTRIBUTE_WARNING": "Contact details of <strong>%{primaryContactName}</strong> will be copied to <strong>%{parentContactName}</strong>."
|
||||
},
|
||||
@@ -374,13 +373,13 @@
|
||||
"ERROR": "ERROR_MESSAGE"
|
||||
},
|
||||
"FORM": {
|
||||
"SUBMIT": " Fusiona contactes",
|
||||
"SUBMIT": " Merge contacts",
|
||||
"CANCEL": "Cancel·la",
|
||||
"CHILD_CONTACT": {
|
||||
"ERROR": "Seleccioneu un contacte fill per fusionar"
|
||||
"ERROR": "Select a child contact to merge"
|
||||
},
|
||||
"SUCCESS_MESSAGE": "Contacte fusionat correctament",
|
||||
"ERROR_MESSAGE": "No s'ha pogut fusionar els contactes, torna-ho a provar!"
|
||||
"SUCCESS_MESSAGE": "Contact merged successfully",
|
||||
"ERROR_MESSAGE": "Could not merge contacts, try again!"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,24 +28,24 @@
|
||||
"is_not_present": "No és present",
|
||||
"is_greater_than": "És més gran que",
|
||||
"is_lesser_than": "Is lesser than",
|
||||
"days_before": "És x dies abans"
|
||||
"days_before": "Is x days before"
|
||||
},
|
||||
"ATTRIBUTES": {
|
||||
"NAME": "Nom",
|
||||
"EMAIL": "Correu electrònic",
|
||||
"PHONE_NUMBER": "Número de telèfon",
|
||||
"IDENTIFIER": "Identifier",
|
||||
"CITY": "Ciutat",
|
||||
"COUNTRY": "País",
|
||||
"CUSTOM_ATTRIBUTE_LIST": "Llista",
|
||||
"CITY": "City",
|
||||
"COUNTRY": "Country",
|
||||
"CUSTOM_ATTRIBUTE_LIST": "List",
|
||||
"CUSTOM_ATTRIBUTE_TEXT": "Llista",
|
||||
"CUSTOM_ATTRIBUTE_NUMBER": "Número",
|
||||
"CUSTOM_ATTRIBUTE_LINK": "Enllaç",
|
||||
"CUSTOM_ATTRIBUTE_CHECKBOX": "Casella de selecció",
|
||||
"CUSTOM_ATTRIBUTE_CHECKBOX": "Checkbox",
|
||||
"CREATED_AT": "Created At",
|
||||
"LAST_ACTIVITY": "Last Activity",
|
||||
"REFERER_LINK": "Referrer link",
|
||||
"BLOCKED": "Blocat"
|
||||
"BLOCKED": "Blocked"
|
||||
},
|
||||
"GROUPS": {
|
||||
"STANDARD_FILTERS": "Standard Filters",
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"CONVERSATION": {
|
||||
"SELECT_A_CONVERSATION": "Si us plau, selecciona una conversa al panell de l’esquerra",
|
||||
"CSAT_REPLY_MESSAGE": "Si us plau, valoreu la conversa",
|
||||
"404": "Ho sentim, no podem trobar la conversa. Torneu-ho a provar",
|
||||
"SWITCH_VIEW_LAYOUT": "Canvia el disseny",
|
||||
"DASHBOARD_APP_TAB_MESSAGES": "Missatges",
|
||||
"UNVERIFIED_SESSION": "La identitat d'aquest usuari no està verificada",
|
||||
"CSAT_REPLY_MESSAGE": "Please rate the conversation",
|
||||
"404": "Sorry, we cannot find the conversation. Please try again",
|
||||
"SWITCH_VIEW_LAYOUT": "Switch the layout",
|
||||
"DASHBOARD_APP_TAB_MESSAGES": "Messages",
|
||||
"UNVERIFIED_SESSION": "The identity of this user is not verified",
|
||||
"NO_MESSAGE_1": "Uh oh! Sembla que no hi ha missatges de clients a la safata d'entrada.",
|
||||
"NO_MESSAGE_2": " per enviar un missatge a la vostra pàgina!",
|
||||
"NO_INBOX_1": "Hola! Sembla que encara no heu afegit cap safata d'entrada.",
|
||||
@@ -13,15 +13,15 @@
|
||||
"NO_INBOX_AGENT": "Uh Oh! Sembla que no ets a cap safata d'entrada. Si us plau, poseu-vos en contacte amb l'administrador",
|
||||
"SEARCH_MESSAGES": "Cerca missatges a les converses",
|
||||
"EMPTY_STATE": {
|
||||
"CMD_BAR": "per obrir el menú d'ordres",
|
||||
"KEYBOARD_SHORTCUTS": "per veure les dreceres del teclat"
|
||||
"CMD_BAR": "to open command menu",
|
||||
"KEYBOARD_SHORTCUTS": "to view keyboard shortcuts"
|
||||
},
|
||||
"SEARCH": {
|
||||
"TITLE": "Cerca missatges",
|
||||
"RESULT_TITLE": "Resultats de la cerca",
|
||||
"RESULT_TITLE": "Search Results",
|
||||
"LOADING_MESSAGE": "S'estan restringint les dades...",
|
||||
"PLACEHOLDER": "Escriu qualsevol text per cercar missatges",
|
||||
"NO_MATCHING_RESULTS": "No s'han trobat resultats."
|
||||
"NO_MATCHING_RESULTS": "No results found."
|
||||
},
|
||||
"UNREAD_MESSAGES": "Missatges no Llegits",
|
||||
"UNREAD_MESSAGE": "Missatge no Llegit",
|
||||
@@ -30,15 +30,15 @@
|
||||
"LOADING_CONVERSATIONS": "S'estan carregant les converses",
|
||||
"CANNOT_REPLY": "No pots respondre degut a",
|
||||
"24_HOURS_WINDOW": "Restricció de finestra de missatges de 24 hores",
|
||||
"NOT_ASSIGNED_TO_YOU": "Aquesta conversa no està assignada a tu. Vols assignar-te-la?",
|
||||
"ASSIGN_TO_ME": "Assigna'm",
|
||||
"TWILIO_WHATSAPP_CAN_REPLY": "Només pots respondre a aquesta conversa mitjançant una plantilla de missatge a causa de",
|
||||
"NOT_ASSIGNED_TO_YOU": "This conversation is not assigned to you. Would you like to assign this conversation to yourself?",
|
||||
"ASSIGN_TO_ME": "Assign to me",
|
||||
"TWILIO_WHATSAPP_CAN_REPLY": "You can only reply to this conversation using a template message due to",
|
||||
"TWILIO_WHATSAPP_24_HOURS_WINDOW": "Restricció de finestra de missatges de 24 hores",
|
||||
"REPLYING_TO": "Estas responent a:",
|
||||
"REMOVE_SELECTION": "Elimina la selecció",
|
||||
"DOWNLOAD": "Descarrega",
|
||||
"UNKNOWN_FILE_TYPE": "Fitxer desconegut",
|
||||
"SAVE_CONTACT": "Desar",
|
||||
"UNKNOWN_FILE_TYPE": "Unknown File",
|
||||
"SAVE_CONTACT": "Save",
|
||||
"UPLOADING_ATTACHMENTS": "Pujant fitxers adjunts...",
|
||||
"REPLIED_TO_STORY": "Replied to your story",
|
||||
"UNSUPPORTED_MESSAGE": "This message is unsupported.",
|
||||
@@ -89,7 +89,7 @@
|
||||
"CANCEL": "Cancel·la"
|
||||
},
|
||||
"PRIORITY": {
|
||||
"TITLE": "Prioritat",
|
||||
"TITLE": "Priority",
|
||||
"OPTIONS": {
|
||||
"NONE": "Ningú",
|
||||
"URGENT": "Urgent",
|
||||
@@ -280,29 +280,29 @@
|
||||
},
|
||||
"CONVERSATION_CUSTOM_ATTRIBUTES": {
|
||||
"ADD_BUTTON_TEXT": "Create attribute",
|
||||
"NO_RECORDS_FOUND": "No s'han trobat atributs",
|
||||
"NO_RECORDS_FOUND": "No attributes found",
|
||||
"UPDATE": {
|
||||
"SUCCESS": "Atribut actualitzat correctament",
|
||||
"ERROR": "No es pot actualitzar l'atribut. Si us plau, intenta-ho més tard"
|
||||
"SUCCESS": "Attribute updated successfully",
|
||||
"ERROR": "Unable to update attribute. Please try again later"
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Afegir",
|
||||
"SUCCESS": "Atribut afegit correctament",
|
||||
"ERROR": "No es pot afegir l'atribut. Si us plau, intenta-ho més tard"
|
||||
"TITLE": "Add",
|
||||
"SUCCESS": "Attribute added successfully",
|
||||
"ERROR": "Unable to add attribute. Please try again later"
|
||||
},
|
||||
"DELETE": {
|
||||
"SUCCESS": "Atribut esborrat correctament",
|
||||
"ERROR": "No es pot esborrar l'atribut. Si us plau, intenta-ho més tard"
|
||||
"SUCCESS": "Attribute deleted successfully",
|
||||
"ERROR": "Unable to delete attribute. Please try again later"
|
||||
},
|
||||
"ATTRIBUTE_SELECT": {
|
||||
"TITLE": "Afegir atributs",
|
||||
"PLACEHOLDER": "Cerca atributs",
|
||||
"NO_RESULT": "No s'han trobat atributs"
|
||||
"TITLE": "Add attributes",
|
||||
"PLACEHOLDER": "Search attributes",
|
||||
"NO_RESULT": "No attributes found"
|
||||
}
|
||||
},
|
||||
"EMAIL_HEADER": {
|
||||
"FROM": "From",
|
||||
"TO": "Per",
|
||||
"TO": "To",
|
||||
"BCC": "Bcc",
|
||||
"CC": "Cc",
|
||||
"SUBJECT": "Subject"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"EMOJI": {
|
||||
"PLACEHOLDER": "Cerca emojis",
|
||||
"NOT_FOUND": "Cap emoji coincideix amb la teva cerca",
|
||||
"PLACEHOLDER": "Search emojis",
|
||||
"NOT_FOUND": "No emoji match your search",
|
||||
"REMOVE": "Suprimeix"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"GENERAL": {
|
||||
"SHOWING_RESULTS": "Es mostren {firstIndex}-{lastIndex} de {totalCount} elements"
|
||||
"SHOWING_RESULTS": "Showing {firstIndex}-{lastIndex} of {totalCount} items"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"TITLE": "Configuració del compte",
|
||||
"SUBMIT": "Actualització de la configuració",
|
||||
"BACK": "Enrere",
|
||||
"DISMISS": "Descartar",
|
||||
"DISMISS": "Dismiss",
|
||||
"UPDATE": {
|
||||
"ERROR": "No s'ha pogut actualitzar la configuració, torna-ho a provar!",
|
||||
"SUCCESS": "La configuració del compte s'ha actualitzat correctament"
|
||||
@@ -15,8 +15,8 @@
|
||||
"NOTE": ""
|
||||
},
|
||||
"ACCOUNT_ID": {
|
||||
"TITLE": "ID del compte",
|
||||
"NOTE": "Aquest identificador és necessari si esteu creant una integració basada en API"
|
||||
"TITLE": "Account ID",
|
||||
"NOTE": "This ID is required if you are building an API based integration"
|
||||
},
|
||||
"NAME": {
|
||||
"LABEL": "Nom del compte",
|
||||
@@ -24,7 +24,7 @@
|
||||
"ERROR": "Introduïu un nom de compte vàlid"
|
||||
},
|
||||
"LANGUAGE": {
|
||||
"LABEL": "Idioma del lloc",
|
||||
"LABEL": "Site language",
|
||||
"PLACEHOLDER": "El nom del vostre compte",
|
||||
"ERROR": ""
|
||||
},
|
||||
@@ -41,7 +41,7 @@
|
||||
"AUTO_RESOLVE_DURATION": {
|
||||
"LABEL": "El nombre de dies després que un ticket es resolgui automàticament si no hi ha activitat",
|
||||
"PLACEHOLDER": "30",
|
||||
"ERROR": "Introduïu una durada de resolució automàtica vàlida (mínim 1 dia i màxim 999 dies)"
|
||||
"ERROR": "Please enter a valid auto resolve duration (minimum 1 day and maximum 999 days)"
|
||||
},
|
||||
"FEATURES": {
|
||||
"INBOUND_EMAIL_ENABLED": "La continuïtat de converses amb correus electrònics està habilitada per al vostre compte.",
|
||||
@@ -49,8 +49,8 @@
|
||||
}
|
||||
},
|
||||
"UPDATE_CHATWOOT": "L'actualització %{latestChatwootVersion} per Chatwoot està disponible. Si us plau, actualitza l'instancia.",
|
||||
"LEARN_MORE": "Aprèn més",
|
||||
"PAYMENT_PENDING": "El teu pagament està pendent. Actualitzeu la vostra informació de pagament per continuar utilitzant Chatwoot",
|
||||
"LEARN_MORE": "Learn more",
|
||||
"PAYMENT_PENDING": "Your payment is pending. Please update your payment information to continue using Chatwoot",
|
||||
"LIMITS_UPGRADE": "Your account has exceeded the usage limits, please upgrade your plan to continue using Chatwoot",
|
||||
"OPEN_BILLING": "Open billing"
|
||||
},
|
||||
@@ -107,7 +107,6 @@
|
||||
"GENERAL": "General",
|
||||
"REPORTS": "Informes",
|
||||
"CONVERSATION": "Conversation",
|
||||
"BULK_ACTIONS": "Bulk Actions",
|
||||
"CHANGE_ASSIGNEE": "Change Assignee",
|
||||
"CHANGE_PRIORITY": "Change Priority",
|
||||
"CHANGE_TEAM": "Change Team",
|
||||
|
||||
@@ -460,7 +460,7 @@
|
||||
"DESCRIPTION": "Create user-friendly self-service portals. Help your users to access the articles and get support 24/7. Upgrade your subscription to enable this feature.",
|
||||
"SELF_HOSTED_DESCRIPTION": "Create user-friendly self-service portals. Help your users to access the articles and get support 24/7. Please contact your administrator to enable this feature.",
|
||||
"BUTTON": {
|
||||
"LEARN_MORE": "Aprèn més",
|
||||
"LEARN_MORE": "Learn more",
|
||||
"UPGRADE": "Upgrade"
|
||||
},
|
||||
"FEATURES": {
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"SORT_OPTIONS": {
|
||||
"NEWEST": "Newest",
|
||||
"OLDEST": "Oldest",
|
||||
"PRIORITY": "Prioritat"
|
||||
"PRIORITY": "Priority"
|
||||
},
|
||||
"DISPLAY_OPTIONS": {
|
||||
"SNOOZED": "Posposat",
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
},
|
||||
"CHANNEL_GREETING_TOGGLE": {
|
||||
"LABEL": "Activa la salutació del canal",
|
||||
"HELP_TEXT": "Envia automàticament missatges de salutació quan els clients inicien una conversa i envien el seu primer missatge.",
|
||||
"HELP_TEXT": "Automatically send a greeting message when a new conversation is created.",
|
||||
"ENABLED": "Habilita",
|
||||
"DISABLED": "Inhabilita"
|
||||
},
|
||||
@@ -169,7 +169,7 @@
|
||||
},
|
||||
"BANDWIDTH": {
|
||||
"ACCOUNT_ID": {
|
||||
"LABEL": "ID del compte",
|
||||
"LABEL": "Account ID",
|
||||
"PLACEHOLDER": "Please enter your Bandwidth Account ID",
|
||||
"ERROR": "Aquest camp és obligatori"
|
||||
},
|
||||
@@ -340,7 +340,7 @@
|
||||
},
|
||||
"AUTH": {
|
||||
"TITLE": "Choose a channel",
|
||||
"DESC": "Chatwoot admet widgets de xat en directe, Facebook Messenger, WhatsApp, correus electrònics, etc., com a canals. Si voleu crear un canal personalitzat, podeu crear-lo mitjançant el canal API. Per començar, tria un dels canals següents."
|
||||
"DESC": "Chatwoot supports live-chat widgets, Facebook Messenger, Twitter profiles, WhatsApp, Emails, etc., as channels. If you want to build a custom channel, you can create it using the API channel. To get started, choose one of the channels below."
|
||||
},
|
||||
"AGENTS": {
|
||||
"TITLE": "Agents",
|
||||
@@ -420,7 +420,7 @@
|
||||
"BUSINESS_NAME": {
|
||||
"BUTTON_TEXT": "+ Configure your business name",
|
||||
"PLACEHOLDER": "Enter your business name",
|
||||
"SAVE_BUTTON_TEXT": "Desar"
|
||||
"SAVE_BUTTON_TEXT": "Save"
|
||||
}
|
||||
},
|
||||
"ALLOW_MESSAGES_AFTER_RESOLVED": {
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
"TITLE": "Confirma l'esborrat",
|
||||
"MESSAGE": "Are you sure to delete the webhook? (%{webhookURL})",
|
||||
"YES": "Si, esborra ",
|
||||
"NO": "No, mantén-la"
|
||||
"NO": "No, manten-la"
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -79,8 +79,8 @@
|
||||
"MESSAGE": "Are you sure you want to delete the integration? Doing so will result in the loss of access to conversations on your Slack workspace."
|
||||
},
|
||||
"HELP_TEXT": {
|
||||
"TITLE": "Com utilitzar la integració de Slack?",
|
||||
"BODY": "Amb aquesta integració, totes les teves converses entrants se sincronitzaran amb el canal ***%{selectedChannelName}*** del teu espai de treball de Slack. Podeu gestionar totes les converses dels vostres clients directament des del canal i no perdreu cap missatge.\n\nAquestes són les principals característiques de la integració:\n\n**Respondre a converses des de Slack:** Per respondre a una conversa al ***%{selectedChannelName}*** canal de Slack, només has d'escriure el teu missatge i enviar-lo com a fil. Això crearà una resposta al client mitjançant Chatwoot. Així de senzill!\n\n **Crear notes privades:** si vols crear notes privades en lloc de respostes, comença el teu missatge amb ***`nota:`***. Això garanteix que el vostre missatge es mantingui privat i no serà visible per al client.\n\n**Associar un perfil d'agent:** si la persona que va respondre a Slack té un perfil d'agent a Chatwoot amb el mateix correu electrònic, les respostes s'associaran amb aquest perfil d'agent automàticament. Això vol dir que podeu fer un seguiment fàcilment qui va dir què i quan. D'altra banda, quan el contestador no té un perfil d'agent associat, les respostes apareixeran des del perfil del bot al client.",
|
||||
"TITLE": "Using Slack Integration",
|
||||
"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>",
|
||||
"SELECTED": "selected"
|
||||
},
|
||||
"SELECT_CHANNEL": {
|
||||
@@ -131,7 +131,7 @@
|
||||
"KEY_PLACEHOLDER": "Enter your OpenAI API key",
|
||||
"BUTTONS": {
|
||||
"NEED_HELP": "Need help?",
|
||||
"DISMISS": "Descartar",
|
||||
"DISMISS": "Dismiss",
|
||||
"FINISH": "Finish Setup"
|
||||
},
|
||||
"DISMISS_MESSAGE": "You can setup OpenAI integration later Whenever you want.",
|
||||
|
||||
@@ -46,7 +46,7 @@
|
||||
"DISMISS": "Dismiss suggestion"
|
||||
},
|
||||
"POWERED_BY": "Chatwoot AI",
|
||||
"DISMISS": "Descartar",
|
||||
"DISMISS": "Dismiss",
|
||||
"ADD_SELECTED_LABELS": "Add selected labels",
|
||||
"ADD_SELECTED_LABEL": "Add selected label",
|
||||
"ADD_ALL_LABELS": "Add all labels"
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"TITLE": "Entra a Chatwoot",
|
||||
"EMAIL": {
|
||||
"LABEL": "Correu electrònic",
|
||||
"PLACEHOLDER": "exemple@nomdelacompanyia.com",
|
||||
"PLACEHOLDER": "Correu electrònic p.e.: someone@exemple.com",
|
||||
"ERROR": "Introduïu una adreça de correu electrònic vàlida"
|
||||
},
|
||||
"PASSWORD": {
|
||||
@@ -16,9 +16,9 @@
|
||||
"UNAUTH": "Nom d'usuari / contrasenya incorrecte. Torna-ho a provar-ho"
|
||||
},
|
||||
"OAUTH": {
|
||||
"GOOGLE_LOGIN": "Inicieu sessió amb Google",
|
||||
"BUSINESS_ACCOUNTS_ONLY": "Si us plau, utilitzeu l'adreça de correu electrònic de la vostra empresa per iniciar sessió",
|
||||
"NO_ACCOUNT_FOUND": "No hem trobat cap compte per a la vostra adreça de correu electrònic."
|
||||
"GOOGLE_LOGIN": "Login with Google",
|
||||
"BUSINESS_ACCOUNTS_ONLY": "Please use your company email address to login",
|
||||
"NO_ACCOUNT_FOUND": "We couldn't find an account for your email address."
|
||||
},
|
||||
"FORGOT_PASSWORD": "Has oblidat la contrasenya?",
|
||||
"CREATE_NEW_ACCOUNT": "Crear un nou compte",
|
||||
|
||||
@@ -92,7 +92,7 @@
|
||||
"DAY": "Day",
|
||||
"WEEK": "Week",
|
||||
"MONTH": "Month",
|
||||
"YEAR": "Any"
|
||||
"YEAR": "Month"
|
||||
},
|
||||
"GROUP_BY_DAY_OPTIONS": [
|
||||
{
|
||||
@@ -140,7 +140,7 @@
|
||||
],
|
||||
"BUSINESS_HOURS": "Business Hours",
|
||||
"FILTER_ACTIONS": {
|
||||
"CLEAR_FILTER": "Esborra els filtres",
|
||||
"CLEAR_FILTER": "Clear filter",
|
||||
"EMPTY_LIST": "No s'ha trobat agents"
|
||||
}
|
||||
},
|
||||
@@ -232,7 +232,7 @@
|
||||
},
|
||||
"FIRST_RESPONSE_TIME": {
|
||||
"NAME": "First Response Time",
|
||||
"DESC": "(Mitjana)",
|
||||
"DESC": "( Promig )",
|
||||
"INFO_TEXT": "Total number of conversations used for computation:",
|
||||
"TOOLTIP_TEXT": "First Response Time is %{metricValue} (based on %{conversationCount} conversations)"
|
||||
},
|
||||
@@ -511,52 +511,52 @@
|
||||
"SATURDAY": "Saturday"
|
||||
},
|
||||
"SLA_REPORTS": {
|
||||
"HEADER": "Informes SLA",
|
||||
"NO_RECORDS": "Les converses aplicades per l'SLA no estan disponibles.",
|
||||
"LOADING": "S'estan carregant dades del SLA...",
|
||||
"DOWNLOAD_SLA_REPORTS": "Descarregar informes SLA",
|
||||
"DOWNLOAD_FAILED": "No s'han pogut baixar els informes SLA",
|
||||
"HEADER": "SLA Reports",
|
||||
"NO_RECORDS": "SLA applied conversations are not available.",
|
||||
"LOADING": "Loading SLA data...",
|
||||
"DOWNLOAD_SLA_REPORTS": "Download SLA reports",
|
||||
"DOWNLOAD_FAILED": "Failed to download SLA Reports",
|
||||
"DROPDOWN": {
|
||||
"ADD_FIlTER": "Afegeix un filtre",
|
||||
"CLEAR_ALL": "Esborrar tot",
|
||||
"CLEAR_FILTER": "Esborra els filtres",
|
||||
"ADD_FIlTER": "Add filter",
|
||||
"CLEAR_ALL": "Clear all",
|
||||
"CLEAR_FILTER": "Clear filter",
|
||||
"EMPTY_LIST": "No s'ha trobat agents",
|
||||
"NO_FILTER": "No hi ha filtres disponibles",
|
||||
"SEARCH": "Cerca filtre",
|
||||
"NO_FILTER": "No filters available",
|
||||
"SEARCH": "Search filter",
|
||||
"INPUT_PLACEHOLDER": {
|
||||
"SLA": "Nom del SLA",
|
||||
"AGENTS": "Nom de l'Agent",
|
||||
"INBOXES": "Nom de la safata d'entrada",
|
||||
"SLA": "SLA name",
|
||||
"AGENTS": "Agent name",
|
||||
"INBOXES": "Inbox name",
|
||||
"LABELS": "Nom de l'etiqueta",
|
||||
"TEAMS": "Nom de l'equip"
|
||||
"TEAMS": "Team name"
|
||||
},
|
||||
"SLA": "Política SLA",
|
||||
"INBOXES": "Safata d'entrada",
|
||||
"SLA": "SLA Policy",
|
||||
"INBOXES": "Inbox",
|
||||
"AGENTS": "Agent",
|
||||
"LABELS": "Etiqueta",
|
||||
"TEAMS": "Equip"
|
||||
"LABELS": "Label",
|
||||
"TEAMS": "Team"
|
||||
},
|
||||
"METRICS": {
|
||||
"HIT_RATE": {
|
||||
"LABEL": "Proporció d'encerts",
|
||||
"TOOLTIP": "El percentatge de SLA creats s'ha completat correctament"
|
||||
"LABEL": "Hit Rate",
|
||||
"TOOLTIP": "Percentage of SLAs created were completed successfully"
|
||||
},
|
||||
"NO_OF_MISSES": {
|
||||
"LABEL": "Nombre de faltes",
|
||||
"TOOLTIP": "SLA total faltes en un període determinat"
|
||||
"LABEL": "Number of Misses",
|
||||
"TOOLTIP": "Total SLA misses in a certain period"
|
||||
},
|
||||
"NO_OF_CONVERSATIONS": {
|
||||
"LABEL": "Número de Converses",
|
||||
"TOOLTIP": "Nombre total de converses amb SLA"
|
||||
"LABEL": "Number of Conversations",
|
||||
"TOOLTIP": "Total number of conversations with SLA"
|
||||
}
|
||||
},
|
||||
"TABLE": {
|
||||
"HEADER": {
|
||||
"POLICY": "Política",
|
||||
"CONVERSATION": "Converses",
|
||||
"POLICY": "Policy",
|
||||
"CONVERSATION": "Conversation",
|
||||
"AGENT": "Agent"
|
||||
},
|
||||
"VIEW_DETAILS": "Veure Detalls"
|
||||
"VIEW_DETAILS": "View Details"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,12 @@
|
||||
"ALL": "Totes",
|
||||
"CONTACTS": "Contactes",
|
||||
"CONVERSATIONS": "Converses",
|
||||
"MESSAGES": "Missatges"
|
||||
"MESSAGES": "Messages"
|
||||
},
|
||||
"SECTION": {
|
||||
"CONTACTS": "Contactes",
|
||||
"CONVERSATIONS": "Converses",
|
||||
"MESSAGES": "Missatges"
|
||||
"MESSAGES": "Messages"
|
||||
},
|
||||
"EMPTY_STATE": "No %{item} found for query '%{query}'",
|
||||
"EMPTY_STATE_FULL": "No results found for query '%{query}'",
|
||||
|
||||
@@ -91,9 +91,9 @@
|
||||
"CONVERSATION_MENTION": "Enviar notificacions per mail quan siguis esmentat en una conversació",
|
||||
"ASSIGNED_CONVERSATION_NEW_MESSAGE": "Envia notificacions per correu electrònic quan es creï un missatge nou en una conversa assignada",
|
||||
"PARTICIPATING_CONVERSATION_NEW_MESSAGE": "Send email notifications when a new message is created in a participating conversation",
|
||||
"SLA_MISSED_FIRST_RESPONSE": "Envia notificacions per correu electrònic quan una conversa no compleixi un SLA de primera resposta",
|
||||
"SLA_MISSED_NEXT_RESPONSE": "Envia notificacions per correu electrònic quan una conversa es perdi la següent resposta SLA",
|
||||
"SLA_MISSED_RESOLUTION": "Envia notificacions per correu electrònic quan una conversa no resol un SLA"
|
||||
"SLA_MISSED_FIRST_RESPONSE": "Send email notifications when a conversation misses first response SLA",
|
||||
"SLA_MISSED_NEXT_RESPONSE": "Send email notifications when a conversation misses next response SLA",
|
||||
"SLA_MISSED_RESOLUTION": "Send email notifications when a conversation misses resolution SLA"
|
||||
},
|
||||
"NOTIFICATIONS": {
|
||||
"TITLE": "Notification preferences",
|
||||
@@ -109,8 +109,7 @@
|
||||
"SLA_MISSED_FIRST_RESPONSE": "A conversation misses first response SLA",
|
||||
"SLA_MISSED_NEXT_RESPONSE": "A conversation misses next response SLA",
|
||||
"SLA_MISSED_RESOLUTION": "A conversation misses resolution SLA"
|
||||
},
|
||||
"BROWSER_PERMISSION": "Enable push notifications for your browser so you’re able to receive them"
|
||||
}
|
||||
},
|
||||
"API": {
|
||||
"UPDATE_SUCCESS": "Les teves preferències de notificació s’han actualitzat correctament",
|
||||
@@ -126,9 +125,9 @@
|
||||
"PARTICIPATING_CONVERSATION_NEW_MESSAGE": "Send push notifications when a new message is created in a participating conversation",
|
||||
"HAS_ENABLED_PUSH": "Heu activat les notificacions per a aquest navegador.",
|
||||
"REQUEST_PUSH": "Activa les notificacions",
|
||||
"SLA_MISSED_FIRST_RESPONSE": "Envia notificacions automàtiques quan una conversa no tingui un SLA de primera resposta",
|
||||
"SLA_MISSED_NEXT_RESPONSE": "Envia notificacions automàtiques quan una conversa no s'aconsegueixi la següent resposta SLA",
|
||||
"SLA_MISSED_RESOLUTION": "Envia notificacions quan una conversa no resol el SLA"
|
||||
"SLA_MISSED_FIRST_RESPONSE": "Send push notifications when a conversation misses first response SLA",
|
||||
"SLA_MISSED_NEXT_RESPONSE": "Send push notifications when a conversation misses next response SLA",
|
||||
"SLA_MISSED_RESOLUTION": "Send push notifications when a conversation misses resolution SLA"
|
||||
},
|
||||
"PROFILE_IMAGE": {
|
||||
"LABEL": "Imatge del Perfil"
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
"COMPANY_NAME": {
|
||||
"LABEL": "Company name",
|
||||
"PLACEHOLDER": "Enter your company name. eg: Wayne Enterprises",
|
||||
"ERROR": "El nom de l'empresa és massa curt."
|
||||
"ERROR": "Company name is too short"
|
||||
},
|
||||
"FULL_NAME": {
|
||||
"LABEL": "Nom complet",
|
||||
@@ -20,7 +20,7 @@
|
||||
},
|
||||
"EMAIL": {
|
||||
"LABEL": "Email de treball",
|
||||
"PLACEHOLDER": "Introdueix la teva adreça de correu electrònica de la feina. P. ex.: bruce@wayne.enterprises",
|
||||
"PLACEHOLDER": "Introdueix la teva adreça email de treball. ex: bruce@wayne.enterprises",
|
||||
"ERROR": "Please enter a valid work email address"
|
||||
},
|
||||
"PASSWORD": {
|
||||
@@ -32,7 +32,7 @@
|
||||
"CONFIRM_PASSWORD": {
|
||||
"LABEL": "Confirma la contrasenya",
|
||||
"PLACEHOLDER": "Confirma la contrasenya",
|
||||
"ERROR": "La contrasenya no coincideix."
|
||||
"ERROR": "Les contrasenyes no coincideixen"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Registrat correctament",
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
{
|
||||
"SLA": {
|
||||
"HEADER": "SLA",
|
||||
"ADD_ACTION": "Afegeix SLA",
|
||||
"ADD_ACTION_LONG": "Crea una nova política de SLA",
|
||||
"DESCRIPTION": "Els acords de nivell de servei (SLA) són contractes que defineixen expectatives clares entre el vostre equip i els clients. Estableixen estàndards de temps de resposta i resolució, creen un marc de responsabilitat i garanteixen una experiència coherent i d'alta qualitat.",
|
||||
"LEARN_MORE": "Més informació sobre SLA",
|
||||
"ADD_ACTION": "Add SLA",
|
||||
"ADD_ACTION_LONG": "Create a new SLA Policy",
|
||||
"DESCRIPTION": "Service Level Agreements (SLAs) are contracts that define clear expectations between your team and customers. They establish standards for response and resolution times, creating a framework for accountability and ensures a consistent, high-quality experience.",
|
||||
"LEARN_MORE": "Learn more about SLA",
|
||||
"LOADING": "Fetching SLAs",
|
||||
"PAYWALL": {
|
||||
"TITLE": "Upgrade to create SLAs",
|
||||
@@ -21,10 +21,10 @@
|
||||
"LIST": {
|
||||
"404": "There are no SLAs available in this account.",
|
||||
"EMPTY": {
|
||||
"TITLE_1": "Empresa P0",
|
||||
"DESC_1": "Problemes plantejats pels clients empresarials, que requereixen atenció immediata.",
|
||||
"TITLE_2": "Empresa P1",
|
||||
"DESC_2": "Problemes plantejats pels clients empresarials, que cal reconèixer ràpidament."
|
||||
"TITLE_1": "Enterprise P0",
|
||||
"DESC_1": "Issues raised by enterprise customers, that require immediate attention.",
|
||||
"TITLE_2": "Enterprise P1",
|
||||
"DESC_2": "Issues raised by enterprise customers, that needs to be acknowledged quickly."
|
||||
},
|
||||
"BUSINESS_HOURS_ON": "Business hours on",
|
||||
"BUSINESS_HOURS_OFF": "Business hours off",
|
||||
@@ -77,7 +77,7 @@
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Add SLA",
|
||||
"DESC": "Promeses amistoses per a un gran servei!",
|
||||
"DESC": "Friendly promises for great service!",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "SLA added successfully",
|
||||
"ERROR_MESSAGE": "S'ha produït un error; tornau-ho a provar"
|
||||
@@ -97,12 +97,12 @@
|
||||
}
|
||||
},
|
||||
"EVENTS": {
|
||||
"TITLE": "Faltes SLA",
|
||||
"TITLE": "SLA Misses",
|
||||
"FRT": "Primer temps de resposta",
|
||||
"NRT": "Pròxim temps de resposta",
|
||||
"RT": "Temps de resolució",
|
||||
"SHOW_MORE": "{count} més",
|
||||
"HIDE": "Amaga {count} files"
|
||||
"NRT": "Next response time",
|
||||
"RT": "Resolution time",
|
||||
"SHOW_MORE": "{count} more",
|
||||
"HIDE": "Hide {count} rows"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@
|
||||
"AGENT_LIST_LOADING": "Načítání agentů",
|
||||
"UPDATE": {
|
||||
"CHANGE_STATUS": "Change status",
|
||||
"SNOOZE_UNTIL": "Odložit",
|
||||
"SNOOZE_UNTIL_NEXT_REPLY": "Snooze until next reply.",
|
||||
"UPDATE_SUCCESFUL": "Conversation status updated successfully.",
|
||||
"UPDATE_FAILED": "Failed to update conversations. Please try again."
|
||||
},
|
||||
|
||||
@@ -84,7 +84,6 @@
|
||||
"CONFIRM": {
|
||||
"TITLE": "Export Contacts",
|
||||
"MESSAGE": "Are you sure you want to export all contacts?",
|
||||
"FILTERED_MESSAGE": "Are you sure you want to export all the filtered contacts?",
|
||||
"YES": "Yes, Export",
|
||||
"NO": "No, Cancel"
|
||||
}
|
||||
|
||||
@@ -107,7 +107,6 @@
|
||||
"GENERAL": "General",
|
||||
"REPORTS": "Zprávy",
|
||||
"CONVERSATION": "Conversation",
|
||||
"BULK_ACTIONS": "Bulk Actions",
|
||||
"CHANGE_ASSIGNEE": "Change Assignee",
|
||||
"CHANGE_PRIORITY": "Change Priority",
|
||||
"CHANGE_TEAM": "Change Team",
|
||||
|
||||
@@ -109,8 +109,7 @@
|
||||
"SLA_MISSED_FIRST_RESPONSE": "A conversation misses first response SLA",
|
||||
"SLA_MISSED_NEXT_RESPONSE": "A conversation misses next response SLA",
|
||||
"SLA_MISSED_RESOLUTION": "A conversation misses resolution SLA"
|
||||
},
|
||||
"BROWSER_PERMISSION": "Enable push notifications for your browser so you’re able to receive them"
|
||||
}
|
||||
},
|
||||
"API": {
|
||||
"UPDATE_SUCCESS": "Vaše předvolby oznámení byly úspěšně aktualizovány",
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"AGENT_LIST_LOADING": "Indlæser agenter",
|
||||
"UPDATE": {
|
||||
"CHANGE_STATUS": "Skift status",
|
||||
"SNOOZE_UNTIL": "Udsæt",
|
||||
"SNOOZE_UNTIL_NEXT_REPLY": "Udsæt til næste svar.",
|
||||
"UPDATE_SUCCESFUL": "Samtalens status blev opdateret.",
|
||||
"UPDATE_FAILED": "Failed to update conversations. Please try again."
|
||||
},
|
||||
|
||||
@@ -84,7 +84,6 @@
|
||||
"CONFIRM": {
|
||||
"TITLE": "Export Contacts",
|
||||
"MESSAGE": "Are you sure you want to export all contacts?",
|
||||
"FILTERED_MESSAGE": "Are you sure you want to export all the filtered contacts?",
|
||||
"YES": "Yes, Export",
|
||||
"NO": "No, Cancel"
|
||||
}
|
||||
|
||||
@@ -107,7 +107,6 @@
|
||||
"GENERAL": "Generelt",
|
||||
"REPORTS": "Rapporter",
|
||||
"CONVERSATION": "Samtale",
|
||||
"BULK_ACTIONS": "Bulk Actions",
|
||||
"CHANGE_ASSIGNEE": "Skift Modtager",
|
||||
"CHANGE_PRIORITY": "Change Priority",
|
||||
"CHANGE_TEAM": "Skift Team",
|
||||
|
||||
@@ -109,8 +109,7 @@
|
||||
"SLA_MISSED_FIRST_RESPONSE": "A conversation misses first response SLA",
|
||||
"SLA_MISSED_NEXT_RESPONSE": "A conversation misses next response SLA",
|
||||
"SLA_MISSED_RESOLUTION": "A conversation misses resolution SLA"
|
||||
},
|
||||
"BROWSER_PERMISSION": "Enable push notifications for your browser so you’re able to receive them"
|
||||
}
|
||||
},
|
||||
"API": {
|
||||
"UPDATE_SUCCESS": "Dine notifikationsindstillinger er opdateret",
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"AGENT_LIST_LOADING": "Agenten werden geladen",
|
||||
"UPDATE": {
|
||||
"CHANGE_STATUS": "Status ändern",
|
||||
"SNOOZE_UNTIL": "Erinnern",
|
||||
"SNOOZE_UNTIL_NEXT_REPLY": "Bis zur nächsten Antwort zurückstellen.",
|
||||
"UPDATE_SUCCESFUL": "Der Konversationsstatus wurde erfolgreich aktualisiert.",
|
||||
"UPDATE_FAILED": "Failed to update conversations. Please try again."
|
||||
},
|
||||
|
||||
@@ -84,7 +84,6 @@
|
||||
"CONFIRM": {
|
||||
"TITLE": "Kontakte exportieren",
|
||||
"MESSAGE": "Are you sure you want to export all contacts?",
|
||||
"FILTERED_MESSAGE": "Are you sure you want to export all the filtered contacts?",
|
||||
"YES": "Yes, Export",
|
||||
"NO": "No, Cancel"
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"CONVERSATION": {
|
||||
"SELECT_A_CONVERSATION": "Bitte wählen Sie eine Konversation aus dem linken Bereich aus",
|
||||
"CSAT_REPLY_MESSAGE": "Bitte bewerten Sie diese Konversation",
|
||||
"CSAT_REPLY_MESSAGE": "Bitte bewerten Sie diese Unterhaltung",
|
||||
"404": "Wir können die Konversation leider nicht finden. Bitte versuche es erneut",
|
||||
"SWITCH_VIEW_LAYOUT": "Layout wechseln",
|
||||
"DASHBOARD_APP_TAB_MESSAGES": "Nachrichten",
|
||||
@@ -49,7 +49,7 @@
|
||||
"NO_RESPONSE": "Keine Antwort",
|
||||
"RATING_TITLE": "Bewertung",
|
||||
"FEEDBACK_TITLE": "Feedback",
|
||||
"REPLY_MESSAGE_NOT_FOUND": "Nachricht nicht verfügbar",
|
||||
"REPLY_MESSAGE_NOT_FOUND": "Message not available",
|
||||
"CARD": {
|
||||
"SHOW_LABELS": "Labels anzeigen",
|
||||
"HIDE_LABELS": "Labels ausblenden"
|
||||
@@ -150,8 +150,8 @@
|
||||
"SEND": "Senden",
|
||||
"CREATE": "Notiz hinzufügen",
|
||||
"INSERT_READ_MORE": "Mehr erfahren",
|
||||
"DISMISS_REPLY": "Antwort verwerfen",
|
||||
"REPLYING_TO": "Antwort auf:",
|
||||
"DISMISS_REPLY": "Dismiss reply",
|
||||
"REPLYING_TO": "Replying to:",
|
||||
"TIP_FORMAT_ICON": "Rich Text Editor anzeigen",
|
||||
"TIP_EMOJI_ICON": "Emoji-Auswahl anzeigen",
|
||||
"TIP_ATTACH_ICON": "Dateien anhängen",
|
||||
@@ -206,7 +206,7 @@
|
||||
},
|
||||
"CONTEXT_MENU": {
|
||||
"COPY": "Kopieren",
|
||||
"REPLY_TO": "Auf diese Nachricht antworten",
|
||||
"REPLY_TO": "Reply to this message",
|
||||
"DELETE": "Löschen",
|
||||
"CREATE_A_CANNED_RESPONSE": "Zu vorgefertigten Antworten hinzufügen",
|
||||
"TRANSLATE": "Übersetzen",
|
||||
|
||||
@@ -107,7 +107,6 @@
|
||||
"GENERAL": "Generell",
|
||||
"REPORTS": "Berichte",
|
||||
"CONVERSATION": "Konversation",
|
||||
"BULK_ACTIONS": "Bulk Actions",
|
||||
"CHANGE_ASSIGNEE": "Beauftragten ändern",
|
||||
"CHANGE_PRIORITY": "Priorität ändern",
|
||||
"CHANGE_TEAM": "Team wechseln",
|
||||
|
||||
@@ -717,7 +717,7 @@
|
||||
"IN_A_DAY": "Wir antworten üblicherweise innerhalb eines Tages"
|
||||
},
|
||||
"FOOTER": {
|
||||
"START_CONVERSATION_BUTTON_TEXT": "Konversation beginnen",
|
||||
"START_CONVERSATION_BUTTON_TEXT": "Unterhaltung beginnen",
|
||||
"CHAT_INPUT_PLACEHOLDER": "Schreiben Sie Ihre Nachricht"
|
||||
},
|
||||
"BODY": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"RESET_PASSWORD": {
|
||||
"TITLE": "Passwort zurücksetzen",
|
||||
"DESCRIPTION": "Geben Sie die E-Mail-Adresse ein, mit der Sie sich bei Chatwoot anmelden, um die Anweisungen zum Zurücksetzen des Passworts zu erhalten.",
|
||||
"DESCRIPTION": "Enter the email address you use to log in to Chatwoot to get the password reset instructions.",
|
||||
"GO_BACK_TO_LOGIN": "If you want to go back to the login page,",
|
||||
"EMAIL": {
|
||||
"LABEL": "E-Mail",
|
||||
|
||||
@@ -109,8 +109,7 @@
|
||||
"SLA_MISSED_FIRST_RESPONSE": "A conversation misses first response SLA",
|
||||
"SLA_MISSED_NEXT_RESPONSE": "A conversation misses next response SLA",
|
||||
"SLA_MISSED_RESOLUTION": "A conversation misses resolution SLA"
|
||||
},
|
||||
"BROWSER_PERMISSION": "Enable push notifications for your browser so you’re able to receive them"
|
||||
}
|
||||
},
|
||||
"API": {
|
||||
"UPDATE_SUCCESS": "Ihre Benachrichtigungseinstellungen wurden erfolgreich aktualisiert",
|
||||
@@ -190,9 +189,9 @@
|
||||
"TRIAL_MESSAGE": "Tage der Testversion verbleibend.",
|
||||
"TRAIL_BUTTON": "Jetzt kaufen",
|
||||
"DELETED_USER": "Gelöschter Benutzer",
|
||||
"EMAIL_VERIFICATION_PENDING": "Es scheint, dass Sie Ihre E-Mail-Adresse noch nicht verifiziert haben. Bitte überprüfen Sie Ihren Posteingang auf die Verifizierungs-E-Mail.",
|
||||
"RESEND_VERIFICATION_MAIL": "Verifizierungs-E-Mail erneut senden",
|
||||
"EMAIL_VERIFICATION_SENT": "Verifizierungs-E-Mail wurde versendet. Bitte überprüfen Sie Ihren Posteingang.",
|
||||
"EMAIL_VERIFICATION_PENDING": "It seems that you haven't verified your email address yet. Please check your inbox for the verification email.",
|
||||
"RESEND_VERIFICATION_MAIL": "Resend verification email",
|
||||
"EMAIL_VERIFICATION_SENT": "Verification email has been sent. Please check your inbox.",
|
||||
"ACCOUNT_SUSPENDED": {
|
||||
"TITLE": "Konto gesperrt",
|
||||
"MESSAGE": "Ihr Account wurde gesperrt. Wenden Sie sich für weitere Informationen bitte an das Support-Team."
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"AGENT_LIST_LOADING": "Φόρτωση πρακτόρων",
|
||||
"UPDATE": {
|
||||
"CHANGE_STATUS": "Αλλαγή κατάστασης",
|
||||
"SNOOZE_UNTIL": "Αναβολή",
|
||||
"SNOOZE_UNTIL_NEXT_REPLY": "Αναβολή έως την επόμενη απάντηση.",
|
||||
"UPDATE_SUCCESFUL": "Η κατάσταση συνομιλίας ενημερώθηκε με επιτυχία.",
|
||||
"UPDATE_FAILED": "Failed to update conversations. Please try again."
|
||||
},
|
||||
|
||||
@@ -84,7 +84,6 @@
|
||||
"CONFIRM": {
|
||||
"TITLE": "Export Contacts",
|
||||
"MESSAGE": "Are you sure you want to export all contacts?",
|
||||
"FILTERED_MESSAGE": "Are you sure you want to export all the filtered contacts?",
|
||||
"YES": "Yes, Export",
|
||||
"NO": "No, Cancel"
|
||||
}
|
||||
|
||||
@@ -107,7 +107,6 @@
|
||||
"GENERAL": "Γενικά",
|
||||
"REPORTS": "Αναφορές",
|
||||
"CONVERSATION": "Συνομιλία",
|
||||
"BULK_ACTIONS": "Bulk Actions",
|
||||
"CHANGE_ASSIGNEE": "Αλλαγή Αναδόχου",
|
||||
"CHANGE_PRIORITY": "Change Priority",
|
||||
"CHANGE_TEAM": "Αλλαγή Ομάδας",
|
||||
|
||||
@@ -109,8 +109,7 @@
|
||||
"SLA_MISSED_FIRST_RESPONSE": "A conversation misses first response SLA",
|
||||
"SLA_MISSED_NEXT_RESPONSE": "A conversation misses next response SLA",
|
||||
"SLA_MISSED_RESOLUTION": "A conversation misses resolution SLA"
|
||||
},
|
||||
"BROWSER_PERMISSION": "Enable push notifications for your browser so you’re able to receive them"
|
||||
}
|
||||
},
|
||||
"API": {
|
||||
"UPDATE_SUCCESS": "Οι προτιμήσεις σας για τις ειδοποιήσεις ενημερώθηκαν",
|
||||
|
||||
@@ -154,7 +154,7 @@
|
||||
"UNTIL_TOMORROW": "Until tomorrow",
|
||||
"UNTIL_NEXT_MONTH": "Until next month",
|
||||
"AN_HOUR_FROM_NOW": "Until an hour from now",
|
||||
"UNTIL_CUSTOM_TIME": "Custom...",
|
||||
"CUSTOM": "Custom...",
|
||||
"CHANGE_APPEARANCE": "Change Appearance",
|
||||
"LIGHT_MODE": "Light",
|
||||
"DARK_MODE": "Dark",
|
||||
|
||||
@@ -8,8 +8,9 @@
|
||||
"NO_NOTIFICATIONS": "No notifications",
|
||||
"NOTE": "Notifications from all subscribed inboxes",
|
||||
"NO_MESSAGES_AVAILABLE": "Oops! Not able to fetch messages",
|
||||
"SNOOZED_UNTIL": "We’ll remind you after {time}",
|
||||
"SNOOZED_ENDS": "We won’t notify you again"
|
||||
"SNOOZED_UNTIL": "Snoozed until",
|
||||
"SNOOZED_UNTIL_TOMORROW": "Snoozed until tomorrow",
|
||||
"SNOOZED_UNTIL_NEXT_WEEK": "Snoozed until next week"
|
||||
},
|
||||
"ACTION_HEADER": {
|
||||
"SNOOZE": "Snooze notification",
|
||||
@@ -17,11 +18,14 @@
|
||||
"BACK": "Back"
|
||||
},
|
||||
"TYPES": {
|
||||
"CONVERSATION_MENTION": "Mention",
|
||||
"CONVERSATION_ASSIGNMENT": "Assigned to you",
|
||||
"SLA_MISSED_FIRST_RESPONSE": "SLA breach",
|
||||
"SLA_MISSED_NEXT_RESPONSE": "SLA breach",
|
||||
"SLA_MISSED_RESOLUTION": "SLA breach"
|
||||
"CONVERSATION_MENTION": "You have been mentioned in a conversation",
|
||||
"CONVERSATION_CREATION": "New conversation created",
|
||||
"CONVERSATION_ASSIGNMENT": "A conversation has been assigned to you",
|
||||
"ASSIGNED_CONVERSATION_NEW_MESSAGE": "New message in an assigned conversation",
|
||||
"PARTICIPATING_CONVERSATION_NEW_MESSAGE": "New message in a conversation you are participating in",
|
||||
"SLA_MISSED_FIRST_RESPONSE": "SLA target first response missed for conversation",
|
||||
"SLA_MISSED_NEXT_RESPONSE": "SLA target next response missed for conversation",
|
||||
"SLA_MISSED_RESOLUTION": "SLA target resolution missed for conversation"
|
||||
},
|
||||
"MENU_ITEM": {
|
||||
"MARK_AS_READ": "Mark as read",
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
"INBOX_MGMT": {
|
||||
"HEADER": "Inboxes",
|
||||
"SIDEBAR_TXT": "<p><b>Inbox</b></p> <p> When you connect a website or a facebook Page to Chatwoot, it is called an <b>Inbox</b>. You can have unlimited inboxes in your Chatwoot account. </p><p> Click on <b>Add Inbox</b> to connect a website or a Facebook Page. </p><p> In the Dashboard, you can see all the conversations from all your inboxes in a single place and respond to them under the `Conversations` tab. </p><p> You can also see conversations specific to an inbox by clicking on the inbox name on the left pane of the dashboard. </p>",
|
||||
"RECONNECTION_REQUIRED": "Your inbox is disconnected, you will not receive any new messages. <a class=\"underline\" href=\"%{actionUrl}\">Click here</a> to reconnect.",
|
||||
"LIST": {
|
||||
"404": "There are no inboxes attached to this account."
|
||||
},
|
||||
@@ -737,4 +736,4 @@
|
||||
"OTHER_PROVIDERS": "Other Providers"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"AGENT_LIST_LOADING": "Cargando agentes",
|
||||
"UPDATE": {
|
||||
"CHANGE_STATUS": "Cambiar estado",
|
||||
"SNOOZE_UNTIL": "Posponer",
|
||||
"SNOOZE_UNTIL_NEXT_REPLY": "Posponer hasta la próxima respuesta.",
|
||||
"UPDATE_SUCCESFUL": "El estado de la conversación se actualizó con éxito.",
|
||||
"UPDATE_FAILED": "No se han podido actualizar las conversaciones. Inténtalo de nuevo."
|
||||
},
|
||||
|
||||
@@ -84,7 +84,6 @@
|
||||
"CONFIRM": {
|
||||
"TITLE": "Exportar contactos",
|
||||
"MESSAGE": "¿Está seguro que desea exportar todos los contactos?",
|
||||
"FILTERED_MESSAGE": "Are you sure you want to export all the filtered contacts?",
|
||||
"YES": "Sí, exportar",
|
||||
"NO": "No, cancelar"
|
||||
}
|
||||
|
||||
@@ -107,7 +107,6 @@
|
||||
"GENERAL": "General",
|
||||
"REPORTS": "Informes",
|
||||
"CONVERSATION": "Conversación",
|
||||
"BULK_ACTIONS": "Bulk Actions",
|
||||
"CHANGE_ASSIGNEE": "Cambiar Asignado",
|
||||
"CHANGE_PRIORITY": "Cambiar prioridad",
|
||||
"CHANGE_TEAM": "Cambiar equipo",
|
||||
|
||||
@@ -109,8 +109,7 @@
|
||||
"SLA_MISSED_FIRST_RESPONSE": "A conversation misses first response SLA",
|
||||
"SLA_MISSED_NEXT_RESPONSE": "A conversation misses next response SLA",
|
||||
"SLA_MISSED_RESOLUTION": "A conversation misses resolution SLA"
|
||||
},
|
||||
"BROWSER_PERMISSION": "Enable push notifications for your browser so you’re able to receive them"
|
||||
}
|
||||
},
|
||||
"API": {
|
||||
"UPDATE_SUCCESS": "Sus preferencias de notificación se actualizaron correctamente",
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"AGENT_LIST_LOADING": "بارگذاری ایجنت ها",
|
||||
"UPDATE": {
|
||||
"CHANGE_STATUS": "تغییر وضعیت",
|
||||
"SNOOZE_UNTIL": "به تعویق انداختن",
|
||||
"SNOOZE_UNTIL_NEXT_REPLY": "تا پاسخ بعدی به تعویق بیافتد.",
|
||||
"UPDATE_SUCCESFUL": "وضعیت گفتگو با موفقیت به روز شد.",
|
||||
"UPDATE_FAILED": "گفتگوها به روز نشدند، لطفا دوباره امتحان کنید."
|
||||
},
|
||||
|
||||
@@ -84,7 +84,6 @@
|
||||
"CONFIRM": {
|
||||
"TITLE": "خروجی گرفتن مخاطب ها",
|
||||
"MESSAGE": "آیا مطمئن هستید که می خواهید از همه مخاطبین خروجی بگیرید؟",
|
||||
"FILTERED_MESSAGE": "Are you sure you want to export all the filtered contacts?",
|
||||
"YES": "بله، خروجی بگیر",
|
||||
"NO": "نه، انصراف"
|
||||
}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"DATE_PICKER": {
|
||||
"APPLY_BUTTON": "درخواست دادن",
|
||||
"CLEAR_BUTTON": "پاک کردن",
|
||||
"CLEAR_BUTTON": "Clear",
|
||||
"DATE_RANGE_INPUT": {
|
||||
"START": "تاریخ شروع",
|
||||
"END": "تاریخ پایان"
|
||||
"START": "Start Date",
|
||||
"END": "End Date"
|
||||
},
|
||||
"DATE_RANGE_OPTIONS": {
|
||||
"TITLE": "محدوده زمانی",
|
||||
"TITLE": "DATE RANGE",
|
||||
"LAST_7_DAYS": "در ۷ روز گذشته",
|
||||
"LAST_30_DAYS": "در ۳۰ روز گذشته",
|
||||
"LAST_3_MONTHS": "۳ ماه گذشته",
|
||||
|
||||
@@ -107,7 +107,6 @@
|
||||
"GENERAL": "عمومی",
|
||||
"REPORTS": "گزارشات",
|
||||
"CONVERSATION": "گفتگو",
|
||||
"BULK_ACTIONS": "Bulk Actions",
|
||||
"CHANGE_ASSIGNEE": "اپراتور را تغییر دهید",
|
||||
"CHANGE_PRIORITY": "تغییر اولویت",
|
||||
"CHANGE_TEAM": "تیم را تغییر دهید",
|
||||
|
||||
@@ -81,12 +81,12 @@
|
||||
"HELP_TEXT": {
|
||||
"TITLE": "استفاده از اسلک",
|
||||
"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>",
|
||||
"SELECTED": "انتخاب شد"
|
||||
"SELECTED": "selected"
|
||||
},
|
||||
"SELECT_CHANNEL": {
|
||||
"OPTION_LABEL": "یک کانال انتخاب کنید",
|
||||
"OPTION_LABEL": "Select a channel",
|
||||
"UPDATE": "اعمال شود",
|
||||
"BUTTON_TEXT": "اتصال کانال",
|
||||
"BUTTON_TEXT": "Connect channel",
|
||||
"DESCRIPTION": "Your Slack workspace is now linked with Chatwoot. However, the integration is currently inactive. To activate the integration and connect a channel to Chatwoot, please click the button below.\n\n**Note:** If you are attempting to connect a private channel, add the Chatwoot app to the Slack channel before proceeding with this step.",
|
||||
"ATTENTION_REQUIRED": "Attention required",
|
||||
"EXPIRED": "Your Slack integration has expired. To continue receiving messages on Slack, please delete the integration and connect your workspace again."
|
||||
@@ -106,7 +106,7 @@
|
||||
"AI_ASSIST": "دستیار هوش مصنوعی",
|
||||
"WITH_AI": " %{option} with AI ",
|
||||
"OPTIONS": {
|
||||
"REPLY_SUGGESTION": "پیشنهاد پاسخ",
|
||||
"REPLY_SUGGESTION": "Reply Suggestion",
|
||||
"SUMMARIZE": "Summarize",
|
||||
"REPHRASE": "Improve Writing",
|
||||
"FIX_SPELLING_GRAMMAR": "Fix Spelling and Grammar",
|
||||
@@ -144,13 +144,13 @@
|
||||
"TONE": {
|
||||
"TITLE": "Tone",
|
||||
"OPTIONS": {
|
||||
"PROFESSIONAL": "حرفهای",
|
||||
"PROFESSIONAL": "Professional",
|
||||
"FRIENDLY": "دوستانه"
|
||||
}
|
||||
},
|
||||
"BUTTONS": {
|
||||
"GENERATE": "تولید",
|
||||
"GENERATING": "در حال تولید...",
|
||||
"GENERATE": "Generate",
|
||||
"GENERATING": "Generating...",
|
||||
"CANCEL": "انصراف"
|
||||
},
|
||||
"GENERATE_ERROR": "There was an error processing the content, please try again"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
"PASSWORD_UPDATE_SUCCESS": "رمز عبورتان عوض شد",
|
||||
"AFTER_EMAIL_CHANGED": "پروفایلتان با موفقیت تغییر یافت، اطلاعات ورود به سیستم تغییر کرده لذا لطفا مجددا به سیستم وارد شوید",
|
||||
"FORM": {
|
||||
"PICTURE": "عکس نمایه",
|
||||
"PICTURE": "Profile Picture",
|
||||
"AVATAR": "عکس پروفایل",
|
||||
"ERROR": "لطفا ایرادات ذکر شده را برطرف کنید",
|
||||
"REMOVE_IMAGE": "حذف",
|
||||
@@ -65,7 +65,7 @@
|
||||
"NOTE": "اعلان های صوتی را در داشبورد برای پیام ها و مکالمات جدید فعال کنید.",
|
||||
"ALERT_TYPES": {
|
||||
"NONE": "هیچکدام",
|
||||
"MINE": "اختصاص داده",
|
||||
"MINE": "Assigned",
|
||||
"ALL": "همه"
|
||||
},
|
||||
"ALERT_TYPE": {
|
||||
@@ -96,8 +96,8 @@
|
||||
"SLA_MISSED_RESOLUTION": "هر وقت گفتگویی سیاست SLA مربوط به زمان حل موضوع را نقض کرد ایمیل ارسال کن"
|
||||
},
|
||||
"NOTIFICATIONS": {
|
||||
"TITLE": "تنظیمات آگاهسازی",
|
||||
"TYPE_TITLE": "نوع آگاهسازی",
|
||||
"TITLE": "Notification preferences",
|
||||
"TYPE_TITLE": "Notification type",
|
||||
"EMAIL": "ایمیل",
|
||||
"PUSH": "Push notification",
|
||||
"TYPES": {
|
||||
@@ -109,8 +109,7 @@
|
||||
"SLA_MISSED_FIRST_RESPONSE": "A conversation misses first response SLA",
|
||||
"SLA_MISSED_NEXT_RESPONSE": "A conversation misses next response SLA",
|
||||
"SLA_MISSED_RESOLUTION": "A conversation misses resolution SLA"
|
||||
},
|
||||
"BROWSER_PERMISSION": "Enable push notifications for your browser so you’re able to receive them"
|
||||
}
|
||||
},
|
||||
"API": {
|
||||
"UPDATE_SUCCESS": "تغییرات تنظیمات اعلامیهها با موفقیت ثبت شد",
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"AGENT_LIST_LOADING": "Loading agents",
|
||||
"UPDATE": {
|
||||
"CHANGE_STATUS": "Change status",
|
||||
"SNOOZE_UNTIL": "Snooze",
|
||||
"SNOOZE_UNTIL_NEXT_REPLY": "Snooze until next reply.",
|
||||
"UPDATE_SUCCESFUL": "Conversation status updated successfully.",
|
||||
"UPDATE_FAILED": "Failed to update conversations. Please try again."
|
||||
},
|
||||
|
||||
@@ -84,7 +84,6 @@
|
||||
"CONFIRM": {
|
||||
"TITLE": "Export Contacts",
|
||||
"MESSAGE": "Are you sure you want to export all contacts?",
|
||||
"FILTERED_MESSAGE": "Are you sure you want to export all the filtered contacts?",
|
||||
"YES": "Yes, Export",
|
||||
"NO": "No, Cancel"
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user