Compare commits
48
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e1f79025e | ||
|
|
e84efdccbd | ||
|
|
44da47c845 | ||
|
|
0ebe187c8a | ||
|
|
5491ca2470 | ||
|
|
72391f9c36 | ||
|
|
f89d9a4401 | ||
|
|
e8ae73230d | ||
|
|
40c75941f5 | ||
|
|
d9b840f161 | ||
|
|
1fbdd68222 | ||
|
|
ef54f07d5b | ||
|
|
e771d99552 | ||
|
|
358a3924b8 | ||
|
|
6b87d6784e | ||
|
|
faaf67129e | ||
|
|
159c810117 | ||
|
|
ce400a36d7 | ||
|
|
d20de25da1 | ||
|
|
c31d693add | ||
|
|
31497d9c63 | ||
|
|
a35c3e4c06 | ||
|
|
344e8d5016 | ||
|
|
3e27e28848 | ||
|
|
38af08534c | ||
|
|
20d6a11dd9 | ||
|
|
5dc5037903 | ||
|
|
3c7b4f6011 | ||
|
|
73f2aea514 | ||
|
|
02424a5a09 | ||
|
|
b015c61d71 | ||
|
|
d483974ef1 | ||
|
|
b16b1b6a49 | ||
|
|
b28d00a117 | ||
|
|
2b3ad3dc74 | ||
|
|
b95944dd4e | ||
|
|
75ba8e9186 | ||
|
|
31969428ae | ||
|
|
a4fab22e28 | ||
|
|
5d27fd798f | ||
|
|
ca14eba448 | ||
|
|
199a55a8e3 | ||
|
|
873094175b | ||
|
|
096bffa893 | ||
|
|
ccbc2c5d56 | ||
|
|
2c0f235d1d | ||
|
|
fc067b7f66 | ||
|
|
eacfa2e19a |
@@ -256,6 +256,8 @@ AZURE_APP_SECRET=
|
|||||||
## Change these values to fine tune performance
|
## Change these values to fine tune performance
|
||||||
# control the concurrency setting of sidekiq
|
# control the concurrency setting of sidekiq
|
||||||
# SIDEKIQ_CONCURRENCY=10
|
# SIDEKIQ_CONCURRENCY=10
|
||||||
|
# Enable verbose logging each time a job is dequeued in Sidekiq
|
||||||
|
# ENABLE_SIDEKIQ_DEQUEUE_LOGGER=false
|
||||||
|
|
||||||
|
|
||||||
# AI powered features
|
# AI powered features
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ gem 'telephone_number'
|
|||||||
gem 'time_diff'
|
gem 'time_diff'
|
||||||
gem 'tzinfo-data'
|
gem 'tzinfo-data'
|
||||||
gem 'valid_email2'
|
gem 'valid_email2'
|
||||||
gem 'octokit'
|
gem 'email-provider-info'
|
||||||
# compress javascript config.assets.js_compressor
|
# compress javascript config.assets.js_compressor
|
||||||
gem 'uglifier'
|
gem 'uglifier'
|
||||||
##-- used for single column multiple binary flags in notification settings/feature flagging --##
|
##-- used for single column multiple binary flags in notification settings/feature flagging --##
|
||||||
|
|||||||
+4
-9
@@ -270,6 +270,7 @@ GEM
|
|||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
http (>= 3.0)
|
http (>= 3.0)
|
||||||
ruby2_keywords
|
ruby2_keywords
|
||||||
|
email-provider-info (0.0.1)
|
||||||
email_reply_trimmer (0.1.13)
|
email_reply_trimmer (0.1.13)
|
||||||
erubi (1.13.0)
|
erubi (1.13.0)
|
||||||
et-orbi (1.2.11)
|
et-orbi (1.2.11)
|
||||||
@@ -591,13 +592,10 @@ GEM
|
|||||||
rack (>= 1.2, < 4)
|
rack (>= 1.2, < 4)
|
||||||
snaky_hash (~> 2.0)
|
snaky_hash (~> 2.0)
|
||||||
version_gem (~> 1.1)
|
version_gem (~> 1.1)
|
||||||
octokit (10.0.0)
|
|
||||||
faraday (>= 1, < 3)
|
|
||||||
sawyer (~> 0.9)
|
|
||||||
oj (3.16.10)
|
oj (3.16.10)
|
||||||
bigdecimal (>= 3.0)
|
bigdecimal (>= 3.0)
|
||||||
ostruct (>= 0.2)
|
ostruct (>= 0.2)
|
||||||
omniauth (2.1.3)
|
omniauth (2.1.4)
|
||||||
hashie (>= 3.4.6)
|
hashie (>= 3.4.6)
|
||||||
logger
|
logger
|
||||||
rack (>= 2.2.3)
|
rack (>= 2.2.3)
|
||||||
@@ -656,7 +654,7 @@ GEM
|
|||||||
rack (>= 2.0.0)
|
rack (>= 2.0.0)
|
||||||
rack-mini-profiler (3.2.0)
|
rack-mini-profiler (3.2.0)
|
||||||
rack (>= 1.2.0)
|
rack (>= 1.2.0)
|
||||||
rack-protection (4.1.1)
|
rack-protection (4.2.1)
|
||||||
base64 (>= 0.1.0)
|
base64 (>= 0.1.0)
|
||||||
logger (>= 1.6.0)
|
logger (>= 1.6.0)
|
||||||
rack (>= 3.0.0, < 4)
|
rack (>= 3.0.0, < 4)
|
||||||
@@ -820,9 +818,6 @@ GEM
|
|||||||
sprockets (> 3.0)
|
sprockets (> 3.0)
|
||||||
sprockets-rails
|
sprockets-rails
|
||||||
tilt
|
tilt
|
||||||
sawyer (0.9.2)
|
|
||||||
addressable (>= 2.3.5)
|
|
||||||
faraday (>= 0.17.3, < 3)
|
|
||||||
scout_apm (5.3.3)
|
scout_apm (5.3.3)
|
||||||
parser
|
parser
|
||||||
scss_lint (0.60.0)
|
scss_lint (0.60.0)
|
||||||
@@ -1022,6 +1017,7 @@ DEPENDENCIES
|
|||||||
dotenv-rails (>= 3.0.0)
|
dotenv-rails (>= 3.0.0)
|
||||||
down
|
down
|
||||||
elastic-apm
|
elastic-apm
|
||||||
|
email-provider-info
|
||||||
email_reply_trimmer
|
email_reply_trimmer
|
||||||
facebook-messenger
|
facebook-messenger
|
||||||
factory_bot_rails (>= 6.4.3)
|
factory_bot_rails (>= 6.4.3)
|
||||||
@@ -1063,7 +1059,6 @@ DEPENDENCIES
|
|||||||
net-smtp (~> 0.3.4)
|
net-smtp (~> 0.3.4)
|
||||||
newrelic-sidekiq-metrics (>= 1.6.2)
|
newrelic-sidekiq-metrics (>= 1.6.2)
|
||||||
newrelic_rpm
|
newrelic_rpm
|
||||||
octokit
|
|
||||||
omniauth (>= 2.1.2)
|
omniauth (>= 2.1.2)
|
||||||
omniauth-google-oauth2 (>= 1.1.3)
|
omniauth-google-oauth2 (>= 1.1.3)
|
||||||
omniauth-oauth2
|
omniauth-oauth2
|
||||||
|
|||||||
@@ -36,6 +36,10 @@
|
|||||||
"REDIS_OPENSSL_VERIFY_MODE":{
|
"REDIS_OPENSSL_VERIFY_MODE":{
|
||||||
"description": "OpenSSL verification mode for Redis connections. ref https://help.heroku.com/HC0F8CUS/redis-connection-issues",
|
"description": "OpenSSL verification mode for Redis connections. ref https://help.heroku.com/HC0F8CUS/redis-connection-issues",
|
||||||
"value": "none"
|
"value": "none"
|
||||||
|
},
|
||||||
|
"NODE_OPTIONS": {
|
||||||
|
"description": "Increase V8 heap for Vite build to avoid OOM",
|
||||||
|
"value": "--max-old-space-size=4096"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"formation": {
|
"formation": {
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ class Messages::MessageBuilder
|
|||||||
process_emails
|
process_emails
|
||||||
# When the message has no quoted content, it will just be rendered as a regular message
|
# When the message has no quoted content, it will just be rendered as a regular message
|
||||||
# The frontend is equipped to handle this case
|
# The frontend is equipped to handle this case
|
||||||
process_email_content if @account.feature_enabled?(:quoted_email_reply)
|
process_email_content
|
||||||
@message.save!
|
@message.save!
|
||||||
@message
|
@message
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
class Api::V1::Accounts::BulkActionsController < Api::V1::Accounts::BaseController
|
class Api::V1::Accounts::BulkActionsController < Api::V1::Accounts::BaseController
|
||||||
before_action :type_matches?
|
|
||||||
|
|
||||||
def create
|
def create
|
||||||
if type_matches?
|
case normalized_type
|
||||||
::BulkActionsJob.perform_later(
|
when 'Conversation'
|
||||||
account: @current_account,
|
enqueue_conversation_job
|
||||||
user: current_user,
|
head :ok
|
||||||
params: permitted_params
|
when 'Contact'
|
||||||
)
|
check_authorization_for_contact_action
|
||||||
|
enqueue_contact_job
|
||||||
head :ok
|
head :ok
|
||||||
else
|
else
|
||||||
render json: { success: false }, status: :unprocessable_entity
|
render json: { success: false }, status: :unprocessable_entity
|
||||||
@@ -16,11 +15,54 @@ class Api::V1::Accounts::BulkActionsController < Api::V1::Accounts::BaseControll
|
|||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def type_matches?
|
def normalized_type
|
||||||
['Conversation'].include?(params[:type])
|
params[:type].to_s.camelize
|
||||||
end
|
end
|
||||||
|
|
||||||
def permitted_params
|
def enqueue_conversation_job
|
||||||
params.permit(:type, :snoozed_until, ids: [], fields: [:status, :assignee_id, :team_id], labels: [add: [], remove: []])
|
::BulkActionsJob.perform_later(
|
||||||
|
account: @current_account,
|
||||||
|
user: current_user,
|
||||||
|
params: conversation_params
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def enqueue_contact_job
|
||||||
|
Contacts::BulkActionJob.perform_later(
|
||||||
|
@current_account.id,
|
||||||
|
current_user.id,
|
||||||
|
contact_params
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def delete_contact_action?
|
||||||
|
params[:action_name] == 'delete'
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_authorization_for_contact_action
|
||||||
|
authorize(Contact, :destroy?) if delete_contact_action?
|
||||||
|
end
|
||||||
|
|
||||||
|
def conversation_params
|
||||||
|
# TODO: Align conversation payloads with the `{ action_name, action_attributes }`
|
||||||
|
# and then remove this method in favor of a common params method.
|
||||||
|
base = params.permit(
|
||||||
|
:snoozed_until,
|
||||||
|
fields: [:status, :assignee_id, :team_id]
|
||||||
|
)
|
||||||
|
append_common_bulk_attributes(base)
|
||||||
|
end
|
||||||
|
|
||||||
|
def contact_params
|
||||||
|
# TODO: remove this method in favor of a common params method.
|
||||||
|
# once legacy conversation payloads are migrated.
|
||||||
|
append_common_bulk_attributes({})
|
||||||
|
end
|
||||||
|
|
||||||
|
def append_common_bulk_attributes(base_params)
|
||||||
|
# NOTE: Conversation payloads historically diverged per action. Going forward we
|
||||||
|
# want all objects to share a common contract: `{ action_name, action_attributes }`
|
||||||
|
common = params.permit(:type, :action_name, ids: [], labels: [add: [], remove: []])
|
||||||
|
base_params.merge(common)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,155 +0,0 @@
|
|||||||
class Api::V1::Accounts::Integrations::GithubController < Api::V1::Accounts::BaseController
|
|
||||||
before_action :fetch_hook
|
|
||||||
before_action :ensure_hook_exists, except: [:destroy]
|
|
||||||
|
|
||||||
def destroy
|
|
||||||
@hook.destroy!
|
|
||||||
head :ok
|
|
||||||
end
|
|
||||||
|
|
||||||
def repositories
|
|
||||||
repositories = github_service.repositories
|
|
||||||
filtered_repos = repositories.map do |repo|
|
|
||||||
{
|
|
||||||
full_name: repo[:full_name] || repo.full_name,
|
|
||||||
private: repo[:private] || repo.private
|
|
||||||
}
|
|
||||||
end
|
|
||||||
render json: filtered_repos
|
|
||||||
end
|
|
||||||
|
|
||||||
def search_repositories
|
|
||||||
repositories = github_service.search_repositories(params[:q])
|
|
||||||
filtered_repos = repositories.map do |repo|
|
|
||||||
{
|
|
||||||
full_name: repo[:full_name] || repo.full_name,
|
|
||||||
private: repo[:private] || repo.private
|
|
||||||
}
|
|
||||||
end
|
|
||||||
render json: filtered_repos
|
|
||||||
end
|
|
||||||
|
|
||||||
def assignees
|
|
||||||
assignees = github_service.assignees(repo_full_name)
|
|
||||||
filtered_assignees = assignees.map do |assignee|
|
|
||||||
{
|
|
||||||
login: assignee.login,
|
|
||||||
avatar_url: assignee.avatar_url
|
|
||||||
}
|
|
||||||
end
|
|
||||||
render json: filtered_assignees
|
|
||||||
end
|
|
||||||
|
|
||||||
def labels
|
|
||||||
labels = github_service.labels(repo_full_name)
|
|
||||||
filtered_labels = labels.map do |label|
|
|
||||||
{
|
|
||||||
name: label.name,
|
|
||||||
color: label.color
|
|
||||||
}
|
|
||||||
end
|
|
||||||
render json: filtered_labels
|
|
||||||
end
|
|
||||||
|
|
||||||
def search_issues
|
|
||||||
issues = github_service.search_issues(repo_full_name, params[:q])
|
|
||||||
filtered_issues = issues.map do |issue|
|
|
||||||
{
|
|
||||||
number: issue.number,
|
|
||||||
title: issue.title,
|
|
||||||
html_url: issue.html_url
|
|
||||||
}
|
|
||||||
end
|
|
||||||
render json: filtered_issues
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_issue
|
|
||||||
issue_data = github_service.create_issue(
|
|
||||||
repo_full_name,
|
|
||||||
params[:title],
|
|
||||||
params[:body],
|
|
||||||
issue_options
|
|
||||||
)
|
|
||||||
|
|
||||||
github_issue = create_linked_issue(issue_data)
|
|
||||||
render json: issue_response(github_issue), status: :created
|
|
||||||
end
|
|
||||||
|
|
||||||
def link_issue
|
|
||||||
issue_data = github_service.issue(repo_full_name, params[:issue_number])
|
|
||||||
github_issue = create_linked_issue(issue_data)
|
|
||||||
render json: issue_response(github_issue), status: :created
|
|
||||||
end
|
|
||||||
|
|
||||||
def linked_issues
|
|
||||||
issues = GithubIssue.where(conversation_id: params[:conversation_id])
|
|
||||||
|
|
||||||
render json: issues.map do |issue|
|
|
||||||
{
|
|
||||||
id: issue.id,
|
|
||||||
issue_number: issue.issue_number,
|
|
||||||
title: issue.issue_title,
|
|
||||||
html_url: issue.html_url,
|
|
||||||
repo_full_name: issue.repo_full_name,
|
|
||||||
linked_by: {
|
|
||||||
id: issue.linked_by.id,
|
|
||||||
name: issue.linked_by.name
|
|
||||||
},
|
|
||||||
created_at: issue.created_at
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def unlink_issue
|
|
||||||
github_issue = GithubIssue.find(params[:id])
|
|
||||||
github_issue.destroy!
|
|
||||||
head :ok
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def fetch_hook
|
|
||||||
@hook = Integrations::Hook.where(account: Current.account).find_by(app_id: 'github')
|
|
||||||
end
|
|
||||||
|
|
||||||
def ensure_hook_exists
|
|
||||||
render json: { error: 'GitHub integration not configured' }, status: :unauthorized unless @hook
|
|
||||||
end
|
|
||||||
|
|
||||||
def github_service
|
|
||||||
@github_service ||= Github::GithubService.new(hook: @hook)
|
|
||||||
end
|
|
||||||
|
|
||||||
def repo_full_name
|
|
||||||
params[:repo_full_name] || "#{params[:owner]}/#{params[:repo]}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def issue_options
|
|
||||||
options = {}
|
|
||||||
options[:assignees] = params[:assignees] if params[:assignees].present?
|
|
||||||
options[:labels] = params[:labels] if params[:labels].present?
|
|
||||||
options
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_linked_issue(issue_data)
|
|
||||||
GithubIssue.create!(
|
|
||||||
conversation_id: params[:conversation_id],
|
|
||||||
account: Current.account,
|
|
||||||
repo_full_name: repo_full_name,
|
|
||||||
issue_number: issue_data.number,
|
|
||||||
issue_title: issue_data.title,
|
|
||||||
html_url: issue_data.html_url,
|
|
||||||
linked_by: Current.user
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def issue_response(github_issue)
|
|
||||||
{
|
|
||||||
id: github_issue.id,
|
|
||||||
issue_number: github_issue.issue_number,
|
|
||||||
title: github_issue.issue_title,
|
|
||||||
html_url: github_issue.html_url,
|
|
||||||
repo_full_name: github_issue.repo_full_name
|
|
||||||
}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
class Github::CallbacksController < ApplicationController
|
|
||||||
include Github::IntegrationHelper
|
|
||||||
|
|
||||||
def show
|
|
||||||
# Validate account context early for all flows that require it
|
|
||||||
account if params[:code].present?
|
|
||||||
|
|
||||||
if params[:installation_id].present? && params[:code].present?
|
|
||||||
# Both installation and OAuth code present - handle both
|
|
||||||
handle_installation_with_oauth
|
|
||||||
elsif params[:installation_id].present?
|
|
||||||
# Only installation_id present - redirect to OAuth
|
|
||||||
handle_installation
|
|
||||||
else
|
|
||||||
# Only OAuth code present - handle authorization
|
|
||||||
handle_authorization
|
|
||||||
end
|
|
||||||
rescue StandardError => e
|
|
||||||
Rails.logger.error("Github callback error: #{e.message}")
|
|
||||||
redirect_to fallback_redirect_uri
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def handle_installation_with_oauth
|
|
||||||
# Handle both installation and OAuth in one go
|
|
||||||
installation_id = params[:installation_id]
|
|
||||||
|
|
||||||
@response = oauth_client.auth_code.get_token(
|
|
||||||
params[:code],
|
|
||||||
redirect_uri: "#{base_url}/github/callback"
|
|
||||||
)
|
|
||||||
|
|
||||||
handle_response(installation_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_installation
|
|
||||||
if params[:setup_action] == 'install'
|
|
||||||
installation_id = params[:installation_id]
|
|
||||||
|
|
||||||
redirect_to build_oauth_url(installation_id)
|
|
||||||
else
|
|
||||||
Rails.logger.error("Unknown setup_action: #{params[:setup_action]}")
|
|
||||||
redirect_to github_integration_settings_url
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_authorization
|
|
||||||
@response = oauth_client.auth_code.get_token(
|
|
||||||
params[:code],
|
|
||||||
redirect_uri: "#{base_url}/github/callback"
|
|
||||||
)
|
|
||||||
|
|
||||||
handle_response
|
|
||||||
end
|
|
||||||
|
|
||||||
def build_oauth_url(installation_id)
|
|
||||||
GlobalConfigService.load('GITHUB_CLIENT_ID', nil)
|
|
||||||
|
|
||||||
# Store installation_id in session for later use
|
|
||||||
session[:github_installation_id] = installation_id
|
|
||||||
|
|
||||||
# For now, redirect to a page that will initiate OAuth with proper account context
|
|
||||||
# This is a temporary solution until we have a proper account-agnostic setup
|
|
||||||
"#{ENV.fetch('FRONTEND_URL', nil)}/app/accounts/1/settings/integrations/github?setup_action=install&installation_id=#{installation_id}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def oauth_client
|
|
||||||
app_id = GlobalConfigService.load('GITHUB_CLIENT_ID', nil)
|
|
||||||
app_secret = GlobalConfigService.load('GITHUB_CLIENT_SECRET', nil)
|
|
||||||
|
|
||||||
OAuth2::Client.new(
|
|
||||||
app_id,
|
|
||||||
app_secret,
|
|
||||||
{
|
|
||||||
site: 'https://github.com',
|
|
||||||
token_url: '/login/oauth/access_token',
|
|
||||||
authorize_url: '/login/oauth/authorize'
|
|
||||||
}
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_response(installation_id = nil)
|
|
||||||
settings = build_hook_settings(installation_id)
|
|
||||||
hook = create_integration_hook(settings)
|
|
||||||
hook.save!
|
|
||||||
|
|
||||||
cleanup_session_data
|
|
||||||
redirect_to github_redirect_uri
|
|
||||||
rescue StandardError => e
|
|
||||||
Rails.logger.error("Github callback error: #{e.message}")
|
|
||||||
redirect_to fallback_redirect_uri
|
|
||||||
end
|
|
||||||
|
|
||||||
def build_hook_settings(installation_id)
|
|
||||||
settings = {
|
|
||||||
token_type: parsed_body['token_type'],
|
|
||||||
scope: parsed_body['scope']
|
|
||||||
}
|
|
||||||
|
|
||||||
settings[:installation_id] = installation_id || session[:github_installation_id]
|
|
||||||
settings.compact
|
|
||||||
end
|
|
||||||
|
|
||||||
def create_integration_hook(settings)
|
|
||||||
account.hooks.new(
|
|
||||||
access_token: parsed_body['access_token'],
|
|
||||||
status: 'enabled',
|
|
||||||
app_id: 'github',
|
|
||||||
settings: settings
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
def cleanup_session_data
|
|
||||||
session.delete(:github_installation_id)
|
|
||||||
end
|
|
||||||
|
|
||||||
def account
|
|
||||||
@account ||= account_from_state
|
|
||||||
end
|
|
||||||
|
|
||||||
def account_from_state
|
|
||||||
raise ActionController::BadRequest, 'Missing state variable' if params[:state].blank?
|
|
||||||
|
|
||||||
# Try signed GlobalID first (installation flow)
|
|
||||||
account = GlobalID::Locator.locate_signed(params[:state])
|
|
||||||
return account if account
|
|
||||||
|
|
||||||
# Fallback to JWT token (direct OAuth flow)
|
|
||||||
account_id = verify_github_token(params[:state])
|
|
||||||
return Account.find(account_id) if account_id
|
|
||||||
|
|
||||||
raise 'Invalid or expired state'
|
|
||||||
rescue StandardError
|
|
||||||
raise ActionController::BadRequest, 'Invalid account context'
|
|
||||||
end
|
|
||||||
|
|
||||||
def github_redirect_uri
|
|
||||||
"#{ENV.fetch('FRONTEND_URL', nil)}/app/accounts/#{account.id}/settings/integrations/github"
|
|
||||||
end
|
|
||||||
|
|
||||||
def github_integration_settings_url
|
|
||||||
"#{ENV.fetch('FRONTEND_URL', nil)}/app/accounts/1/settings/integrations/github"
|
|
||||||
end
|
|
||||||
|
|
||||||
def fallback_redirect_uri
|
|
||||||
github_redirect_uri
|
|
||||||
rescue StandardError
|
|
||||||
# Fallback if no account context available
|
|
||||||
"#{ENV.fetch('FRONTEND_URL', nil)}/app/settings/integrations"
|
|
||||||
end
|
|
||||||
|
|
||||||
def parsed_body
|
|
||||||
@parsed_body ||= @response.response.parsed
|
|
||||||
end
|
|
||||||
|
|
||||||
def base_url
|
|
||||||
ENV.fetch('FRONTEND_URL', 'http://localhost:3000')
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -42,8 +42,7 @@ class SuperAdmin::AppConfigsController < SuperAdmin::ApplicationController
|
|||||||
'instagram' => %w[INSTAGRAM_APP_ID INSTAGRAM_APP_SECRET INSTAGRAM_VERIFY_TOKEN INSTAGRAM_API_VERSION ENABLE_INSTAGRAM_CHANNEL_HUMAN_AGENT],
|
'instagram' => %w[INSTAGRAM_APP_ID INSTAGRAM_APP_SECRET INSTAGRAM_VERIFY_TOKEN INSTAGRAM_API_VERSION ENABLE_INSTAGRAM_CHANNEL_HUMAN_AGENT],
|
||||||
'whatsapp_embedded' => %w[WHATSAPP_APP_ID WHATSAPP_APP_SECRET WHATSAPP_CONFIGURATION_ID WHATSAPP_API_VERSION],
|
'whatsapp_embedded' => %w[WHATSAPP_APP_ID WHATSAPP_APP_SECRET WHATSAPP_CONFIGURATION_ID WHATSAPP_API_VERSION],
|
||||||
'notion' => %w[NOTION_CLIENT_ID NOTION_CLIENT_SECRET],
|
'notion' => %w[NOTION_CLIENT_ID NOTION_CLIENT_SECRET],
|
||||||
'google' => %w[GOOGLE_OAUTH_CLIENT_ID GOOGLE_OAUTH_CLIENT_SECRET GOOGLE_OAUTH_REDIRECT_URI],
|
'google' => %w[GOOGLE_OAUTH_CLIENT_ID GOOGLE_OAUTH_CLIENT_SECRET GOOGLE_OAUTH_REDIRECT_URI]
|
||||||
'github' => %w[GITHUB_CLIENT_ID GITHUB_CLIENT_SECRET]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@allowed_configs = mapping.fetch(@config, %w[ENABLE_ACCOUNT_SIGNUP FIREBASE_PROJECT_ID FIREBASE_CREDENTIALS])
|
@allowed_configs = mapping.fetch(@config, %w[ENABLE_ACCOUNT_SIGNUP FIREBASE_PROJECT_ID FIREBASE_CREDENTIALS])
|
||||||
|
|||||||
@@ -1,47 +0,0 @@
|
|||||||
module Github::IntegrationHelper
|
|
||||||
# Generates a signed JWT token for Github integration
|
|
||||||
#
|
|
||||||
# @param account_id [Integer] The account ID to encode in the token
|
|
||||||
# @return [String, nil] The encoded JWT token or nil if client secret is missing
|
|
||||||
def generate_github_token(account_id)
|
|
||||||
return if github_client_secret.blank?
|
|
||||||
|
|
||||||
JWT.encode(github_token_payload(account_id), github_client_secret, 'HS256')
|
|
||||||
rescue StandardError => e
|
|
||||||
Rails.logger.error("Failed to generate Github token: #{e.message}")
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
|
|
||||||
def github_token_payload(account_id)
|
|
||||||
{
|
|
||||||
sub: account_id,
|
|
||||||
iat: Time.current.to_i
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
# Verifies and decodes a Github JWT token
|
|
||||||
#
|
|
||||||
# @param token [String] The JWT token to verify
|
|
||||||
# @return [Integer, nil] The account ID from the token or nil if invalid
|
|
||||||
def verify_github_token(token)
|
|
||||||
return if token.blank? || github_client_secret.blank?
|
|
||||||
|
|
||||||
github_decode_token(token, github_client_secret)
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def github_client_secret
|
|
||||||
@github_client_secret ||= GlobalConfigService.load('GITHUB_CLIENT_SECRET', nil)
|
|
||||||
end
|
|
||||||
|
|
||||||
def github_decode_token(token, secret)
|
|
||||||
JWT.decode(token, secret, true, {
|
|
||||||
algorithm: 'HS256',
|
|
||||||
verify_expiration: true
|
|
||||||
}).first['sub']
|
|
||||||
rescue StandardError => e
|
|
||||||
Rails.logger.error("Unexpected error verifying Github token: #{e.message}")
|
|
||||||
nil
|
|
||||||
end
|
|
||||||
end
|
|
||||||
+38
-35
@@ -5,6 +5,7 @@ import { useToggle } from '@vueuse/core';
|
|||||||
|
|
||||||
import Button from 'dashboard/components-next/button/Button.vue';
|
import Button from 'dashboard/components-next/button/Button.vue';
|
||||||
import ConfirmContactDeleteDialog from 'dashboard/components-next/Contacts/ContactsForm/ConfirmContactDeleteDialog.vue';
|
import ConfirmContactDeleteDialog from 'dashboard/components-next/Contacts/ContactsForm/ConfirmContactDeleteDialog.vue';
|
||||||
|
import Policy from 'dashboard/components/policy.vue';
|
||||||
|
|
||||||
defineProps({
|
defineProps({
|
||||||
selectedContact: {
|
selectedContact: {
|
||||||
@@ -24,42 +25,44 @@ const openConfirmDeleteContactDialog = () => {
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col items-start border-t border-n-strong px-6 py-5">
|
<Policy :permissions="['administrator']">
|
||||||
<Button
|
<div class="flex flex-col items-start border-t border-n-strong px-6 py-5">
|
||||||
:label="t('CONTACTS_LAYOUT.DETAILS.DELETE_CONTACT')"
|
<Button
|
||||||
sm
|
:label="t('CONTACTS_LAYOUT.DETAILS.DELETE_CONTACT')"
|
||||||
link
|
sm
|
||||||
slate
|
link
|
||||||
class="hover:!no-underline text-n-slate-12"
|
slate
|
||||||
icon="i-lucide-chevron-down"
|
class="hover:!no-underline text-n-slate-12"
|
||||||
trailing-icon
|
icon="i-lucide-chevron-down"
|
||||||
@click="toggleDeleteSection()"
|
trailing-icon
|
||||||
/>
|
@click="toggleDeleteSection()"
|
||||||
|
/>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class="transition-all duration-300 ease-in-out grid w-full overflow-hidden"
|
class="transition-all duration-300 ease-in-out grid w-full overflow-hidden"
|
||||||
:class="
|
:class="
|
||||||
showDeleteSection
|
showDeleteSection
|
||||||
? 'grid-rows-[1fr] opacity-100 mt-2'
|
? 'grid-rows-[1fr] opacity-100 mt-2'
|
||||||
: 'grid-rows-[0fr] opacity-0 mt-0'
|
: 'grid-rows-[0fr] opacity-0 mt-0'
|
||||||
"
|
"
|
||||||
>
|
>
|
||||||
<div class="overflow-hidden min-h-0">
|
<div class="overflow-hidden min-h-0">
|
||||||
<span class="inline-flex text-n-slate-11 text-sm items-center gap-1">
|
<span class="inline-flex text-n-slate-11 text-sm items-center gap-1">
|
||||||
{{ t('CONTACTS_LAYOUT.CARD.DELETE_CONTACT.MESSAGE') }}
|
{{ t('CONTACTS_LAYOUT.CARD.DELETE_CONTACT.MESSAGE') }}
|
||||||
<Button
|
<Button
|
||||||
:label="t('CONTACTS_LAYOUT.CARD.DELETE_CONTACT.BUTTON')"
|
:label="t('CONTACTS_LAYOUT.CARD.DELETE_CONTACT.BUTTON')"
|
||||||
sm
|
sm
|
||||||
ruby
|
ruby
|
||||||
link
|
link
|
||||||
@click="openConfirmDeleteContactDialog()"
|
@click="openConfirmDeleteContactDialog()"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<ConfirmContactDeleteDialog
|
||||||
<ConfirmContactDeleteDialog
|
ref="confirmDeleteContactDialogRef"
|
||||||
ref="confirmDeleteContactDialogRef"
|
:selected-contact="selectedContact"
|
||||||
:selected-contact="selectedContact"
|
/>
|
||||||
/>
|
</Policy>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import Button from 'dashboard/components-next/button/Button.vue';
|
|||||||
import Avatar from 'dashboard/components-next/avatar/Avatar.vue';
|
import Avatar from 'dashboard/components-next/avatar/Avatar.vue';
|
||||||
import Flag from 'dashboard/components-next/flag/Flag.vue';
|
import Flag from 'dashboard/components-next/flag/Flag.vue';
|
||||||
import ContactDeleteSection from 'dashboard/components-next/Contacts/ContactsCard/ContactDeleteSection.vue';
|
import ContactDeleteSection from 'dashboard/components-next/Contacts/ContactsCard/ContactDeleteSection.vue';
|
||||||
|
import Checkbox from 'dashboard/components-next/checkbox/Checkbox.vue';
|
||||||
import countries from 'shared/constants/countries';
|
import countries from 'shared/constants/countries';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
@@ -20,9 +21,17 @@ const props = defineProps({
|
|||||||
availabilityStatus: { type: String, default: null },
|
availabilityStatus: { type: String, default: null },
|
||||||
isExpanded: { type: Boolean, default: false },
|
isExpanded: { type: Boolean, default: false },
|
||||||
isUpdating: { type: Boolean, default: false },
|
isUpdating: { type: Boolean, default: false },
|
||||||
|
selectable: { type: Boolean, default: false },
|
||||||
|
isSelected: { type: Boolean, default: false },
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['toggle', 'updateContact', 'showContact']);
|
const emit = defineEmits([
|
||||||
|
'toggle',
|
||||||
|
'updateContact',
|
||||||
|
'showContact',
|
||||||
|
'select',
|
||||||
|
'avatarHover',
|
||||||
|
]);
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
@@ -88,111 +97,148 @@ const onClickExpand = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onClickViewDetails = () => emit('showContact', props.id);
|
const onClickViewDetails = () => emit('showContact', props.id);
|
||||||
|
|
||||||
|
const toggleSelect = checked => {
|
||||||
|
emit('select', checked);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAvatarHover = isHovered => {
|
||||||
|
emit('avatarHover', isHovered);
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<CardLayout :key="id" layout="row">
|
<div class="relative">
|
||||||
<div class="flex items-center justify-start flex-1 gap-4">
|
<CardLayout
|
||||||
<Avatar
|
:key="id"
|
||||||
:name="name"
|
layout="row"
|
||||||
:src="thumbnail"
|
:class="{
|
||||||
:size="48"
|
'outline-n-weak !bg-n-slate-3 dark:!bg-n-solid-3': isSelected,
|
||||||
:status="availabilityStatus"
|
}"
|
||||||
hide-offline-status
|
>
|
||||||
rounded-full
|
<div class="flex items-center justify-start flex-1 gap-4">
|
||||||
/>
|
<div
|
||||||
<div class="flex flex-col gap-0.5 flex-1">
|
class="relative"
|
||||||
<div class="flex flex-wrap items-center gap-x-4 gap-y-1">
|
@mouseenter="handleAvatarHover(true)"
|
||||||
<span class="text-base font-medium truncate text-n-slate-12">
|
@mouseleave="handleAvatarHover(false)"
|
||||||
{{ name }}
|
>
|
||||||
</span>
|
<Avatar
|
||||||
<span class="inline-flex items-center gap-1">
|
:name="name"
|
||||||
<span
|
:src="thumbnail"
|
||||||
v-if="additionalAttributes?.companyName"
|
:size="48"
|
||||||
class="i-ph-building-light size-4 text-n-slate-10 mb-0.5"
|
:status="availabilityStatus"
|
||||||
/>
|
hide-offline-status
|
||||||
<span
|
rounded-full
|
||||||
v-if="additionalAttributes?.companyName"
|
|
||||||
class="text-sm truncate text-n-slate-11"
|
|
||||||
>
|
|
||||||
{{ additionalAttributes.companyName }}
|
|
||||||
</span>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="flex flex-wrap items-center justify-start gap-x-3 gap-y-1">
|
|
||||||
<div v-if="email" class="truncate max-w-72" :title="email">
|
|
||||||
<span class="text-sm text-n-slate-11">
|
|
||||||
{{ email }}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div v-if="email" class="w-px h-3 truncate bg-n-slate-6" />
|
|
||||||
<span v-if="phoneNumber" class="text-sm truncate text-n-slate-11">
|
|
||||||
{{ phoneNumber }}
|
|
||||||
</span>
|
|
||||||
<div v-if="phoneNumber" class="w-px h-3 truncate bg-n-slate-6" />
|
|
||||||
<span
|
|
||||||
v-if="countryDetails"
|
|
||||||
class="inline-flex items-center gap-2 text-sm truncate text-n-slate-11"
|
|
||||||
>
|
>
|
||||||
<Flag :country="countryDetails.countryCode" class="size-3.5" />
|
<template v-if="selectable" #overlay="{ size }">
|
||||||
{{ formattedLocation }}
|
<label
|
||||||
</span>
|
class="flex items-center justify-center rounded-full cursor-pointer absolute inset-0 z-10 backdrop-blur-[2px] border border-n-weak"
|
||||||
<div v-if="countryDetails" class="w-px h-3 truncate bg-n-slate-6" />
|
:style="{ width: `${size}px`, height: `${size}px` }"
|
||||||
<Button
|
@click.stop
|
||||||
:label="t('CONTACTS_LAYOUT.CARD.VIEW_DETAILS')"
|
>
|
||||||
variant="link"
|
<Checkbox
|
||||||
size="xs"
|
:model-value="isSelected"
|
||||||
@click="onClickViewDetails"
|
@change="event => toggleSelect(event.target.checked)"
|
||||||
/>
|
/>
|
||||||
|
</label>
|
||||||
|
</template>
|
||||||
|
</Avatar>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="flex flex-col gap-0.5 flex-1">
|
||||||
</div>
|
<div class="flex flex-wrap items-center gap-x-4 gap-y-1">
|
||||||
|
<span class="text-base font-medium truncate text-n-slate-12">
|
||||||
<Button
|
{{ name }}
|
||||||
icon="i-lucide-chevron-down"
|
</span>
|
||||||
variant="ghost"
|
<span class="inline-flex items-center gap-1">
|
||||||
color="slate"
|
<span
|
||||||
size="xs"
|
v-if="additionalAttributes?.companyName"
|
||||||
:class="{ 'rotate-180': isExpanded }"
|
class="i-ph-building-light size-4 text-n-slate-10 mb-0.5"
|
||||||
@click="onClickExpand"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<template #after>
|
|
||||||
<div
|
|
||||||
class="transition-all duration-500 ease-in-out grid overflow-hidden"
|
|
||||||
:class="
|
|
||||||
isExpanded
|
|
||||||
? 'grid-rows-[1fr] opacity-100'
|
|
||||||
: 'grid-rows-[0fr] opacity-0'
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<div class="overflow-hidden">
|
|
||||||
<div class="flex flex-col gap-6 p-6 border-t border-n-strong">
|
|
||||||
<ContactsForm
|
|
||||||
ref="contactsFormRef"
|
|
||||||
:contact-data="contactData"
|
|
||||||
@update="handleFormUpdate"
|
|
||||||
/>
|
|
||||||
<div>
|
|
||||||
<Button
|
|
||||||
:label="
|
|
||||||
t('CONTACTS_LAYOUT.CARD.EDIT_DETAILS_FORM.UPDATE_BUTTON')
|
|
||||||
"
|
|
||||||
size="sm"
|
|
||||||
:is-loading="isUpdating"
|
|
||||||
:disabled="isUpdating || isFormInvalid"
|
|
||||||
@click="handleUpdateContact"
|
|
||||||
/>
|
/>
|
||||||
|
<span
|
||||||
|
v-if="additionalAttributes?.companyName"
|
||||||
|
class="text-sm truncate text-n-slate-11"
|
||||||
|
>
|
||||||
|
{{ additionalAttributes.companyName }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="flex flex-wrap items-center justify-start gap-x-3 gap-y-1"
|
||||||
|
>
|
||||||
|
<div v-if="email" class="truncate max-w-72" :title="email">
|
||||||
|
<span class="text-sm text-n-slate-11">
|
||||||
|
{{ email }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-if="email" class="w-px h-3 truncate bg-n-slate-6" />
|
||||||
|
<span v-if="phoneNumber" class="text-sm truncate text-n-slate-11">
|
||||||
|
{{ phoneNumber }}
|
||||||
|
</span>
|
||||||
|
<div v-if="phoneNumber" class="w-px h-3 truncate bg-n-slate-6" />
|
||||||
|
<span
|
||||||
|
v-if="countryDetails"
|
||||||
|
class="inline-flex items-center gap-2 text-sm truncate text-n-slate-11"
|
||||||
|
>
|
||||||
|
<Flag :country="countryDetails.countryCode" class="size-3.5" />
|
||||||
|
{{ formattedLocation }}
|
||||||
|
</span>
|
||||||
|
<div v-if="countryDetails" class="w-px h-3 truncate bg-n-slate-6" />
|
||||||
|
<Button
|
||||||
|
:label="t('CONTACTS_LAYOUT.CARD.VIEW_DETAILS')"
|
||||||
|
variant="link"
|
||||||
|
size="xs"
|
||||||
|
@click="onClickViewDetails"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<ContactDeleteSection
|
|
||||||
:selected-contact="{
|
|
||||||
id: props.id,
|
|
||||||
name: props.name,
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
|
||||||
</CardLayout>
|
<Button
|
||||||
|
icon="i-lucide-chevron-down"
|
||||||
|
variant="ghost"
|
||||||
|
color="slate"
|
||||||
|
size="xs"
|
||||||
|
:class="{ 'rotate-180': isExpanded }"
|
||||||
|
@click="onClickExpand"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<template #after>
|
||||||
|
<div
|
||||||
|
class="transition-all duration-500 ease-in-out grid overflow-hidden"
|
||||||
|
:class="
|
||||||
|
isExpanded
|
||||||
|
? 'grid-rows-[1fr] opacity-100'
|
||||||
|
: 'grid-rows-[0fr] opacity-0'
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<div class="overflow-hidden">
|
||||||
|
<div class="flex flex-col gap-6 p-6 border-t border-n-strong">
|
||||||
|
<ContactsForm
|
||||||
|
ref="contactsFormRef"
|
||||||
|
:contact-data="contactData"
|
||||||
|
@update="handleFormUpdate"
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
|
<Button
|
||||||
|
:label="
|
||||||
|
t('CONTACTS_LAYOUT.CARD.EDIT_DETAILS_FORM.UPDATE_BUTTON')
|
||||||
|
"
|
||||||
|
size="sm"
|
||||||
|
:is-loading="isUpdating"
|
||||||
|
:disabled="isUpdating || isFormInvalid"
|
||||||
|
@click="handleUpdateContact"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ContactDeleteSection
|
||||||
|
:selected-contact="{
|
||||||
|
id: props.id,
|
||||||
|
name: props.name,
|
||||||
|
}"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</CardLayout>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import Button from 'dashboard/components-next/button/Button.vue';
|
|||||||
import ContactLabels from 'dashboard/components-next/Contacts/ContactLabels/ContactLabels.vue';
|
import ContactLabels from 'dashboard/components-next/Contacts/ContactLabels/ContactLabels.vue';
|
||||||
import ContactsForm from 'dashboard/components-next/Contacts/ContactsForm/ContactsForm.vue';
|
import ContactsForm from 'dashboard/components-next/Contacts/ContactsForm/ContactsForm.vue';
|
||||||
import ConfirmContactDeleteDialog from 'dashboard/components-next/Contacts/ContactsForm/ConfirmContactDeleteDialog.vue';
|
import ConfirmContactDeleteDialog from 'dashboard/components-next/Contacts/ContactsForm/ConfirmContactDeleteDialog.vue';
|
||||||
|
import Policy from 'dashboard/components/policy.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
selectedContact: {
|
selectedContact: {
|
||||||
@@ -174,27 +175,29 @@ const handleAvatarDelete = async () => {
|
|||||||
@click="updateContact"
|
@click="updateContact"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<Policy :permissions="['administrator']">
|
||||||
class="flex flex-col items-start w-full gap-4 pt-6 border-t border-n-strong"
|
<div
|
||||||
>
|
class="flex flex-col items-start w-full gap-4 pt-6 border-t border-n-strong"
|
||||||
<div class="flex flex-col gap-2">
|
>
|
||||||
<h6 class="text-base font-medium text-n-slate-12">
|
<div class="flex flex-col gap-2">
|
||||||
{{ t('CONTACTS_LAYOUT.DETAILS.DELETE_CONTACT') }}
|
<h6 class="text-base font-medium text-n-slate-12">
|
||||||
</h6>
|
{{ t('CONTACTS_LAYOUT.DETAILS.DELETE_CONTACT') }}
|
||||||
<span class="text-sm text-n-slate-11">
|
</h6>
|
||||||
{{ t('CONTACTS_LAYOUT.DETAILS.DELETE_CONTACT_DESCRIPTION') }}
|
<span class="text-sm text-n-slate-11">
|
||||||
</span>
|
{{ t('CONTACTS_LAYOUT.DETAILS.DELETE_CONTACT_DESCRIPTION') }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<Button
|
||||||
|
:label="t('CONTACTS_LAYOUT.DETAILS.DELETE_CONTACT')"
|
||||||
|
color="ruby"
|
||||||
|
@click="openConfirmDeleteContactDialog"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<Button
|
<ConfirmContactDeleteDialog
|
||||||
:label="t('CONTACTS_LAYOUT.DETAILS.DELETE_CONTACT')"
|
ref="confirmDeleteContactDialogRef"
|
||||||
color="ruby"
|
:selected-contact="selectedContact"
|
||||||
@click="openConfirmDeleteContactDialog"
|
@go-to-contacts-list="emit('goToContactsList')"
|
||||||
/>
|
/>
|
||||||
</div>
|
</Policy>
|
||||||
<ConfirmContactDeleteDialog
|
|
||||||
ref="confirmDeleteContactDialogRef"
|
|
||||||
:selected-contact="selectedContact"
|
|
||||||
@go-to-contacts-list="emit('goToContactsList')"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -10,7 +10,15 @@ import {
|
|||||||
} from 'shared/helpers/CustomErrors';
|
} from 'shared/helpers/CustomErrors';
|
||||||
import ContactsCard from 'dashboard/components-next/Contacts/ContactsCard/ContactsCard.vue';
|
import ContactsCard from 'dashboard/components-next/Contacts/ContactsCard/ContactsCard.vue';
|
||||||
|
|
||||||
defineProps({ contacts: { type: Array, required: true } });
|
const props = defineProps({
|
||||||
|
contacts: { type: Array, required: true },
|
||||||
|
selectedContactIds: {
|
||||||
|
type: Array,
|
||||||
|
default: () => [],
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['toggleContact']);
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
@@ -20,6 +28,9 @@ const route = useRoute();
|
|||||||
const uiFlags = useMapGetter('contacts/getUIFlags');
|
const uiFlags = useMapGetter('contacts/getUIFlags');
|
||||||
const isUpdating = computed(() => uiFlags.value.isUpdating);
|
const isUpdating = computed(() => uiFlags.value.isUpdating);
|
||||||
const expandedCardId = ref(null);
|
const expandedCardId = ref(null);
|
||||||
|
const hoveredAvatarId = ref(null);
|
||||||
|
|
||||||
|
const selectedIdsSet = computed(() => new Set(props.selectedContactIds || []));
|
||||||
|
|
||||||
const updateContact = async updatedData => {
|
const updateContact = async updatedData => {
|
||||||
try {
|
try {
|
||||||
@@ -58,25 +69,43 @@ const onClickViewDetails = async id => {
|
|||||||
const toggleExpanded = id => {
|
const toggleExpanded = id => {
|
||||||
expandedCardId.value = expandedCardId.value === id ? null : id;
|
expandedCardId.value = expandedCardId.value === id ? null : id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const isSelected = id => selectedIdsSet.value.has(id);
|
||||||
|
|
||||||
|
const shouldShowSelection = id => {
|
||||||
|
return hoveredAvatarId.value === id || isSelected(id);
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSelect = (id, value) => {
|
||||||
|
emit('toggleContact', { id, value });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleAvatarHover = (id, isHovered) => {
|
||||||
|
hoveredAvatarId.value = isHovered ? id : null;
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="flex flex-col gap-4 px-6 pt-4 pb-6">
|
<div class="flex flex-col gap-4">
|
||||||
<ContactsCard
|
<div v-for="contact in contacts" :key="contact.id" class="relative">
|
||||||
v-for="contact in contacts"
|
<ContactsCard
|
||||||
:id="contact.id"
|
:id="contact.id"
|
||||||
:key="contact.id"
|
:name="contact.name"
|
||||||
:name="contact.name"
|
:email="contact.email"
|
||||||
:email="contact.email"
|
:thumbnail="contact.thumbnail"
|
||||||
:thumbnail="contact.thumbnail"
|
:phone-number="contact.phoneNumber"
|
||||||
:phone-number="contact.phoneNumber"
|
:additional-attributes="contact.additionalAttributes"
|
||||||
:additional-attributes="contact.additionalAttributes"
|
:availability-status="contact.availabilityStatus"
|
||||||
:availability-status="contact.availabilityStatus"
|
:is-expanded="expandedCardId === contact.id"
|
||||||
:is-expanded="expandedCardId === contact.id"
|
:is-updating="isUpdating"
|
||||||
:is-updating="isUpdating"
|
:selectable="shouldShowSelection(contact.id)"
|
||||||
@toggle="toggleExpanded(contact.id)"
|
:is-selected="isSelected(contact.id)"
|
||||||
@update-contact="updateContact"
|
@toggle="toggleExpanded(contact.id)"
|
||||||
@show-contact="onClickViewDetails"
|
@update-contact="updateContact"
|
||||||
/>
|
@show-contact="onClickViewDetails"
|
||||||
|
@select="value => handleSelect(contact.id, value)"
|
||||||
|
@avatar-hover="value => handleAvatarHover(contact.id, value)"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ defineProps({
|
|||||||
type: Array,
|
type: Array,
|
||||||
default: () => [],
|
default: () => [],
|
||||||
},
|
},
|
||||||
|
showBackdrop: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -25,14 +29,24 @@ defineProps({
|
|||||||
class="relative w-full max-w-[60rem] mx-auto overflow-hidden h-full max-h-[28rem]"
|
class="relative w-full max-w-[60rem] mx-auto overflow-hidden h-full max-h-[28rem]"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
|
v-if="showBackdrop"
|
||||||
class="w-full h-full space-y-4 overflow-y-hidden opacity-50 pointer-events-none"
|
class="w-full h-full space-y-4 overflow-y-hidden opacity-50 pointer-events-none"
|
||||||
>
|
>
|
||||||
<slot name="empty-state-item" />
|
<slot name="empty-state-item" />
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="absolute inset-x-0 bottom-0 flex flex-col items-center justify-end w-full h-full pb-20 bg-gradient-to-t from-n-background from-25% dark:from-n-background to-transparent"
|
class="flex flex-col items-center justify-end w-full h-full pb-20"
|
||||||
|
:class="{
|
||||||
|
'absolute inset-x-0 bottom-0 bg-gradient-to-t from-n-background from-25% dark:from-n-background to-transparent':
|
||||||
|
showBackdrop,
|
||||||
|
}"
|
||||||
>
|
>
|
||||||
<div class="flex flex-col items-center justify-center gap-6">
|
<div
|
||||||
|
class="flex flex-col items-center justify-center gap-6"
|
||||||
|
:class="{
|
||||||
|
'mt-48': !showBackdrop,
|
||||||
|
}"
|
||||||
|
>
|
||||||
<div class="flex flex-col items-center justify-center gap-3">
|
<div class="flex flex-col items-center justify-center gap-3">
|
||||||
<h2
|
<h2
|
||||||
class="text-3xl font-medium text-center text-n-slate-12 font-interDisplay"
|
class="text-3xl font-medium text-center text-n-slate-12 font-interDisplay"
|
||||||
@@ -40,6 +54,7 @@ defineProps({
|
|||||||
{{ title }}
|
{{ title }}
|
||||||
</h2>
|
</h2>
|
||||||
<p
|
<p
|
||||||
|
v-if="subtitle"
|
||||||
class="max-w-xl text-base text-center text-n-slate-11 font-interDisplay tracking-[0.3px]"
|
class="max-w-xl text-base text-center text-n-slate-11 font-interDisplay tracking-[0.3px]"
|
||||||
>
|
>
|
||||||
{{ subtitle }}
|
{{ subtitle }}
|
||||||
|
|||||||
@@ -114,6 +114,7 @@ const handlePageChange = event => {
|
|||||||
<slot name="action" />
|
<slot name="action" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<slot name="subHeader" />
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
<main class="flex-1 px-6 overflow-y-auto">
|
<main class="flex-1 px-6 overflow-y-auto">
|
||||||
|
|||||||
@@ -64,20 +64,23 @@ const bulkCheckboxState = computed({
|
|||||||
class="flex items-center gap-3 py-1 ltr:pl-3 rtl:pr-3 ltr:pr-4 rtl:pl-4 rounded-lg bg-n-solid-2 outline outline-1 outline-n-container shadow"
|
class="flex items-center gap-3 py-1 ltr:pl-3 rtl:pr-3 ltr:pr-4 rtl:pl-4 rounded-lg bg-n-solid-2 outline outline-1 outline-n-container shadow"
|
||||||
>
|
>
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<div class="flex items-center gap-1.5">
|
<div class="flex items-center gap-1.5 min-w-0">
|
||||||
<Checkbox
|
<Checkbox
|
||||||
v-model="bulkCheckboxState"
|
v-model="bulkCheckboxState"
|
||||||
:indeterminate="isIndeterminate"
|
:indeterminate="isIndeterminate"
|
||||||
/>
|
/>
|
||||||
<span class="text-sm font-medium text-n-slate-12 tabular-nums">
|
<span
|
||||||
|
class="text-sm font-medium truncate text-n-slate-12 tabular-nums"
|
||||||
|
>
|
||||||
{{ selectAllLabel }}
|
{{ selectAllLabel }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<span class="text-sm text-n-slate-10 tabular-nums">
|
<span class="text-sm text-n-slate-10 truncate tabular-nums">
|
||||||
{{ selectedCountLabel }}
|
{{ selectedCountLabel }}
|
||||||
</span>
|
</span>
|
||||||
|
<div class="h-4 w-px bg-n-strong" />
|
||||||
|
<slot name="secondary-actions" />
|
||||||
</div>
|
</div>
|
||||||
<div class="h-4 w-px bg-n-strong" />
|
|
||||||
<div class="flex items-center gap-3">
|
<div class="flex items-center gap-3">
|
||||||
<slot name="actions" :selected-count="selectedCount">
|
<slot name="actions" :selected-count="selectedCount">
|
||||||
<Button
|
<Button
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import DropdownMenu from 'dashboard/components-next/dropdown-menu/DropdownMenu.v
|
|||||||
import Button from 'dashboard/components-next/button/Button.vue';
|
import Button from 'dashboard/components-next/button/Button.vue';
|
||||||
import Checkbox from 'dashboard/components-next/checkbox/Checkbox.vue';
|
import Checkbox from 'dashboard/components-next/checkbox/Checkbox.vue';
|
||||||
import Policy from 'dashboard/components/policy.vue';
|
import Policy from 'dashboard/components/policy.vue';
|
||||||
|
import Icon from 'dashboard/components-next/icon/Icon.vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
@@ -59,6 +60,10 @@ const props = defineProps({
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true,
|
default: true,
|
||||||
},
|
},
|
||||||
|
showActions: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
const emit = defineEmits(['action', 'navigate', 'select', 'hover']);
|
const emit = defineEmits(['action', 'navigate', 'select', 'hover']);
|
||||||
@@ -159,73 +164,116 @@ const handleDocumentableClick = () => {
|
|||||||
<span class="text-n-slate-11 text-sm line-clamp-5">
|
<span class="text-n-slate-11 text-sm line-clamp-5">
|
||||||
{{ answer }}
|
{{ answer }}
|
||||||
</span>
|
</span>
|
||||||
<div v-if="!compact" class="items-center justify-between hidden lg:flex">
|
<div
|
||||||
<div class="inline-flex items-center">
|
v-if="!compact"
|
||||||
<span
|
class="flex items-start justify-between flex-col-reverse md:flex-row gap-3"
|
||||||
class="text-sm shrink-0 truncate text-n-slate-11 inline-flex items-center gap-1"
|
>
|
||||||
>
|
<Policy v-if="showActions" :permissions="['administrator']">
|
||||||
<i class="i-woot-captain" />
|
<div class="flex items-center gap-2 sm:gap-5 w-full">
|
||||||
{{ assistant?.name || '' }}
|
<Button
|
||||||
</span>
|
v-if="status === 'pending'"
|
||||||
<div
|
:label="$t('CAPTAIN.RESPONSES.OPTIONS.APPROVE')"
|
||||||
v-if="documentable"
|
icon="i-lucide-circle-check-big"
|
||||||
class="shrink-0 text-sm text-n-slate-11 inline-flex line-clamp-1 gap-1 ml-3"
|
sm
|
||||||
>
|
link
|
||||||
|
class="hover:!no-underline"
|
||||||
|
@click="
|
||||||
|
handleAssistantAction({ action: 'approve', value: 'approve' })
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
:label="$t('CAPTAIN.RESPONSES.OPTIONS.EDIT_RESPONSE')"
|
||||||
|
icon="i-lucide-pencil-line"
|
||||||
|
sm
|
||||||
|
slate
|
||||||
|
link
|
||||||
|
class="hover:!no-underline"
|
||||||
|
@click="
|
||||||
|
handleAssistantAction({
|
||||||
|
action: 'edit',
|
||||||
|
value: 'edit',
|
||||||
|
})
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
:label="$t('CAPTAIN.RESPONSES.OPTIONS.DELETE_RESPONSE')"
|
||||||
|
icon="i-lucide-trash"
|
||||||
|
sm
|
||||||
|
ruby
|
||||||
|
link
|
||||||
|
class="hover:!no-underline"
|
||||||
|
@click="
|
||||||
|
handleAssistantAction({ action: 'delete', value: 'delete' })
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Policy>
|
||||||
|
<div
|
||||||
|
class="flex items-center gap-3"
|
||||||
|
:class="{ 'justify-between w-full': !showActions }"
|
||||||
|
>
|
||||||
|
<div class="inline-flex items-center gap-3 min-w-0">
|
||||||
<span
|
<span
|
||||||
v-if="documentable.type === 'Captain::Document'"
|
v-if="status === 'approved'"
|
||||||
class="inline-flex items-center gap-1 truncate over"
|
class="text-sm shrink-0 truncate text-n-slate-11 inline-flex items-center gap-1"
|
||||||
>
|
>
|
||||||
<i class="i-ph-files-light text-base" />
|
<Icon icon="i-woot-captain" class="size-3.5" />
|
||||||
<span class="max-w-96 truncate" :title="documentable.name">
|
{{ assistant?.name || '' }}
|
||||||
|
</span>
|
||||||
|
<div
|
||||||
|
v-if="documentable"
|
||||||
|
class="text-sm text-n-slate-11 grid grid-cols-[auto_1fr] items-center gap-1 min-w-0"
|
||||||
|
>
|
||||||
|
<Icon
|
||||||
|
v-if="documentable.type === 'Captain::Document'"
|
||||||
|
icon="i-ph-files-light"
|
||||||
|
class="size-3.5"
|
||||||
|
/>
|
||||||
|
<Icon
|
||||||
|
v-else-if="documentable.type === 'User'"
|
||||||
|
icon="i-ph-user-circle-plus"
|
||||||
|
class="size-3.5"
|
||||||
|
/>
|
||||||
|
<Icon
|
||||||
|
v-else-if="documentable.type === 'Conversation'"
|
||||||
|
icon="i-ph-chat-circle-dots"
|
||||||
|
class="size-3.5"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
v-if="documentable.type === 'Captain::Document'"
|
||||||
|
class="truncate"
|
||||||
|
:title="documentable.name"
|
||||||
|
>
|
||||||
{{ documentable.name }}
|
{{ documentable.name }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
v-if="documentable.type === 'User'"
|
|
||||||
class="inline-flex items-center gap-1"
|
|
||||||
>
|
|
||||||
<i class="i-ph-user-circle-plus text-base" />
|
|
||||||
<span
|
<span
|
||||||
class="max-w-96 truncate"
|
v-else-if="documentable.type === 'User'"
|
||||||
|
class="truncate"
|
||||||
:title="documentable.available_name"
|
:title="documentable.available_name"
|
||||||
>
|
>
|
||||||
{{ documentable.available_name }}
|
{{ documentable.available_name }}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
<span
|
||||||
<span
|
v-else-if="documentable.type === 'Conversation'"
|
||||||
v-else-if="documentable.type === 'Conversation'"
|
class="hover:underline truncate cursor-pointer"
|
||||||
class="inline-flex items-center gap-1 group cursor-pointer"
|
role="button"
|
||||||
role="button"
|
@click="handleDocumentableClick"
|
||||||
@click="handleDocumentableClick"
|
>
|
||||||
>
|
|
||||||
<i class="i-ph-chat-circle-dots text-base" />
|
|
||||||
<span class="group-hover:underline">
|
|
||||||
{{
|
{{
|
||||||
t(`CAPTAIN.RESPONSES.DOCUMENTABLE.CONVERSATION`, {
|
t(`CAPTAIN.RESPONSES.DOCUMENTABLE.CONVERSATION`, {
|
||||||
id: documentable.display_id,
|
id: documentable.display_id,
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
</span>
|
</span>
|
||||||
</span>
|
</div>
|
||||||
<span v-else />
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="status !== 'approved'"
|
class="shrink-0 text-sm text-n-slate-11 line-clamp-1 inline-flex items-center gap-1"
|
||||||
class="shrink-0 text-sm text-n-slate-11 line-clamp-1 inline-flex items-center gap-1 ml-3"
|
|
||||||
>
|
>
|
||||||
<i
|
<Icon icon="i-ph-calendar-dot" class="size-3.5" />
|
||||||
class="i-ph-stack text-base"
|
{{ timestamp }}
|
||||||
:title="t('CAPTAIN.RESPONSES.STATUS.TITLE')"
|
|
||||||
/>
|
|
||||||
{{ t(`CAPTAIN.RESPONSES.STATUS.${status.toUpperCase()}`) }}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
|
||||||
class="shrink-0 text-sm text-n-slate-11 line-clamp-1 inline-flex items-center gap-1 ml-3"
|
|
||||||
>
|
|
||||||
<i class="i-ph-calendar-dot" />
|
|
||||||
{{ timestamp }}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</CardLayout>
|
</CardLayout>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
+47
-9
@@ -6,16 +6,39 @@ import ResponseCard from 'dashboard/components-next/captain/assistant/ResponseCa
|
|||||||
import FeatureSpotlight from 'dashboard/components-next/feature-spotlight/FeatureSpotlight.vue';
|
import FeatureSpotlight from 'dashboard/components-next/feature-spotlight/FeatureSpotlight.vue';
|
||||||
import { responsesList } from 'dashboard/components-next/captain/pageComponents/emptyStates/captainEmptyStateContent.js';
|
import { responsesList } from 'dashboard/components-next/captain/pageComponents/emptyStates/captainEmptyStateContent.js';
|
||||||
|
|
||||||
const emit = defineEmits(['click']);
|
import { computed } from 'vue';
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
variant: {
|
||||||
|
type: String,
|
||||||
|
default: 'approved',
|
||||||
|
validator: value => ['approved', 'pending'].includes(value),
|
||||||
|
},
|
||||||
|
hasActiveFilters: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const emit = defineEmits(['click', 'clearFilters']);
|
||||||
|
|
||||||
|
const isApproved = computed(() => props.variant === 'approved');
|
||||||
|
const isPending = computed(() => props.variant === 'pending');
|
||||||
|
|
||||||
const { isOnChatwootCloud } = useAccount();
|
const { isOnChatwootCloud } = useAccount();
|
||||||
|
|
||||||
const onClick = () => {
|
const onClick = () => {
|
||||||
emit('click');
|
emit('click');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const onClearFilters = () => {
|
||||||
|
emit('clearFilters');
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FeatureSpotlight
|
<FeatureSpotlight
|
||||||
|
v-if="isApproved"
|
||||||
:title="$t('CAPTAIN.RESPONSES.EMPTY_STATE.FEATURE_SPOTLIGHT.TITLE')"
|
:title="$t('CAPTAIN.RESPONSES.EMPTY_STATE.FEATURE_SPOTLIGHT.TITLE')"
|
||||||
:note="$t('CAPTAIN.RESPONSES.EMPTY_STATE.FEATURE_SPOTLIGHT.NOTE')"
|
:note="$t('CAPTAIN.RESPONSES.EMPTY_STATE.FEATURE_SPOTLIGHT.NOTE')"
|
||||||
fallback-thumbnail="/assets/images/dashboard/captain/faqs-light.svg"
|
fallback-thumbnail="/assets/images/dashboard/captain/faqs-light.svg"
|
||||||
@@ -25,11 +48,16 @@ const onClick = () => {
|
|||||||
class="mb-8"
|
class="mb-8"
|
||||||
/>
|
/>
|
||||||
<EmptyStateLayout
|
<EmptyStateLayout
|
||||||
:title="$t('CAPTAIN.RESPONSES.EMPTY_STATE.TITLE')"
|
:title="
|
||||||
:subtitle="$t('CAPTAIN.RESPONSES.EMPTY_STATE.SUBTITLE')"
|
isPending
|
||||||
|
? $t('CAPTAIN.RESPONSES.EMPTY_STATE.NO_PENDING_TITLE')
|
||||||
|
: $t('CAPTAIN.RESPONSES.EMPTY_STATE.TITLE')
|
||||||
|
"
|
||||||
|
:subtitle="isApproved ? $t('CAPTAIN.RESPONSES.EMPTY_STATE.SUBTITLE') : ''"
|
||||||
:action-perms="['administrator']"
|
:action-perms="['administrator']"
|
||||||
|
:show-backdrop="isApproved"
|
||||||
>
|
>
|
||||||
<template #empty-state-item>
|
<template v-if="isApproved" #empty-state-item>
|
||||||
<div class="grid grid-cols-1 gap-4 p-px overflow-hidden">
|
<div class="grid grid-cols-1 gap-4 p-px overflow-hidden">
|
||||||
<ResponseCard
|
<ResponseCard
|
||||||
v-for="(response, index) in responsesList.slice(0, 5)"
|
v-for="(response, index) in responsesList.slice(0, 5)"
|
||||||
@@ -45,11 +73,21 @@ const onClick = () => {
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<Button
|
<div class="flex flex-col items-center gap-3">
|
||||||
:label="$t('CAPTAIN.RESPONSES.ADD_NEW')"
|
<Button
|
||||||
icon="i-lucide-plus"
|
v-if="isApproved"
|
||||||
@click="onClick"
|
:label="$t('CAPTAIN.RESPONSES.ADD_NEW')"
|
||||||
/>
|
icon="i-lucide-plus"
|
||||||
|
@click="onClick"
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
v-else-if="isPending && hasActiveFilters"
|
||||||
|
:label="$t('CAPTAIN.RESPONSES.EMPTY_STATE.CLEAR_SEARCH')"
|
||||||
|
variant="link"
|
||||||
|
size="sm"
|
||||||
|
@click="onClearFilters"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</EmptyStateLayout>
|
</EmptyStateLayout>
|
||||||
</template>
|
</template>
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
<script setup>
|
||||||
|
import Button from 'dashboard/components-next/button/Button.vue';
|
||||||
|
|
||||||
|
defineProps({
|
||||||
|
message: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="text-n-slate-12 max-w-80 flex flex-col gap-2.5">
|
||||||
|
<div class="p-3 bg-n-alpha-2 rounded-xl">
|
||||||
|
<span
|
||||||
|
v-dompurify-html="message.content"
|
||||||
|
class="prose prose-bubble font-medium text-sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="flex gap-2">
|
||||||
|
<Button label="Call us" slate class="!text-n-blue-text w-full" />
|
||||||
|
<Button
|
||||||
|
label="Visit our website"
|
||||||
|
slate
|
||||||
|
class="!text-n-blue-text w-full"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<script setup>
|
||||||
|
import Button from 'dashboard/components-next/button/Button.vue';
|
||||||
|
defineProps({
|
||||||
|
message: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="bg-n-alpha-2 divide-y divide-n-strong text-n-slate-12 rounded-xl max-w-80"
|
||||||
|
>
|
||||||
|
<div class="px-3 py-2.5">
|
||||||
|
<img :src="message.image_url" class="max-h-44 rounded-lg w-full" />
|
||||||
|
<div class="pt-2.5 flex flex-col gap-2">
|
||||||
|
<h6 class="font-semibold">{{ message.title }}</h6>
|
||||||
|
<span
|
||||||
|
v-dompurify-html="message.content"
|
||||||
|
class="prose prose-bubble text-sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="p-3 flex items-center justify-center">
|
||||||
|
<Button label="Call us to order" link class="hover:!no-underline" />
|
||||||
|
</div>
|
||||||
|
<div class="p-3 flex items-center justify-center">
|
||||||
|
<Button label="Visit our store" link class="hover:!no-underline" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
<script setup>
|
||||||
|
import Button from 'dashboard/components-next/button/Button.vue';
|
||||||
|
defineProps({
|
||||||
|
message: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="bg-n-alpha-2 divide-y divide-n-strong text-n-slate-12 rounded-xl max-w-80"
|
||||||
|
>
|
||||||
|
<div class="p-3">
|
||||||
|
<span
|
||||||
|
v-dompurify-html="message.content"
|
||||||
|
class="prose prose-bubble font-medium text-sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="p-3 flex items-center justify-center">
|
||||||
|
<Button label="See options" link class="hover:!no-underline" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<script setup>
|
||||||
|
defineProps({
|
||||||
|
message: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="bg-n-alpha-2 text-n-slate-12 rounded-xl flex flex-col gap-2.5 p-3 max-w-80"
|
||||||
|
>
|
||||||
|
<img :src="message.image_url" class="max-h-44 rounded-lg w-full" />
|
||||||
|
<span
|
||||||
|
v-dompurify-html="message.content"
|
||||||
|
class="prose prose-bubble font-medium text-sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
<script setup>
|
||||||
|
import Button from 'dashboard/components-next/button/Button.vue';
|
||||||
|
defineProps({
|
||||||
|
message: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="bg-n-alpha-2 divide-y divide-n-strong text-n-slate-12 rounded-xl max-w-80"
|
||||||
|
>
|
||||||
|
<div class="p-3">
|
||||||
|
<span
|
||||||
|
v-dompurify-html="message.content"
|
||||||
|
class="prose prose-bubble font-medium text-sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="p-3 flex items-center justify-center">
|
||||||
|
<Button label="No, that will be all" link class="hover:!no-underline">
|
||||||
|
<template #icon>
|
||||||
|
<svg
|
||||||
|
width="15"
|
||||||
|
height="15"
|
||||||
|
viewBox="0 0 15 15"
|
||||||
|
fill="none"
|
||||||
|
class="stroke-n-blue-text"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M.667 6.654 5.315.667v3.326c7.968 0 8.878 6.46 8.656 10.007l-.005-.027c-.334-1.79-.474-4.658-8.65-4.658v3.327z"
|
||||||
|
stroke-width="1.333"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div class="p-3 flex items-center justify-center">
|
||||||
|
<Button
|
||||||
|
label="I want to talk to an agents"
|
||||||
|
link
|
||||||
|
class="hover:!no-underline"
|
||||||
|
>
|
||||||
|
<template #icon>
|
||||||
|
<svg
|
||||||
|
width="15"
|
||||||
|
height="15"
|
||||||
|
viewBox="0 0 15 15"
|
||||||
|
fill="none"
|
||||||
|
class="stroke-n-blue-text"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
d="M.667 6.654 5.315.667v3.326c7.968 0 8.878 6.46 8.656 10.007l-.005-.027c-.334-1.79-.474-4.658-8.65-4.658v3.327z"
|
||||||
|
stroke-width="1.333"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<script setup>
|
||||||
|
defineProps({
|
||||||
|
message: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="bg-n-alpha-2 text-n-slate-12 rounded-xl p-3 max-w-80">
|
||||||
|
<span v-dompurify-html="message.content" class="prose prose-bubble" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
@@ -47,6 +47,7 @@ const isReel = computed(() => {
|
|||||||
'max-w-48': isReel,
|
'max-w-48': isReel,
|
||||||
'max-w-full': !isReel,
|
'max-w-full': !isReel,
|
||||||
}"
|
}"
|
||||||
|
@click.stop
|
||||||
@error="handleError"
|
@error="handleError"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
<script setup>
|
||||||
|
import CallToAction from '../../bubbles/Template/CallToAction.vue';
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
content:
|
||||||
|
'We have super cool products going live! Pre-order and customize products. Contact us for more details',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Story
|
||||||
|
title="Components/Message Bubbles/Template/CallToAction"
|
||||||
|
:layout="{ type: 'grid', width: '600px' }"
|
||||||
|
>
|
||||||
|
<Variant title="Call To Action">
|
||||||
|
<div class="p-4 bg-n-background rounded-lg w-full min-w-4xl">
|
||||||
|
<CallToAction :message="message" />
|
||||||
|
</div>
|
||||||
|
</Variant>
|
||||||
|
</Story>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<script setup>
|
||||||
|
import Card from '../../bubbles/Template/Card.vue';
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
title: 'Two in one cake (1 pound)',
|
||||||
|
content: 'Customize your order for special occasions',
|
||||||
|
image_url:
|
||||||
|
'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=500&h=300&fit=crop',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Story
|
||||||
|
title="Components/Message Bubbles/Template/Card"
|
||||||
|
:layout="{ type: 'grid', width: '600px' }"
|
||||||
|
>
|
||||||
|
<Variant title="Card">
|
||||||
|
<div class="p-4 bg-n-background rounded-lg w-full min-w-4xl">
|
||||||
|
<Card :message="message" />
|
||||||
|
</div>
|
||||||
|
</Variant>
|
||||||
|
</Story>
|
||||||
|
</template>
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
<script setup>
|
||||||
|
import ListPicker from '../../bubbles/Template/ListPicker.vue';
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
content: `Hey there! Thanks for reaching out to us. Could you let us know
|
||||||
|
what you need to help us better assist you? `,
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Story
|
||||||
|
title="Components/Message Bubbles/Template/ListPicker"
|
||||||
|
:layout="{ type: 'grid', width: '600px' }"
|
||||||
|
>
|
||||||
|
<Variant title="ListPicker">
|
||||||
|
<div class="p-4 bg-n-background rounded-lg w-full min-w-4xl">
|
||||||
|
<ListPicker :message="message" />
|
||||||
|
</div>
|
||||||
|
</Variant>
|
||||||
|
</Story>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<script setup>
|
||||||
|
import Media from '../../bubbles/Template/Media.vue';
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
content:
|
||||||
|
'Welcome to our Diwali sale! Get flat 50% off on select items. Hurry now!',
|
||||||
|
image_url:
|
||||||
|
'https://images.unsplash.com/photo-1506905925346-21bda4d32df4?w=500&h=300&fit=crop',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Story
|
||||||
|
title="Components/Message Bubbles/Template/Media"
|
||||||
|
:layout="{ type: 'grid', width: '600px' }"
|
||||||
|
>
|
||||||
|
<Variant title="Image Media">
|
||||||
|
<div class="p-4 bg-n-background rounded-lg w-full min-w-4xl">
|
||||||
|
<Media :message="message" />
|
||||||
|
</div>
|
||||||
|
</Variant>
|
||||||
|
</Story>
|
||||||
|
</template>
|
||||||
+21
@@ -0,0 +1,21 @@
|
|||||||
|
<script setup>
|
||||||
|
import QuickReply from '../../bubbles/Template/QuickReply.vue';
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
content: `Hey there! Thanks for reaching out to us. Could you let us know
|
||||||
|
what you need to help us better assist you?`,
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Story
|
||||||
|
title="Components/Message Bubbles/Template/QuickReply"
|
||||||
|
:layout="{ type: 'grid', width: '600px' }"
|
||||||
|
>
|
||||||
|
<Variant title="Quick Replies">
|
||||||
|
<div class="p-4 bg-n-background rounded-lg w-full min-w-4xl">
|
||||||
|
<QuickReply :message="message" />
|
||||||
|
</div>
|
||||||
|
</Variant>
|
||||||
|
</Story>
|
||||||
|
</template>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
<script setup>
|
||||||
|
import Text from '../../bubbles/Template/Text.vue';
|
||||||
|
|
||||||
|
const message = {
|
||||||
|
content: 'Hello John, how may we assist you?',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<Story
|
||||||
|
title="Components/Message Bubbles/Template/Text"
|
||||||
|
:layout="{ type: 'grid', width: '600px' }"
|
||||||
|
>
|
||||||
|
<Variant title="Default Text">
|
||||||
|
<div class="p-4 bg-n-background rounded-lg w-full min-w-4xl">
|
||||||
|
<Text :message="message" />
|
||||||
|
</div>
|
||||||
|
</Variant>
|
||||||
|
</Story>
|
||||||
|
</template>
|
||||||
+92
-159
@@ -1,100 +1,129 @@
|
|||||||
<script>
|
<script setup>
|
||||||
import { mapGetters } from 'vuex';
|
import { ref, computed } from 'vue';
|
||||||
import NextButton from 'dashboard/components-next/button/Button.vue';
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { useMapGetter } from 'dashboard/composables/store';
|
||||||
|
import { vOnClickOutside } from '@vueuse/components';
|
||||||
|
|
||||||
export default {
|
import NextButton from 'dashboard/components-next/button/Button.vue';
|
||||||
components: {
|
import Input from 'dashboard/components-next/input/Input.vue';
|
||||||
NextButton,
|
|
||||||
},
|
const emit = defineEmits(['close', 'assign']);
|
||||||
emits: ['update', 'close', 'assign'],
|
|
||||||
data() {
|
const { t } = useI18n();
|
||||||
return {
|
|
||||||
query: '',
|
const labels = useMapGetter('labels/getLabels');
|
||||||
selectedLabels: [],
|
|
||||||
};
|
const query = ref('');
|
||||||
},
|
const selectedLabels = ref([]);
|
||||||
computed: {
|
|
||||||
...mapGetters({ labels: 'labels/getLabels' }),
|
const filteredLabels = computed(() => {
|
||||||
filteredLabels() {
|
if (!query.value) return labels.value;
|
||||||
return this.labels.filter(label =>
|
return labels.value.filter(label =>
|
||||||
label.title.toLowerCase().includes(this.query.toLowerCase())
|
label.title.toLowerCase().includes(query.value.toLowerCase())
|
||||||
);
|
);
|
||||||
},
|
});
|
||||||
},
|
|
||||||
methods: {
|
const hasLabels = computed(() => labels.value.length > 0);
|
||||||
isLabelSelected(label) {
|
const hasFilteredLabels = computed(() => filteredLabels.value.length > 0);
|
||||||
return this.selectedLabels.includes(label);
|
|
||||||
},
|
const isLabelSelected = label => {
|
||||||
assignLabels(key) {
|
return selectedLabels.value.includes(label);
|
||||||
this.$emit('update', key);
|
};
|
||||||
},
|
|
||||||
onClose() {
|
const onClose = () => {
|
||||||
this.$emit('close');
|
emit('close');
|
||||||
},
|
};
|
||||||
},
|
|
||||||
|
const handleAssign = () => {
|
||||||
|
if (selectedLabels.value.length > 0) {
|
||||||
|
emit('assign', selectedLabels.value);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-on-clickaway="onClose" class="labels-container">
|
<div
|
||||||
|
v-on-click-outside="onClose"
|
||||||
|
class="absolute ltr:right-2 rtl:left-2 top-12 origin-top-right z-20 w-60 bg-n-alpha-3 backdrop-blur-[100px] border-n-weak rounded-lg border border-solid shadow-md"
|
||||||
|
role="dialog"
|
||||||
|
aria-labelledby="label-dialog-title"
|
||||||
|
>
|
||||||
<div class="triangle">
|
<div class="triangle">
|
||||||
<svg height="12" viewBox="0 0 24 12" width="24">
|
<svg height="12" viewBox="0 0 24 12" width="24">
|
||||||
<path d="M20 12l-8-8-12 12" fill-rule="evenodd" stroke-width="1px" />
|
<path d="M20 12l-8-8-12 12" fill-rule="evenodd" stroke-width="1px" />
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between header">
|
<div class="flex items-center justify-between p-2.5">
|
||||||
<span>{{ $t('BULK_ACTION.LABELS.ASSIGN_LABELS') }}</span>
|
<span class="text-sm font-medium">{{
|
||||||
|
t('BULK_ACTION.LABELS.ASSIGN_LABELS')
|
||||||
|
}}</span>
|
||||||
<NextButton ghost xs slate icon="i-lucide-x" @click="onClose" />
|
<NextButton ghost xs slate icon="i-lucide-x" @click="onClose" />
|
||||||
</div>
|
</div>
|
||||||
<div class="labels-list">
|
<div class="flex flex-col max-h-60 min-h-0">
|
||||||
<header class="labels-list__header">
|
<header class="py-2 px-2.5">
|
||||||
<div
|
<Input
|
||||||
class="flex items-center justify-between h-8 gap-2 label-list-search"
|
v-model="query"
|
||||||
>
|
type="search"
|
||||||
<fluent-icon icon="search" class="search-icon" size="16" />
|
:placeholder="t('BULK_ACTION.SEARCH_INPUT_PLACEHOLDER')"
|
||||||
<input
|
icon-left="i-lucide-search"
|
||||||
v-model="query"
|
size="sm"
|
||||||
type="search"
|
class="w-full"
|
||||||
:placeholder="$t('BULK_ACTION.SEARCH_INPUT_PLACEHOLDER')"
|
:aria-label="t('BULK_ACTION.SEARCH_INPUT_PLACEHOLDER')"
|
||||||
class="reset-base !outline-0 !text-sm label--search_input"
|
/>
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</header>
|
</header>
|
||||||
<ul class="labels-list__body">
|
<ul
|
||||||
|
v-if="hasLabels"
|
||||||
|
class="flex-1 overflow-y-auto m-0 list-none"
|
||||||
|
role="listbox"
|
||||||
|
:aria-label="t('BULK_ACTION.LABELS.ASSIGN_LABELS')"
|
||||||
|
>
|
||||||
|
<li v-if="!hasFilteredLabels" class="p-2 text-center">
|
||||||
|
<span class="text-sm text-n-slate-11">{{
|
||||||
|
t('BULK_ACTION.LABELS.NO_LABELS_FOUND')
|
||||||
|
}}</span>
|
||||||
|
</li>
|
||||||
<li
|
<li
|
||||||
v-for="label in filteredLabels"
|
v-for="label in filteredLabels"
|
||||||
:key="label.id"
|
:key="label.id"
|
||||||
class="label__list-item"
|
class="my-1 mx-0 py-0 px-2.5"
|
||||||
|
role="option"
|
||||||
|
:aria-selected="isLabelSelected(label.title)"
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
class="item"
|
class="items-center rounded-md cursor-pointer flex py-1 px-2.5 hover:bg-n-slate-3 dark:hover:bg-n-solid-3 has-[:checked]:bg-n-slate-2"
|
||||||
:class="{ 'label-selected': isLabelSelected(label.title) }"
|
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
v-model="selectedLabels"
|
v-model="selectedLabels"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
:value="label.title"
|
:value="label.title"
|
||||||
class="label-checkbox"
|
class="my-0 ltr:mr-2.5 rtl:ml-2.5"
|
||||||
|
:aria-label="label.title"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
class="overflow-hidden label-title whitespace-nowrap text-ellipsis"
|
class="overflow-hidden flex-grow w-full text-sm whitespace-nowrap text-ellipsis"
|
||||||
>
|
>
|
||||||
{{ label.title }}
|
{{ label.title }}
|
||||||
</span>
|
</span>
|
||||||
<span
|
<span
|
||||||
class="label-pill"
|
class="rounded-md h-3 w-3 flex-shrink-0 border border-solid border-n-weak"
|
||||||
:style="{ backgroundColor: label.color }"
|
:style="{ backgroundColor: label.color }"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<footer class="labels-list__footer">
|
<div v-else class="p-2 text-center">
|
||||||
|
<span class="text-sm text-n-slate-11">{{
|
||||||
|
t('CONTACTS_BULK_ACTIONS.NO_LABELS_FOUND')
|
||||||
|
}}</span>
|
||||||
|
</div>
|
||||||
|
<footer class="p-2">
|
||||||
<NextButton
|
<NextButton
|
||||||
sm
|
sm
|
||||||
type="submit"
|
type="submit"
|
||||||
:label="$t('BULK_ACTION.LABELS.ASSIGN_SELECTED_LABELS')"
|
class="w-full"
|
||||||
|
:label="t('BULK_ACTION.LABELS.ASSIGN_SELECTED_LABELS')"
|
||||||
:disabled="!selectedLabels.length"
|
:disabled="!selectedLabels.length"
|
||||||
@click="$emit('assign', selectedLabels)"
|
@click="handleAssign"
|
||||||
/>
|
/>
|
||||||
</footer>
|
</footer>
|
||||||
</div>
|
</div>
|
||||||
@@ -102,107 +131,11 @@ export default {
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
.labels-list {
|
.triangle {
|
||||||
@apply flex flex-col max-h-[15rem] min-h-[auto];
|
@apply block z-10 absolute text-left -top-3 ltr:right-[--triangle-position] rtl:left-[--triangle-position];
|
||||||
|
|
||||||
.labels-list__header {
|
svg path {
|
||||||
@apply bg-n-alpha-3 backdrop-blur-[100px] py-0 px-2.5;
|
@apply fill-n-alpha-3 backdrop-blur-[100px] stroke-n-weak;
|
||||||
}
|
}
|
||||||
|
|
||||||
.labels-list__body {
|
|
||||||
@apply flex-1 overflow-y-auto py-2.5 mx-0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.labels-list__footer {
|
|
||||||
@apply p-2;
|
|
||||||
|
|
||||||
button {
|
|
||||||
@apply w-full;
|
|
||||||
|
|
||||||
.button__content {
|
|
||||||
@apply text-center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.label-list-search {
|
|
||||||
@apply bg-n-alpha-black2 py-0 px-2.5 border border-solid border-n-strong rounded-md;
|
|
||||||
|
|
||||||
.search-icon {
|
|
||||||
@apply text-n-slate-10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label--search_input {
|
|
||||||
@apply border-0 text-xs m-0 dark:bg-transparent bg-transparent h-[unset] w-full;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.labels-container {
|
|
||||||
@apply absolute ltr:right-2 rtl:left-2 top-12 origin-top-right w-auto z-20 max-w-[15rem] min-w-[15rem] bg-n-alpha-3 backdrop-blur-[100px] border-n-weak rounded-lg border border-solid shadow-md;
|
|
||||||
|
|
||||||
.header {
|
|
||||||
@apply p-2.5;
|
|
||||||
|
|
||||||
span {
|
|
||||||
@apply text-sm font-medium;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
@apply max-h-[15rem] overflow-y-auto;
|
|
||||||
|
|
||||||
.label__list-container {
|
|
||||||
@apply h-full;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.triangle {
|
|
||||||
@apply block z-10 absolute text-left -top-3 ltr:right-[--triangle-position] rtl:left-[--triangle-position];
|
|
||||||
|
|
||||||
svg path {
|
|
||||||
@apply fill-n-alpha-3 backdrop-blur-[100px] stroke-n-weak;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
|
||||||
@apply m-0 list-none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.labels-placeholder {
|
|
||||||
@apply p-2;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label__list-item {
|
|
||||||
@apply my-1 mx-0 py-0 px-2.5;
|
|
||||||
|
|
||||||
.item {
|
|
||||||
@apply items-center rounded-md cursor-pointer flex py-1 px-2.5 hover:bg-n-slate-3 dark:hover:bg-n-solid-3;
|
|
||||||
|
|
||||||
&.label-selected {
|
|
||||||
@apply bg-n-slate-2;
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
@apply text-sm;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label-checkbox {
|
|
||||||
@apply my-0 ltr:mr-2.5 rtl:ml-2.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label-title {
|
|
||||||
@apply flex-grow w-full;
|
|
||||||
}
|
|
||||||
|
|
||||||
.label-pill {
|
|
||||||
@apply rounded-md h-3 w-3 flex-shrink-0 border border-solid border-n-weak;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-container {
|
|
||||||
@apply bg-n-alpha-3 backdrop-blur-[100px] py-0 px-2.5 sticky top-0 z-20;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "No labels found for",
|
"NO_LABELS_FOUND": "No labels found",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "በአሁኑ ጊዜ ንቁ እውቂያዎች የሉም 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "በአሁኑ ጊዜ ንቁ እውቂያዎች የሉም 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Assign Labels",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "All"
|
"ALL": "All"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Edit",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Delete"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "إضافة وسم",
|
"ASSIGN_LABELS": "إضافة وسم",
|
||||||
"NO_LABELS_FOUND": "لم يتم العثور على تسميات لـ",
|
"NO_LABELS_FOUND": "لم يتم العثور على تصنيفات",
|
||||||
"ASSIGN_SELECTED_LABELS": "تعيين التسميات المحددة",
|
"ASSIGN_SELECTED_LABELS": "تعيين التسميات المحددة",
|
||||||
"ASSIGN_SUCCESFUL": "تم تعيين التسميات بنجاح.",
|
"ASSIGN_SUCCESFUL": "تم تعيين التسميات بنجاح.",
|
||||||
"ASSIGN_FAILED": "فشل في تعيين التسميات ، الرجاء المحاولة مرة أخرى."
|
"ASSIGN_FAILED": "فشل في تعيين التسميات ، الرجاء المحاولة مرة أخرى."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "تعيين التسميات",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "تم تعيين التسميات بنجاح.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "الكل"
|
"ALL": "الكل"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "تعديل",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "حذف"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "No labels found for",
|
"NO_LABELS_FOUND": "No labels found",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Assign Labels",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "All"
|
"ALL": "All"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Edit",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Delete"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "No labels found for",
|
"NO_LABELS_FOUND": "Няма намерени етикети",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Assign Labels",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "Всички"
|
"ALL": "Всички"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Редактирай",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Изтрий"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "No labels found for",
|
"NO_LABELS_FOUND": "No labels found",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Assign Labels",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "All"
|
"ALL": "All"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Edit",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Delete"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assignar etiquetes",
|
"ASSIGN_LABELS": "Assignar etiquetes",
|
||||||
"NO_LABELS_FOUND": "No s'han trobat etiquetes per a",
|
"NO_LABELS_FOUND": "No s'han trobat etiquetes",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assigna les etiquetes seleccionades",
|
"ASSIGN_SELECTED_LABELS": "Assigna les etiquetes seleccionades",
|
||||||
"ASSIGN_SUCCESFUL": "L'etiqueta s'ha assignat correctament.",
|
"ASSIGN_SUCCESFUL": "L'etiqueta s'ha assignat correctament.",
|
||||||
"ASSIGN_FAILED": "No s'han pogut assignar les etiquetes. Torna-ho a provar."
|
"ASSIGN_FAILED": "No s'han pogut assignar les etiquetes. Torna-ho a provar."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Assign Labels",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "L'etiqueta s'ha assignat correctament.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "Totes"
|
"ALL": "Totes"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Edita",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Esborrar"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "No labels found for",
|
"NO_LABELS_FOUND": "No labels found",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Assign Labels",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "Vše"
|
"ALL": "Vše"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Upravit",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Vymazat"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "Ingen etiketter fundet for",
|
"NO_LABELS_FOUND": "Ingen labels fundet",
|
||||||
"ASSIGN_SELECTED_LABELS": "Tildel valgte etiketter",
|
"ASSIGN_SELECTED_LABELS": "Tildel valgte etiketter",
|
||||||
"ASSIGN_SUCCESFUL": "Etiketter tildelt med succes.",
|
"ASSIGN_SUCCESFUL": "Etiketter tildelt med succes.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Tildel Etiketter",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "Etiketter tildelt med succes.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "Alle"
|
"ALL": "Alle"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Rediger",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Slet"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Labels zuweisen",
|
"ASSIGN_LABELS": "Labels zuweisen",
|
||||||
"NO_LABELS_FOUND": "Keine Labels gefunden für",
|
"NO_LABELS_FOUND": "Keine Labels gefunden",
|
||||||
"ASSIGN_SELECTED_LABELS": "Ausgewählte Labels zuweisen",
|
"ASSIGN_SELECTED_LABELS": "Ausgewählte Labels zuweisen",
|
||||||
"ASSIGN_SUCCESFUL": "Labels erfolgreich zugewiesen.",
|
"ASSIGN_SUCCESFUL": "Labels erfolgreich zugewiesen.",
|
||||||
"ASSIGN_FAILED": "Labels konnten nicht zugewiesen werden. Bitte versuchen Sie es erneut."
|
"ASSIGN_FAILED": "Labels konnten nicht zugewiesen werden. Bitte versuchen Sie es erneut."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "Im Moment sind keine Kontakte aktiv 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "Im Moment sind keine Kontakte aktiv 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Labels zuweisen",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "Labels erfolgreich zugewiesen.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "Wir konnten die Suche nicht abschließen. Bitte versuch es erneut."
|
"ERROR_MESSAGE": "Wir konnten die Suche nicht abschließen. Bitte versuch es erneut."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "Alle"
|
"ALL": "Alle"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Bearbeiten",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Löschen"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "Δεν βρέθηκαν πρότυπα για",
|
"NO_LABELS_FOUND": "Δεν βρέθηκαν ετικέτες",
|
||||||
"ASSIGN_SELECTED_LABELS": "Ανάθεση επιλεγμένων ετικετών",
|
"ASSIGN_SELECTED_LABELS": "Ανάθεση επιλεγμένων ετικετών",
|
||||||
"ASSIGN_SUCCESFUL": "Επιτυχής ανάθεση ετικετών.",
|
"ASSIGN_SUCCESFUL": "Επιτυχής ανάθεση ετικετών.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Ανάθεση Ετικετών",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "Επιτυχής ανάθεση ετικετών.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "Όλες"
|
"ALL": "Όλες"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Επεξεργασία",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Διαγραφή"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "No labels found for",
|
"NO_LABELS_FOUND": "No labels found",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
||||||
|
|||||||
@@ -572,6 +572,27 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Assign Labels",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})",
|
||||||
|
"DELETE_CONTACTS": "Delete",
|
||||||
|
"DELETE_SUCCESS": "Contacts deleted successfully.",
|
||||||
|
"DELETE_FAILED": "Failed to delete contacts.",
|
||||||
|
"DELETE_DIALOG": {
|
||||||
|
"TITLE": "Delete selected contacts",
|
||||||
|
"SINGULAR_TITLE": "Delete selected contact",
|
||||||
|
"DESCRIPTION": "This will permanently delete {count} selected contacts. This action cannot be undone.",
|
||||||
|
"SINGULAR_DESCRIPTION": "This will permanently delete the selected contact. This action cannot be undone.",
|
||||||
|
"CONFIRM_MULTIPLE": "Delete contacts",
|
||||||
|
"CONFIRM_SINGLE": "Delete contact"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
|
|||||||
@@ -15,20 +15,6 @@
|
|||||||
},
|
},
|
||||||
"ERROR": "There was an error connecting to Shopify. Please try again or contact support if the issue persists."
|
"ERROR": "There was an error connecting to Shopify. Please try again or contact support if the issue persists."
|
||||||
},
|
},
|
||||||
"GITHUB": {
|
|
||||||
"TITLE": "Connect Github",
|
|
||||||
"LABEL": "Github Client ID",
|
|
||||||
"PLACEHOLDER": "Enter your Github Client ID",
|
|
||||||
"HELP": "Enter your Github Client ID",
|
|
||||||
"CANCEL": "Cancel",
|
|
||||||
"SUBMIT": "Connect",
|
|
||||||
"DELETE": {
|
|
||||||
"TITLE": "Are you sure you want to delete the integration?",
|
|
||||||
"MESSAGE": "Are you sure you want to delete the integration?",
|
|
||||||
"CONFIRM": "Yes, delete",
|
|
||||||
"CANCEL": "Cancel"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"HEADER": "Integrations",
|
"HEADER": "Integrations",
|
||||||
"DESCRIPTION": "Chatwoot integrates with multiple tools and services to improve your team's efficiency. Explore the list below to configure your favorite apps.",
|
"DESCRIPTION": "Chatwoot integrates with multiple tools and services to improve your team's efficiency. Explore the list below to configure your favorite apps.",
|
||||||
"LEARN_MORE": "Learn more about integrations",
|
"LEARN_MORE": "Learn more about integrations",
|
||||||
@@ -352,7 +338,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
"CAPTAIN": {
|
"CAPTAIN": {
|
||||||
"NAME": "Captain",
|
"NAME": "Captain",
|
||||||
"HEADER_KNOW_MORE": "Know more",
|
"HEADER_KNOW_MORE": "Know more",
|
||||||
@@ -876,6 +861,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -915,6 +901,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "All"
|
"ALL": "All"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -946,13 +936,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Edit",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Delete"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Asignar etiqueta",
|
"ASSIGN_LABELS": "Asignar etiqueta",
|
||||||
"NO_LABELS_FOUND": "No se encontraron etiquetas para",
|
"NO_LABELS_FOUND": "No se encontraron etiquetas",
|
||||||
"ASSIGN_SELECTED_LABELS": "Asignar etiquetas seleccionadas",
|
"ASSIGN_SELECTED_LABELS": "Asignar etiquetas seleccionadas",
|
||||||
"ASSIGN_SUCCESFUL": "Etiquetas asignadas correctamente.",
|
"ASSIGN_SUCCESFUL": "Etiquetas asignadas correctamente.",
|
||||||
"ASSIGN_FAILED": "Error al asignar etiquetas, inténtalo de nuevo."
|
"ASSIGN_FAILED": "Error al asignar etiquetas, inténtalo de nuevo."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No hay contactos activos por el momento 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No hay contactos activos por el momento 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Asignar etiquetas",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "Etiquetas asignadas correctamente.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "No pudimos completar la búsqueda. Por favor, inténtalo de nuevo."
|
"ERROR_MESSAGE": "No pudimos completar la búsqueda. Por favor, inténtalo de nuevo."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "Preguntas frecuentes",
|
"HEADER": "Preguntas frecuentes",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "Todos"
|
"ALL": "Todos"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Editar",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Eliminar"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "No labels found for",
|
"NO_LABELS_FOUND": "No labels found",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Assign Labels",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "All"
|
"ALL": "All"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Edit",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Delete"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "برچسب اختصاص دهید",
|
"ASSIGN_LABELS": "برچسب اختصاص دهید",
|
||||||
"NO_LABELS_FOUND": "هیچ برچسبی یافت نشد برای",
|
"NO_LABELS_FOUND": "هیچ برچسبی یافت نشد",
|
||||||
"ASSIGN_SELECTED_LABELS": "اختصاص برچسبهای انتخاب شده",
|
"ASSIGN_SELECTED_LABELS": "اختصاص برچسبهای انتخاب شده",
|
||||||
"ASSIGN_SUCCESFUL": "برچسبها با موفقیت اختصاص یافتند.",
|
"ASSIGN_SUCCESFUL": "برچسبها با موفقیت اختصاص یافتند.",
|
||||||
"ASSIGN_FAILED": "اختصاص برچسب به صورت موفق انجام نشد، لطفا دوباره امتحان کنید."
|
"ASSIGN_FAILED": "اختصاص برچسب به صورت موفق انجام نشد، لطفا دوباره امتحان کنید."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "اختصاص برچسبها",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "برچسبها با موفقیت اختصاص یافتند.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "همه"
|
"ALL": "همه"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "ویرایش",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "حذف"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "No labels found for",
|
"NO_LABELS_FOUND": "No labels found",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Assign Labels",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "Kaikki"
|
"ALL": "Kaikki"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Muokkaa",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Poista"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assigner une étiquette",
|
"ASSIGN_LABELS": "Assigner une étiquette",
|
||||||
"NO_LABELS_FOUND": "Aucune étiquette trouvée pour",
|
"NO_LABELS_FOUND": "Aucune étiquette trouvée",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assigner les étiquettes sélectionnées",
|
"ASSIGN_SELECTED_LABELS": "Assigner les étiquettes sélectionnées",
|
||||||
"ASSIGN_SUCCESFUL": "Étiquettes attribuées avec succès.",
|
"ASSIGN_SUCCESFUL": "Étiquettes attribuées avec succès.",
|
||||||
"ASSIGN_FAILED": "Impossible d'attribuer les étiquettes, veuillez réessayer."
|
"ASSIGN_FAILED": "Impossible d'attribuer les étiquettes, veuillez réessayer."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "Aucun contact n'est actif pour le moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "Aucun contact n'est actif pour le moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Assigner des étiquettes",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "Étiquettes attribuées avec succès.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "Tous"
|
"ALL": "Tous"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Modifier",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Supprimer"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "לא נצאו תוויות עבור",
|
"NO_LABELS_FOUND": "לא נמצאו תוויות",
|
||||||
"ASSIGN_SELECTED_LABELS": "שייך תוויות נבחרות",
|
"ASSIGN_SELECTED_LABELS": "שייך תוויות נבחרות",
|
||||||
"ASSIGN_SUCCESFUL": "תוויות שוייכו בהצלחה.",
|
"ASSIGN_SUCCESFUL": "תוויות שוייכו בהצלחה.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "הקצה תוויות",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "תוויות שוייכו בהצלחה.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "הכל"
|
"ALL": "הכל"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "ערוך",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "מחק"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "No labels found for",
|
"NO_LABELS_FOUND": "No labels found",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Assign Labels",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "All"
|
"ALL": "All"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Edit",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Delete"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "No labels found for",
|
"NO_LABELS_FOUND": "No labels found",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Assign Labels",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "Sve"
|
"ALL": "Sve"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Uredi",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Izbriši"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Címkék hozzárendelése",
|
"ASSIGN_LABELS": "Címkék hozzárendelése",
|
||||||
"NO_LABELS_FOUND": "Nem található cimke erre:",
|
"NO_LABELS_FOUND": "Nem találtunk címkét",
|
||||||
"ASSIGN_SELECTED_LABELS": "Válogatott címkék hozzárendelése",
|
"ASSIGN_SELECTED_LABELS": "Válogatott címkék hozzárendelése",
|
||||||
"ASSIGN_SUCCESFUL": "Címkék hozzárendelése sikeres.",
|
"ASSIGN_SUCCESFUL": "Címkék hozzárendelése sikeres.",
|
||||||
"ASSIGN_FAILED": "Nem sikerült címkéket hozzárendelni. Kérjük, próbálja újra."
|
"ASSIGN_FAILED": "Nem sikerült címkéket hozzárendelni. Kérjük, próbálja újra."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Cimke hozzáadása",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "Címkék hozzárendelése sikeres.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "Mind"
|
"ALL": "Mind"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Szerkesztés",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Törlés"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "No labels found for",
|
"NO_LABELS_FOUND": "No labels found",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Assign Labels",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "Labels assigned successfully.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "All"
|
"ALL": "All"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Edit",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Delete"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "Tidak ada label ditemukan untuk",
|
"NO_LABELS_FOUND": "Tidak ada label",
|
||||||
"ASSIGN_SELECTED_LABELS": "Tugaskan label terpilih",
|
"ASSIGN_SELECTED_LABELS": "Tugaskan label terpilih",
|
||||||
"ASSIGN_SUCCESFUL": "Label berhasil ditugaskan.",
|
"ASSIGN_SUCCESFUL": "Label berhasil ditugaskan.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
||||||
|
|||||||
@@ -571,6 +571,16 @@
|
|||||||
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
"ACTIVE_EMPTY_STATE_TITLE": "No contacts are active at the moment 🌙"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"CONTACTS_BULK_ACTIONS": {
|
||||||
|
"ASSIGN_LABELS": "Tugaskan Label",
|
||||||
|
"ASSIGN_LABELS_SUCCESS": "Label berhasil ditugaskan.",
|
||||||
|
"ASSIGN_LABELS_FAILED": "Failed to assign labels",
|
||||||
|
"DESCRIPTION": "Select the labels you want to add to the selected contacts.",
|
||||||
|
"NO_LABELS_FOUND": "No labels available yet.",
|
||||||
|
"SELECTED_COUNT": "{count} selected",
|
||||||
|
"CLEAR_SELECTION": "Clear selection",
|
||||||
|
"SELECT_ALL": "Select all ({count})"
|
||||||
|
},
|
||||||
"COMPOSE_NEW_CONVERSATION": {
|
"COMPOSE_NEW_CONVERSATION": {
|
||||||
"CONTACT_SEARCH": {
|
"CONTACT_SEARCH": {
|
||||||
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
"ERROR_MESSAGE": "We couldn’t complete the search. Please try again."
|
||||||
|
|||||||
@@ -863,6 +863,7 @@
|
|||||||
},
|
},
|
||||||
"RESPONSES": {
|
"RESPONSES": {
|
||||||
"HEADER": "FAQs",
|
"HEADER": "FAQs",
|
||||||
|
"PENDING_FAQS": "Pending FAQs",
|
||||||
"ADD_NEW": "Create new FAQ",
|
"ADD_NEW": "Create new FAQ",
|
||||||
"DOCUMENTABLE": {
|
"DOCUMENTABLE": {
|
||||||
"CONVERSATION": "Conversation #{id}"
|
"CONVERSATION": "Conversation #{id}"
|
||||||
@@ -902,6 +903,10 @@
|
|||||||
"APPROVED": "Approved",
|
"APPROVED": "Approved",
|
||||||
"ALL": "Semua"
|
"ALL": "Semua"
|
||||||
},
|
},
|
||||||
|
"PENDING_BANNER": {
|
||||||
|
"TITLE": "Captain has found some FAQs your customers were looking for.",
|
||||||
|
"ACTION": "Click here to review"
|
||||||
|
},
|
||||||
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
"FORM_DESCRIPTION": "Add a question and its corresponding answer to the knowledge base and select the assistant it should be associated with.",
|
||||||
"CREATE": {
|
"CREATE": {
|
||||||
"TITLE": "Add an FAQ",
|
"TITLE": "Add an FAQ",
|
||||||
@@ -932,13 +937,15 @@
|
|||||||
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
"APPROVE_SUCCESS_MESSAGE": "The FAQ was marked as approved"
|
||||||
},
|
},
|
||||||
"OPTIONS": {
|
"OPTIONS": {
|
||||||
"APPROVE": "Mark as approved",
|
"APPROVE": "Approve",
|
||||||
"EDIT_RESPONSE": "Edit FAQ",
|
"EDIT_RESPONSE": "Edit",
|
||||||
"DELETE_RESPONSE": "Delete FAQ"
|
"DELETE_RESPONSE": "Hapus"
|
||||||
},
|
},
|
||||||
"EMPTY_STATE": {
|
"EMPTY_STATE": {
|
||||||
"TITLE": "No FAQs Found",
|
"TITLE": "No FAQs Found",
|
||||||
|
"NO_PENDING_TITLE": "There are no more pending FAQs to review",
|
||||||
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
"SUBTITLE": "FAQs help your assistant provide quick and accurate answers to questions from your customers. They can be generated automatically from your content or can be added manually.",
|
||||||
|
"CLEAR_SEARCH": "Clear active filters",
|
||||||
"FEATURE_SPOTLIGHT": {
|
"FEATURE_SPOTLIGHT": {
|
||||||
"TITLE": "Captain FAQ",
|
"TITLE": "Captain FAQ",
|
||||||
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
"NOTE": "Captain FAQs detects common customer questions—whether missing from your knowledge base or frequently asked—and generates relevant FAQs to improve support. You can review each suggestion and decide whether to approve or reject it."
|
||||||
|
|||||||
@@ -24,7 +24,7 @@
|
|||||||
},
|
},
|
||||||
"LABELS": {
|
"LABELS": {
|
||||||
"ASSIGN_LABELS": "Assign labels",
|
"ASSIGN_LABELS": "Assign labels",
|
||||||
"NO_LABELS_FOUND": "No labels found for",
|
"NO_LABELS_FOUND": "Engar merkingar fundust",
|
||||||
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
"ASSIGN_SELECTED_LABELS": "Assign selected labels",
|
||||||
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
"ASSIGN_SUCCESFUL": "Labels assigned successfully.",
|
||||||
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
"ASSIGN_FAILED": "Failed to assign labels. Please try again."
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user