Merge branch 'release/1.16.0'
This commit is contained in:
commit
10f3d321de
557 changed files with 19291 additions and 4575 deletions
|
@ -30,3 +30,6 @@ exclude_patterns:
|
|||
- "**/*.md"
|
||||
- "**/*.yml"
|
||||
- "app/javascript/dashboard/i18n/locale"
|
||||
- "stories/**/*"
|
||||
- "**/*.stories.js"
|
||||
- "**/stories/"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
{
|
||||
"printWidth": 80,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "es5"
|
||||
"trailingComma": "es5",
|
||||
"arrowParens": "avoid"
|
||||
}
|
||||
|
|
|
@ -101,6 +101,7 @@ Rails/BulkChangeTable:
|
|||
- 'db/migrate/20170511134418_latlong.rb'
|
||||
- 'db/migrate/20191027054756_create_contact_inboxes.rb'
|
||||
- 'db/migrate/20191130164019_add_template_type_to_messages.rb'
|
||||
- 'db/migrate/20210425093724_convert_integration_hook_settings_field.rb'
|
||||
Rails/UniqueValidationWithoutIndex:
|
||||
Exclude:
|
||||
- 'app/models/channel/twitter_profile.rb'
|
||||
|
|
44
.storybook/main.js
Normal file
44
.storybook/main.js
Normal file
|
@ -0,0 +1,44 @@
|
|||
const path = require('path');
|
||||
const resolve = require('../config/webpack/resolve');
|
||||
|
||||
// Chatwoot's webpack.config.js
|
||||
process.env.NODE_ENV = 'development';
|
||||
const custom = require('../config/webpack/environment');
|
||||
|
||||
module.exports = {
|
||||
stories: [
|
||||
'../stories/**/*.stories.mdx',
|
||||
'../app/javascript/**/*.stories.@(js|jsx|ts|tsx)',
|
||||
],
|
||||
addons: [
|
||||
{
|
||||
name: '@storybook/addon-docs',
|
||||
options: {
|
||||
vueDocgenOptions: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, '../'),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
'@storybook/addon-links',
|
||||
'@storybook/addon-essentials',
|
||||
],
|
||||
webpackFinal: config => {
|
||||
const newConfig = {
|
||||
...config,
|
||||
resolve: {
|
||||
...config.resolve,
|
||||
modules: custom.resolvedModules.map(i => i.value),
|
||||
},
|
||||
};
|
||||
|
||||
newConfig.module.rules.push({
|
||||
test: /\.scss$/,
|
||||
use: ['style-loader', 'css-loader', 'sass-loader'],
|
||||
include: path.resolve(__dirname, '../app/javascript'),
|
||||
});
|
||||
|
||||
return newConfig;
|
||||
},
|
||||
};
|
38
.storybook/preview.js
Normal file
38
.storybook/preview.js
Normal file
|
@ -0,0 +1,38 @@
|
|||
import { addDecorator } from '@storybook/vue';
|
||||
import Vue from 'vue';
|
||||
import Vuex from 'vuex';
|
||||
import VueI18n from 'vue-i18n';
|
||||
|
||||
import WootUiKit from '../app/javascript/dashboard/components';
|
||||
import i18n from '../app/javascript/dashboard/i18n';
|
||||
|
||||
import '../app/javascript/dashboard/assets/scss/storybook.scss';
|
||||
|
||||
Vue.use(VueI18n);
|
||||
Vue.use(WootUiKit);
|
||||
Vue.use(Vuex);
|
||||
|
||||
const store = new Vuex.Store({});
|
||||
const i18nConfig = new VueI18n({
|
||||
locale: 'en',
|
||||
messages: i18n,
|
||||
});
|
||||
|
||||
addDecorator(() => ({
|
||||
template: '<story/>',
|
||||
i18n: i18nConfig,
|
||||
store,
|
||||
beforeCreate: function() {
|
||||
this.$root._i18n = this.$i18n;
|
||||
},
|
||||
}));
|
||||
|
||||
export const parameters = {
|
||||
actions: { argTypesRegex: '^on[A-Z].*' },
|
||||
controls: {
|
||||
matchers: {
|
||||
color: /(background|color)$/i,
|
||||
date: /Date$/,
|
||||
},
|
||||
},
|
||||
};
|
8
Gemfile
8
Gemfile
|
@ -31,6 +31,8 @@ gem 'haikunator'
|
|||
gem 'liquid'
|
||||
# Parse Markdown to HTML
|
||||
gem 'commonmarker'
|
||||
# Validate Data against JSON Schema
|
||||
gem 'json_schemer'
|
||||
|
||||
##-- for active storage --##
|
||||
gem 'aws-sdk-s3', require: false
|
||||
|
@ -80,6 +82,8 @@ gem 'twitty'
|
|||
gem 'koala'
|
||||
# slack client
|
||||
gem 'slack-ruby-client'
|
||||
# for dialogflow integrations
|
||||
gem 'google-cloud-dialogflow'
|
||||
|
||||
##--- gems for debugging and error reporting ---##
|
||||
# static analysis
|
||||
|
@ -105,6 +109,8 @@ gem 'maxminddb'
|
|||
# to create db triggers
|
||||
gem 'hairtrigger'
|
||||
|
||||
gem 'procore-sift'
|
||||
|
||||
group :development do
|
||||
gem 'annotate'
|
||||
gem 'bullet'
|
||||
|
@ -112,7 +118,7 @@ group :development do
|
|||
gem 'web-console'
|
||||
|
||||
# used in swagger build
|
||||
gem 'json_refs', git: 'https://github.com/tzmfreedom/json_refs', ref: 'e32deb0'
|
||||
gem 'json_refs', git: 'https://github.com/tzmfreedom/json_refs', ref: '131b11294fd6af9c428171f38516e6222a58c874'
|
||||
|
||||
# When we want to squash migrations
|
||||
gem 'squasher'
|
||||
|
|
186
Gemfile.lock
186
Gemfile.lock
|
@ -7,10 +7,10 @@ GIT
|
|||
|
||||
GIT
|
||||
remote: https://github.com/tzmfreedom/json_refs
|
||||
revision: e32deb073ce9aef39bdd63556bffd7fe7c2a803d
|
||||
ref: e32deb0
|
||||
revision: 131b11294fd6af9c428171f38516e6222a58c874
|
||||
ref: 131b11294fd6af9c428171f38516e6222a58c874
|
||||
specs:
|
||||
json_refs (0.1.2)
|
||||
json_refs (0.1.6)
|
||||
hana
|
||||
|
||||
GEM
|
||||
|
@ -18,58 +18,58 @@ GEM
|
|||
specs:
|
||||
action-cable-testing (0.6.1)
|
||||
actioncable (>= 5.0)
|
||||
actioncable (6.0.3.6)
|
||||
actionpack (= 6.0.3.6)
|
||||
actioncable (6.0.3.7)
|
||||
actionpack (= 6.0.3.7)
|
||||
nio4r (~> 2.0)
|
||||
websocket-driver (>= 0.6.1)
|
||||
actionmailbox (6.0.3.6)
|
||||
actionpack (= 6.0.3.6)
|
||||
activejob (= 6.0.3.6)
|
||||
activerecord (= 6.0.3.6)
|
||||
activestorage (= 6.0.3.6)
|
||||
activesupport (= 6.0.3.6)
|
||||
actionmailbox (6.0.3.7)
|
||||
actionpack (= 6.0.3.7)
|
||||
activejob (= 6.0.3.7)
|
||||
activerecord (= 6.0.3.7)
|
||||
activestorage (= 6.0.3.7)
|
||||
activesupport (= 6.0.3.7)
|
||||
mail (>= 2.7.1)
|
||||
actionmailer (6.0.3.6)
|
||||
actionpack (= 6.0.3.6)
|
||||
actionview (= 6.0.3.6)
|
||||
activejob (= 6.0.3.6)
|
||||
actionmailer (6.0.3.7)
|
||||
actionpack (= 6.0.3.7)
|
||||
actionview (= 6.0.3.7)
|
||||
activejob (= 6.0.3.7)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
actionpack (6.0.3.6)
|
||||
actionview (= 6.0.3.6)
|
||||
activesupport (= 6.0.3.6)
|
||||
actionpack (6.0.3.7)
|
||||
actionview (= 6.0.3.7)
|
||||
activesupport (= 6.0.3.7)
|
||||
rack (~> 2.0, >= 2.0.8)
|
||||
rack-test (>= 0.6.3)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.2.0)
|
||||
actiontext (6.0.3.6)
|
||||
actionpack (= 6.0.3.6)
|
||||
activerecord (= 6.0.3.6)
|
||||
activestorage (= 6.0.3.6)
|
||||
activesupport (= 6.0.3.6)
|
||||
actiontext (6.0.3.7)
|
||||
actionpack (= 6.0.3.7)
|
||||
activerecord (= 6.0.3.7)
|
||||
activestorage (= 6.0.3.7)
|
||||
activesupport (= 6.0.3.7)
|
||||
nokogiri (>= 1.8.5)
|
||||
actionview (6.0.3.6)
|
||||
activesupport (= 6.0.3.6)
|
||||
actionview (6.0.3.7)
|
||||
activesupport (= 6.0.3.7)
|
||||
builder (~> 3.1)
|
||||
erubi (~> 1.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.1, >= 1.2.0)
|
||||
activejob (6.0.3.6)
|
||||
activesupport (= 6.0.3.6)
|
||||
activejob (6.0.3.7)
|
||||
activesupport (= 6.0.3.7)
|
||||
globalid (>= 0.3.6)
|
||||
activemodel (6.0.3.6)
|
||||
activesupport (= 6.0.3.6)
|
||||
activerecord (6.0.3.6)
|
||||
activemodel (= 6.0.3.6)
|
||||
activesupport (= 6.0.3.6)
|
||||
activemodel (6.0.3.7)
|
||||
activesupport (= 6.0.3.7)
|
||||
activerecord (6.0.3.7)
|
||||
activemodel (= 6.0.3.7)
|
||||
activesupport (= 6.0.3.7)
|
||||
activerecord-import (1.0.7)
|
||||
activerecord (>= 3.2)
|
||||
activestorage (6.0.3.6)
|
||||
actionpack (= 6.0.3.6)
|
||||
activejob (= 6.0.3.6)
|
||||
activerecord (= 6.0.3.6)
|
||||
activestorage (6.0.3.7)
|
||||
actionpack (= 6.0.3.7)
|
||||
activejob (= 6.0.3.7)
|
||||
activerecord (= 6.0.3.7)
|
||||
marcel (~> 1.0.0)
|
||||
activesupport (6.0.3.6)
|
||||
activesupport (6.0.3.7)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 0.7, < 2)
|
||||
minitest (~> 5.1)
|
||||
|
@ -79,11 +79,10 @@ GEM
|
|||
activerecord (>= 5.0, < 6.1)
|
||||
addressable (2.7.0)
|
||||
public_suffix (>= 2.0.2, < 5.0)
|
||||
administrate (0.14.0)
|
||||
actionpack (>= 4.2)
|
||||
actionview (>= 4.2)
|
||||
activerecord (>= 4.2)
|
||||
autoprefixer-rails (>= 6.0)
|
||||
administrate (0.16.0)
|
||||
actionpack (>= 5.0)
|
||||
actionview (>= 5.0)
|
||||
activerecord (>= 5.0)
|
||||
datetime_picker_rails (~> 0.0.7)
|
||||
jquery-rails (>= 4.0)
|
||||
kaminari (>= 1.0)
|
||||
|
@ -95,8 +94,6 @@ GEM
|
|||
rake (>= 10.4, < 14.0)
|
||||
ast (2.4.1)
|
||||
attr_extras (6.2.4)
|
||||
autoprefixer-rails (9.8.6.3)
|
||||
execjs
|
||||
aws-eventstream (1.1.0)
|
||||
aws-partitions (1.360.0)
|
||||
aws-sdk-core (3.105.0)
|
||||
|
@ -184,6 +181,8 @@ GEM
|
|||
dotenv-rails (2.7.6)
|
||||
dotenv (= 2.7.6)
|
||||
railties (>= 3.2)
|
||||
ecma-re-validator (0.2.1)
|
||||
regexp_parser (~> 1.2)
|
||||
equalizer (0.0.11)
|
||||
erubi (1.10.0)
|
||||
et-orbi (1.2.4)
|
||||
|
@ -205,12 +204,18 @@ GEM
|
|||
faraday (~> 1.0)
|
||||
fcm (1.0.2)
|
||||
faraday (~> 1.0.0)
|
||||
ffi (1.14.2)
|
||||
ffi (1.15.0)
|
||||
flag_shih_tzu (0.3.23)
|
||||
foreman (0.87.2)
|
||||
fugit (1.4.1)
|
||||
et-orbi (~> 1.1, >= 1.1.8)
|
||||
raabro (~> 1.4)
|
||||
gapic-common (0.3.4)
|
||||
google-protobuf (~> 3.12, >= 3.12.2)
|
||||
googleapis-common-protos (>= 1.3.9, < 2.0)
|
||||
googleapis-common-protos-types (>= 1.0.4, < 2.0)
|
||||
googleauth (~> 0.9)
|
||||
grpc (~> 1.25)
|
||||
geocoder (1.6.3)
|
||||
gli (2.19.2)
|
||||
globalid (0.4.2)
|
||||
|
@ -223,12 +228,18 @@ GEM
|
|||
representable (~> 3.0)
|
||||
retriable (>= 2.0, < 4.0)
|
||||
signet (~> 0.12)
|
||||
google-cloud-core (1.5.0)
|
||||
google-cloud-core (1.6.0)
|
||||
google-cloud-env (~> 1.0)
|
||||
google-cloud-errors (~> 1.0)
|
||||
google-cloud-env (1.3.3)
|
||||
google-cloud-dialogflow (1.2.0)
|
||||
google-cloud-core (~> 1.5)
|
||||
google-cloud-dialogflow-v2 (~> 0.1)
|
||||
google-cloud-dialogflow-v2 (0.6.4)
|
||||
gapic-common (~> 0.3)
|
||||
google-cloud-errors (~> 1.0)
|
||||
google-cloud-env (1.5.0)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
google-cloud-errors (1.0.1)
|
||||
google-cloud-errors (1.1.0)
|
||||
google-cloud-storage (1.28.0)
|
||||
addressable (~> 2.5)
|
||||
digest-crc (~> 0.4)
|
||||
|
@ -236,7 +247,14 @@ GEM
|
|||
google-cloud-core (~> 1.2)
|
||||
googleauth (~> 0.9)
|
||||
mini_mime (~> 1.0)
|
||||
googleauth (0.13.1)
|
||||
google-protobuf (3.15.8)
|
||||
googleapis-common-protos (1.3.11)
|
||||
google-protobuf (~> 3.14)
|
||||
googleapis-common-protos-types (>= 1.0.6, < 2.0)
|
||||
grpc (~> 1.27)
|
||||
googleapis-common-protos-types (1.0.6)
|
||||
google-protobuf (~> 3.14)
|
||||
googleauth (0.16.2)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
jwt (>= 1.4, < 3.0)
|
||||
memoist (~> 0.16)
|
||||
|
@ -245,12 +263,15 @@ GEM
|
|||
signet (~> 0.14)
|
||||
groupdate (5.1.0)
|
||||
activesupport (>= 5)
|
||||
grpc (1.37.1)
|
||||
google-protobuf (~> 3.15)
|
||||
googleapis-common-protos-types (~> 1.0)
|
||||
haikunator (1.1.0)
|
||||
hairtrigger (0.2.23)
|
||||
activerecord (>= 5.0, < 7)
|
||||
ruby2ruby (~> 2.4)
|
||||
ruby_parser (~> 3.10)
|
||||
hana (1.3.6)
|
||||
hana (1.3.7)
|
||||
hashdiff (1.0.1)
|
||||
hashie (4.1.0)
|
||||
hkdf (0.3.0)
|
||||
|
@ -261,7 +282,7 @@ GEM
|
|||
mime-types (~> 3.0)
|
||||
multi_xml (>= 0.5.2)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.8.9)
|
||||
i18n (1.8.10)
|
||||
concurrent-ruby (~> 1.0)
|
||||
ice_nine (0.11.2)
|
||||
inflecto (0.0.2)
|
||||
|
@ -273,7 +294,12 @@ GEM
|
|||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
json (2.3.1)
|
||||
jwt (2.2.2)
|
||||
json_schemer (0.2.16)
|
||||
ecma-re-validator (~> 0.2)
|
||||
hana (~> 1.3)
|
||||
regexp_parser (~> 1.5)
|
||||
uri_template (~> 0.7)
|
||||
jwt (2.2.3)
|
||||
kaminari (1.2.1)
|
||||
activesupport (>= 4.1.0)
|
||||
kaminari-actionview (= 1.2.1)
|
||||
|
@ -298,12 +324,12 @@ GEM
|
|||
listen (3.3.3)
|
||||
rb-fsevent (~> 0.10, >= 0.10.3)
|
||||
rb-inotify (~> 0.9, >= 0.9.10)
|
||||
loofah (2.9.0)
|
||||
loofah (2.9.1)
|
||||
crass (~> 1.0.2)
|
||||
nokogiri (>= 1.5.9)
|
||||
mail (2.7.1)
|
||||
mini_mime (>= 0.1.1)
|
||||
marcel (1.0.0)
|
||||
marcel (1.0.1)
|
||||
maxminddb (0.1.22)
|
||||
memoist (0.16.2)
|
||||
method_source (1.0.0)
|
||||
|
@ -311,8 +337,8 @@ GEM
|
|||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2020.0512)
|
||||
mini_magick (4.10.1)
|
||||
mini_mime (1.0.3)
|
||||
mini_portile2 (2.5.0)
|
||||
mini_mime (1.1.0)
|
||||
mini_portile2 (2.5.1)
|
||||
minitest (5.14.4)
|
||||
momentjs-rails (2.20.1)
|
||||
railties (>= 3.1)
|
||||
|
@ -324,22 +350,24 @@ GEM
|
|||
connection_pool (~> 2.2)
|
||||
netrc (0.11.0)
|
||||
nio4r (2.5.7)
|
||||
nokogiri (1.11.2)
|
||||
nokogiri (1.11.3)
|
||||
mini_portile2 (~> 2.5.0)
|
||||
racc (~> 1.4)
|
||||
oauth (0.5.4)
|
||||
oauth (0.5.6)
|
||||
orm_adapter (0.5.0)
|
||||
os (1.1.1)
|
||||
parallel (1.19.2)
|
||||
parser (2.7.1.4)
|
||||
ast (~> 2.4.1)
|
||||
pg (1.2.3)
|
||||
procore-sift (0.15.0)
|
||||
rails (> 4.2.0)
|
||||
pry (0.13.1)
|
||||
coderay (~> 1.1)
|
||||
method_source (~> 1.0)
|
||||
pry-rails (0.3.9)
|
||||
pry (>= 0.10.4)
|
||||
public_suffix (4.0.5)
|
||||
public_suffix (4.0.6)
|
||||
puma (4.3.6)
|
||||
nio4r (~> 2.0)
|
||||
pundit (2.1.0)
|
||||
|
@ -355,29 +383,29 @@ GEM
|
|||
rack
|
||||
rack-test (1.1.0)
|
||||
rack (>= 1.0, < 3)
|
||||
rails (6.0.3.6)
|
||||
actioncable (= 6.0.3.6)
|
||||
actionmailbox (= 6.0.3.6)
|
||||
actionmailer (= 6.0.3.6)
|
||||
actionpack (= 6.0.3.6)
|
||||
actiontext (= 6.0.3.6)
|
||||
actionview (= 6.0.3.6)
|
||||
activejob (= 6.0.3.6)
|
||||
activemodel (= 6.0.3.6)
|
||||
activerecord (= 6.0.3.6)
|
||||
activestorage (= 6.0.3.6)
|
||||
activesupport (= 6.0.3.6)
|
||||
rails (6.0.3.7)
|
||||
actioncable (= 6.0.3.7)
|
||||
actionmailbox (= 6.0.3.7)
|
||||
actionmailer (= 6.0.3.7)
|
||||
actionpack (= 6.0.3.7)
|
||||
actiontext (= 6.0.3.7)
|
||||
actionview (= 6.0.3.7)
|
||||
activejob (= 6.0.3.7)
|
||||
activemodel (= 6.0.3.7)
|
||||
activerecord (= 6.0.3.7)
|
||||
activestorage (= 6.0.3.7)
|
||||
activesupport (= 6.0.3.7)
|
||||
bundler (>= 1.3.0)
|
||||
railties (= 6.0.3.6)
|
||||
railties (= 6.0.3.7)
|
||||
sprockets-rails (>= 2.0.0)
|
||||
rails-dom-testing (2.0.3)
|
||||
activesupport (>= 4.2.0)
|
||||
nokogiri (>= 1.6)
|
||||
rails-html-sanitizer (1.3.0)
|
||||
loofah (~> 2.3)
|
||||
railties (6.0.3.6)
|
||||
actionpack (= 6.0.3.6)
|
||||
activesupport (= 6.0.3.6)
|
||||
railties (6.0.3.7)
|
||||
actionpack (= 6.0.3.7)
|
||||
activesupport (= 6.0.3.7)
|
||||
method_source
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.20.3, < 2.0)
|
||||
|
@ -408,7 +436,7 @@ GEM
|
|||
mime-types (>= 1.16, < 4.0)
|
||||
netrc (~> 0.8)
|
||||
retriable (3.1.2)
|
||||
rexml (3.2.4)
|
||||
rexml (3.2.5)
|
||||
rspec-core (3.9.2)
|
||||
rspec-support (~> 3.9.3)
|
||||
rspec-expectations (3.9.2)
|
||||
|
@ -489,7 +517,7 @@ GEM
|
|||
sidekiq-cron (1.2.0)
|
||||
fugit (~> 1.1)
|
||||
sidekiq (>= 4.2.1)
|
||||
signet (0.14.0)
|
||||
signet (0.15.0)
|
||||
addressable (~> 2.3)
|
||||
faraday (>= 0.17.3, < 2.0)
|
||||
jwt (>= 1.5, < 3.0)
|
||||
|
@ -547,6 +575,7 @@ GEM
|
|||
unf_ext (0.0.7.7)
|
||||
unicode-display_width (1.7.0)
|
||||
uniform_notifier (1.13.0)
|
||||
uri_template (0.7.0)
|
||||
valid_email2 (3.3.1)
|
||||
activemodel (>= 3.2)
|
||||
mail (~> 2.5)
|
||||
|
@ -612,6 +641,7 @@ DEPENDENCIES
|
|||
flag_shih_tzu
|
||||
foreman
|
||||
geocoder
|
||||
google-cloud-dialogflow
|
||||
google-cloud-storage
|
||||
groupdate
|
||||
haikunator
|
||||
|
@ -619,6 +649,7 @@ DEPENDENCIES
|
|||
hashie
|
||||
jbuilder
|
||||
json_refs!
|
||||
json_schemer
|
||||
jwt
|
||||
kaminari
|
||||
koala
|
||||
|
@ -629,6 +660,7 @@ DEPENDENCIES
|
|||
mini_magick
|
||||
mock_redis!
|
||||
pg
|
||||
procore-sift
|
||||
pry-rails
|
||||
puma
|
||||
pundit
|
||||
|
|
38
app/builders/campaigns/campaign_conversation_builder.rb
Normal file
38
app/builders/campaigns/campaign_conversation_builder.rb
Normal file
|
@ -0,0 +1,38 @@
|
|||
class Campaigns::CampaignConversationBuilder
|
||||
pattr_initialize [:contact_inbox_id!, :campaign_display_id!, :conversation_additional_attributes]
|
||||
|
||||
def perform
|
||||
@contact_inbox = ContactInbox.find(@contact_inbox_id)
|
||||
@campaign = @contact_inbox.inbox.campaigns.find_by!(display_id: campaign_display_id)
|
||||
|
||||
ActiveRecord::Base.transaction do
|
||||
@contact_inbox.lock!
|
||||
|
||||
# We won't send campaigns if a conversation is already present
|
||||
return if @contact_inbox.reload.conversations.present?
|
||||
|
||||
@conversation = ::Conversation.create!(conversation_params)
|
||||
Messages::MessageBuilder.new(@campaign.sender, @conversation, message_params).perform
|
||||
end
|
||||
@conversation
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def message_params
|
||||
ActionController::Parameters.new({
|
||||
content: @campaign.message
|
||||
})
|
||||
end
|
||||
|
||||
def conversation_params
|
||||
{
|
||||
account_id: @campaign.account_id,
|
||||
inbox_id: @contact_inbox.inbox_id,
|
||||
contact_id: @contact_inbox.contact_id,
|
||||
contact_inbox_id: @contact_inbox.id,
|
||||
campaign_id: @campaign.id,
|
||||
additional_attributes: conversation_additional_attributes
|
||||
}
|
||||
end
|
||||
end
|
28
app/controllers/api/v1/accounts/campaigns_controller.rb
Normal file
28
app/controllers/api/v1/accounts/campaigns_controller.rb
Normal file
|
@ -0,0 +1,28 @@
|
|||
class Api::V1::Accounts::CampaignsController < Api::V1::Accounts::BaseController
|
||||
before_action :campaign, except: [:index, :create]
|
||||
before_action :check_authorization
|
||||
|
||||
def index
|
||||
@campaigns = Current.account.campaigns
|
||||
end
|
||||
|
||||
def create
|
||||
@campaign = Current.account.campaigns.create!(campaign_params)
|
||||
end
|
||||
|
||||
def show; end
|
||||
|
||||
def update
|
||||
@campaign.update(campaign_params)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def campaign
|
||||
@campaign ||= Current.account.campaigns.find_by(display_id: params[:id])
|
||||
end
|
||||
|
||||
def campaign_params
|
||||
params.require(:campaign).permit(:title, :description, :message, :enabled, :inbox_id, :sender_id, trigger_rules: {})
|
||||
end
|
||||
end
|
|
@ -1,4 +1,11 @@
|
|||
class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController
|
||||
include Sift
|
||||
|
||||
sort_on :email, type: :string
|
||||
sort_on :name, type: :string
|
||||
sort_on :phone_number, type: :string
|
||||
sort_on :last_activity_at, type: :datetime
|
||||
|
||||
RESULTS_PER_PAGE = 15
|
||||
protect_from_forgery with: :null_session
|
||||
|
||||
|
@ -68,7 +75,6 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController
|
|||
@resolved_contacts ||= Current.account.contacts
|
||||
.where.not(email: [nil, ''])
|
||||
.or(Current.account.contacts.where.not(phone_number: [nil, '']))
|
||||
.order('LOWER(name)')
|
||||
end
|
||||
|
||||
def set_current_page
|
||||
|
@ -76,11 +82,11 @@ class Api::V1::Accounts::ContactsController < Api::V1::Accounts::BaseController
|
|||
end
|
||||
|
||||
def fetch_contact_last_seen_at(contacts)
|
||||
contacts.left_outer_joins(:conversations)
|
||||
.select('contacts.*, COUNT(conversations.id) as conversations_count, MAX(conversations.contact_last_seen_at) as last_seen_at')
|
||||
.group('contacts.id')
|
||||
.includes([{ avatar_attachment: [:blob] }, { contact_inboxes: [:inbox] }])
|
||||
.page(@current_page).per(RESULTS_PER_PAGE)
|
||||
filtrate(contacts).left_outer_joins(:conversations)
|
||||
.select('contacts.*, COUNT(conversations.id) as conversations_count')
|
||||
.group('contacts.id')
|
||||
.includes([{ avatar_attachment: [:blob] }, { contact_inboxes: [:inbox] }])
|
||||
.page(@current_page).per(RESULTS_PER_PAGE)
|
||||
end
|
||||
|
||||
def build_contact_inbox
|
||||
|
|
|
@ -11,6 +11,10 @@ class Api::V1::Accounts::InboxesController < Api::V1::Accounts::BaseController
|
|||
@assignable_agents = (Current.account.users.where(id: @inbox.members.select(:user_id)) + Current.account.administrators).uniq
|
||||
end
|
||||
|
||||
def campaigns
|
||||
@campaigns = @inbox.campaigns
|
||||
end
|
||||
|
||||
def create
|
||||
ActiveRecord::Base.transaction do
|
||||
channel = create_channel
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
class Api::V1::Accounts::Integrations::HooksController < Api::V1::Accounts::BaseController
|
||||
before_action :fetch_hook, only: [:update, :destroy]
|
||||
before_action :check_authorization
|
||||
|
||||
def create
|
||||
@hook = Current.account.hooks.create!(permitted_params)
|
||||
end
|
||||
|
||||
def update
|
||||
@hook.update!(permitted_params.slice(:status, :settings))
|
||||
end
|
||||
|
||||
def destroy
|
||||
@hook.destroy
|
||||
head :ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def fetch_hook
|
||||
@hook = Current.account.hooks.find(params[:id])
|
||||
end
|
||||
|
||||
def check_authorization
|
||||
authorize(:hook)
|
||||
end
|
||||
|
||||
def permitted_params
|
||||
params.require(:hook).permit(:app_id, :inbox_id, :status, settings: {})
|
||||
end
|
||||
end
|
13
app/controllers/api/v1/widget/campaigns_controller.rb
Normal file
13
app/controllers/api/v1/widget/campaigns_controller.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
class Api::V1::Widget::CampaignsController < Api::V1::Widget::BaseController
|
||||
skip_before_action :set_contact
|
||||
|
||||
def index
|
||||
@campaigns = @web_widget.inbox.campaigns.where(enabled: true)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def permitted_params
|
||||
params.permit(:website_token)
|
||||
end
|
||||
end
|
|
@ -2,7 +2,8 @@ class Api::V1::Widget::EventsController < Api::V1::Widget::BaseController
|
|||
include Events::Types
|
||||
|
||||
def create
|
||||
Rails.configuration.dispatcher.dispatch(permitted_params[:name], Time.zone.now, contact_inbox: @contact_inbox, event_info: event_info)
|
||||
Rails.configuration.dispatcher.dispatch(permitted_params[:name], Time.zone.now, contact_inbox: @contact_inbox,
|
||||
event_info: permitted_params[:event_info].to_h.merge(event_info))
|
||||
head :no_content
|
||||
end
|
||||
|
||||
|
@ -17,6 +18,6 @@ class Api::V1::Widget::EventsController < Api::V1::Widget::BaseController
|
|||
end
|
||||
|
||||
def permitted_params
|
||||
params.permit(:name, :website_token)
|
||||
params.permit(:name, :website_token, event_info: {})
|
||||
end
|
||||
end
|
||||
|
|
|
@ -12,7 +12,8 @@ class AsyncDispatcher < BaseDispatcher
|
|||
[
|
||||
EventListener.instance,
|
||||
WebhookListener.instance,
|
||||
InstallationWebhookListener.instance, HookListener.instance
|
||||
InstallationWebhookListener.instance, HookListener.instance,
|
||||
CampaignListener.instance
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
9
app/javascript/dashboard/api/campaigns.js
Normal file
9
app/javascript/dashboard/api/campaigns.js
Normal file
|
@ -0,0 +1,9 @@
|
|||
import ApiClient from './ApiClient';
|
||||
|
||||
class CampaignsAPI extends ApiClient {
|
||||
constructor() {
|
||||
super('campaigns', { accountScoped: true });
|
||||
}
|
||||
}
|
||||
|
||||
export default new CampaignsAPI();
|
|
@ -6,8 +6,8 @@ class ContactAPI extends ApiClient {
|
|||
super('contacts', { accountScoped: true });
|
||||
}
|
||||
|
||||
get(page) {
|
||||
return axios.get(`${this.url}?page=${page}`);
|
||||
get(page, sortAttr = 'name') {
|
||||
return axios.get(`${this.url}?page=${page}&sort=${sortAttr}`);
|
||||
}
|
||||
|
||||
getConversations(contactId) {
|
||||
|
@ -18,8 +18,10 @@ class ContactAPI extends ApiClient {
|
|||
return axios.get(`${this.url}/${contactId}/contactable_inboxes`);
|
||||
}
|
||||
|
||||
search(search = '', page = 1) {
|
||||
return axios.get(`${this.url}/search?q=${search}&page=${page}`);
|
||||
search(search = '', page = 1, sortAttr = 'name') {
|
||||
return axios.get(
|
||||
`${this.url}/search?q=${search}&page=${page}&sort=${sortAttr}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,9 +1,18 @@
|
|||
/* global axios */
|
||||
import ApiClient from './ApiClient';
|
||||
|
||||
class Inboxes extends ApiClient {
|
||||
constructor() {
|
||||
super('inboxes', { accountScoped: true });
|
||||
}
|
||||
|
||||
getAssignableAgents(inboxId) {
|
||||
return axios.get(`${this.url}/${inboxId}/assignable_agents`);
|
||||
}
|
||||
|
||||
getCampaigns(inboxId) {
|
||||
return axios.get(`${this.url}/${inboxId}/campaigns`);
|
||||
}
|
||||
}
|
||||
|
||||
export default new Inboxes();
|
||||
|
|
13
app/javascript/dashboard/api/specs/campaign.spec.js
Normal file
13
app/javascript/dashboard/api/specs/campaign.spec.js
Normal file
|
@ -0,0 +1,13 @@
|
|||
import campaigns from '../campaigns';
|
||||
import ApiClient from '../ApiClient';
|
||||
|
||||
describe('#CampaignAPI', () => {
|
||||
it('creates correct instance', () => {
|
||||
expect(campaigns).toBeInstanceOf(ApiClient);
|
||||
expect(campaigns).toHaveProperty('get');
|
||||
expect(campaigns).toHaveProperty('show');
|
||||
expect(campaigns).toHaveProperty('create');
|
||||
expect(campaigns).toHaveProperty('update');
|
||||
expect(campaigns).toHaveProperty('delete');
|
||||
});
|
||||
});
|
|
@ -15,10 +15,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.label {
|
||||
font-weight: $font-weight-bold;
|
||||
}
|
||||
|
||||
.tooltip {
|
||||
border-radius: $space-smaller;
|
||||
font-size: $font-size-mini;
|
||||
|
|
|
@ -358,7 +358,7 @@ $form-label-font-weight: $font-weight-medium;
|
|||
$form-label-line-height: 1.8;
|
||||
$select-background: $white;
|
||||
$select-triangle-color: $dark-gray;
|
||||
$select-radius: $global-radius;
|
||||
$select-radius: var(--border-radius-normal);
|
||||
$input-color: $header-color;
|
||||
$input-placeholder-color: $light-gray;
|
||||
$input-font-family: inherit;
|
||||
|
@ -374,19 +374,19 @@ $input-shadow-focus: 0;
|
|||
$input-cursor-disabled: not-allowed;
|
||||
$input-transition: border-color 0.25s ease-in-out;
|
||||
$input-number-spinners: true;
|
||||
$input-radius: $global-radius;
|
||||
$form-button-radius: $global-radius;
|
||||
$input-radius: var(--border-radius-normal);
|
||||
$form-button-radius: var(--border-radius-normal);
|
||||
|
||||
// 20. Label
|
||||
// ---------
|
||||
|
||||
$label-background: lighten($primary-color, 40%);
|
||||
$label-color: $primary-color;
|
||||
$label-background: $primary-color;
|
||||
$label-color: $white;
|
||||
$label-color-alt: $black;
|
||||
$label-palette: $foundation-palette;
|
||||
$label-font-size: $font-size-micro;
|
||||
$label-font-size: $font-size-mini;
|
||||
$label-padding: $space-smaller $space-small;
|
||||
$label-radius: $space-micro;
|
||||
$label-radius: var(--border-radius-small);
|
||||
|
||||
// 21. Media Object
|
||||
// ----------------
|
||||
|
|
|
@ -51,25 +51,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
input,
|
||||
textarea,
|
||||
select {
|
||||
border-radius: var(--space-smaller) !important;
|
||||
}
|
||||
|
||||
.input-group {
|
||||
.input-group-label:first-child {
|
||||
border-bottom-left-radius: var(--space-smaller);
|
||||
border-top-left-radius: var(--space-smaller);
|
||||
}
|
||||
|
||||
.input-group-field {
|
||||
border-bottom-left-radius: 0 !important;
|
||||
border-top-left-radius: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
.justify-space-between {
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
|
|
@ -236,3 +236,11 @@ $spinner-before-border-color: rgba(255, 255, 255, 0.7);
|
|||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@mixin three-column-grid($column-one-width: 25.6rem,
|
||||
$column-three-width: 25.6rem) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: minmax($column-one-width, 6fr) 10fr minmax($column-three-width, 6fr);
|
||||
}
|
||||
|
|
27
app/javascript/dashboard/assets/scss/storybook.scss
Normal file
27
app/javascript/dashboard/assets/scss/storybook.scss
Normal file
|
@ -0,0 +1,27 @@
|
|||
@import 'shared/assets/fonts/inter';
|
||||
@import 'shared/assets/stylesheets/colors';
|
||||
@import 'shared/assets/stylesheets/spacing';
|
||||
@import 'shared/assets/stylesheets/font-size';
|
||||
@import 'shared/assets/stylesheets/font-weights';
|
||||
@import 'shared/assets/stylesheets/shadows';
|
||||
@import 'shared/assets/stylesheets/border-radius';
|
||||
@import 'variables';
|
||||
|
||||
@import '~spinkit/scss/spinners/7-three-bounce';
|
||||
@import '~shared/assets/stylesheets/ionicons';
|
||||
|
||||
@import 'mixins';
|
||||
@import 'foundation-settings';
|
||||
@import 'helper-classes';
|
||||
@import 'foundation-sites/scss/foundation';
|
||||
@import '~bourbon/core/bourbon';
|
||||
|
||||
@include foundation-everything($flex: true);
|
||||
|
||||
@import 'typography';
|
||||
@import 'layout';
|
||||
@import 'animations';
|
||||
|
||||
@import 'foundation-custom';
|
||||
@import 'widgets/buttons';
|
||||
@import 'widgets/forms';
|
|
@ -39,20 +39,25 @@ $resolve-button-width: 13.2rem;
|
|||
.user {
|
||||
@include flex;
|
||||
@include flex-align($x: center, $y: middle);
|
||||
margin-right: var(--space-normal);
|
||||
min-width: 0;
|
||||
|
||||
.user--name {
|
||||
@include margin(0);
|
||||
display: inline-block;
|
||||
font-size: $font-size-medium;
|
||||
line-height: 1.3;
|
||||
text-transform: capitalize;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.user--profile__meta {
|
||||
align-items: flex-start;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
justify-content: flex-start;
|
||||
margin-left: $space-slab;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.user--profile__button {
|
||||
|
|
|
@ -132,7 +132,6 @@
|
|||
|
||||
.bubble {
|
||||
@include bubble-with-types;
|
||||
max-width: 50rem;
|
||||
text-align: left;
|
||||
word-wrap: break-word;
|
||||
|
||||
|
@ -236,7 +235,9 @@
|
|||
|
||||
.wrap {
|
||||
@include margin($zero $space-normal);
|
||||
max-width: 69%;
|
||||
|
||||
--bubble-max-width: 49.6rem;
|
||||
max-width: Min(var(--bubble-max-width), 85%);
|
||||
|
||||
.sender--name {
|
||||
font-size: $font-size-mini;
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
.error {
|
||||
|
||||
#{$all-text-inputs},
|
||||
select,
|
||||
.multiselect > .multiselect__tags {
|
||||
.multiselect>.multiselect__tags {
|
||||
@include thin-border(var(--r-400));
|
||||
}
|
||||
|
||||
|
@ -33,3 +34,10 @@ input {
|
|||
.help-text {
|
||||
font-weight: $font-weight-normal;
|
||||
}
|
||||
|
||||
.input-group.small {
|
||||
input {
|
||||
font-size: var(--font-size-small);
|
||||
height: var(--space-large);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -116,7 +116,7 @@ export default {
|
|||
return this.$store.getters['inboxes/getInbox'](this.activeInbox);
|
||||
},
|
||||
currentPage() {
|
||||
return this.$store.getters['conversationPage/getCurrentPage'](
|
||||
return this.$store.getters['conversationPage/getCurrentPageFilter'](
|
||||
this.activeAssigneeTab
|
||||
);
|
||||
},
|
||||
|
@ -199,6 +199,7 @@ export default {
|
|||
},
|
||||
updateAssigneeTab(selectedTab) {
|
||||
if (this.activeAssigneeTab !== selectedTab) {
|
||||
bus.$emit('clearSearchInput');
|
||||
this.activeAssigneeTab = selectedTab;
|
||||
if (!this.currentPage) {
|
||||
this.fetchConversations();
|
||||
|
|
|
@ -6,8 +6,10 @@ import Button from './ui/WootButton';
|
|||
import Code from './Code';
|
||||
import ColorPicker from './widgets/ColorPicker';
|
||||
import DeleteModal from './widgets/modal/DeleteModal.vue';
|
||||
import DropdownItem from 'shared/components/ui/dropdown/DropdownItem';
|
||||
import DropdownMenu from 'shared/components/ui/dropdown/DropdownMenu';
|
||||
import Input from './widgets/forms/Input.vue';
|
||||
import Label from './widgets/Label.vue';
|
||||
import Label from './ui/Label';
|
||||
import LoadingState from './widgets/LoadingState';
|
||||
import Modal from './Modal';
|
||||
import ModalHeader from './ModalHeader';
|
||||
|
@ -26,6 +28,8 @@ const WootUIKit = {
|
|||
Code,
|
||||
ColorPicker,
|
||||
DeleteModal,
|
||||
DropdownItem,
|
||||
DropdownMenu,
|
||||
Input,
|
||||
LoadingState,
|
||||
Label,
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
<template>
|
||||
<div class="status">
|
||||
<div class="status-view">
|
||||
<div
|
||||
:class="`status-badge status-badge__${currentUserAvailabilityStatus}`"
|
||||
/>
|
||||
|
||||
<availability-status-badge :status="currentUserAvailabilityStatus" />
|
||||
<div class="status-view--title">
|
||||
{{ availabilityDisplayLabel }}
|
||||
</div>
|
||||
|
@ -23,22 +20,28 @@
|
|||
:key="status.value"
|
||||
class="status-items"
|
||||
>
|
||||
<button
|
||||
class="button clear status-change--dropdown-button"
|
||||
:disabled="status.disabled"
|
||||
<woot-button
|
||||
variant="clear"
|
||||
class-names="status-change--dropdown-button"
|
||||
:is-disabled="status.disabled"
|
||||
@click="changeAvailabilityStatus(status.value)"
|
||||
>
|
||||
<span :class="`status-badge status-badge__${status.value}`" />
|
||||
<availability-status-badge :status="status.value" />
|
||||
{{ status.label }}
|
||||
</button>
|
||||
</woot-button>
|
||||
</woot-dropdown-item>
|
||||
</woot-dropdown-menu>
|
||||
</div>
|
||||
</transition>
|
||||
|
||||
<button class="status-change--change-button" @click="openStatusMenu">
|
||||
<woot-button
|
||||
variant="clear"
|
||||
color-scheme="secondary"
|
||||
class-names="status-change--change-button link"
|
||||
@click="openStatusMenu"
|
||||
>
|
||||
{{ $t('SIDEBAR_ITEMS.CHANGE_AVAILABILITY_STATUS') }}
|
||||
</button>
|
||||
</woot-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -48,6 +51,7 @@ import { mapGetters } from 'vuex';
|
|||
import { mixin as clickaway } from 'vue-clickaway';
|
||||
import WootDropdownItem from 'shared/components/ui/dropdown/DropdownItem.vue';
|
||||
import WootDropdownMenu from 'shared/components/ui/dropdown/DropdownMenu.vue';
|
||||
import AvailabilityStatusBadge from '../widgets/conversation/AvailabilityStatusBadge';
|
||||
|
||||
const AVAILABILITY_STATUS_KEYS = ['online', 'busy', 'offline'];
|
||||
|
||||
|
@ -55,6 +59,7 @@ export default {
|
|||
components: {
|
||||
WootDropdownMenu,
|
||||
WootDropdownItem,
|
||||
AvailabilityStatusBadge,
|
||||
},
|
||||
|
||||
mixins: [clickaway],
|
||||
|
@ -147,26 +152,6 @@ export default {
|
|||
}
|
||||
}
|
||||
|
||||
.status-badge {
|
||||
width: var(--space-one);
|
||||
height: var(--space-one);
|
||||
margin-right: var(--space-micro);
|
||||
display: inline-block;
|
||||
border-radius: 50%;
|
||||
|
||||
&__online {
|
||||
background: var(--g-400);
|
||||
}
|
||||
|
||||
&__offline {
|
||||
background: var(--b-600);
|
||||
}
|
||||
|
||||
&__busy {
|
||||
background: var(--y-700);
|
||||
}
|
||||
}
|
||||
|
||||
.status-change {
|
||||
.dropdown-pane {
|
||||
top: -132px;
|
||||
|
@ -177,15 +162,5 @@ export default {
|
|||
display: flex;
|
||||
align-items: baseline;
|
||||
}
|
||||
& &--change-button {
|
||||
color: var(--b-600);
|
||||
font-size: var(--font-size-small);
|
||||
cursor: pointer;
|
||||
outline: none;
|
||||
|
||||
&:hover {
|
||||
color: var(--w-600);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -144,6 +144,7 @@ export default {
|
|||
cssClass: 'menu-title align-justify',
|
||||
toState: frontendURL(`accounts/${this.accountId}/settings/inboxes`),
|
||||
toStateName: 'settings_inbox_list',
|
||||
newLinkRouteName: 'settings_inbox_new',
|
||||
children: this.inboxes.map(inbox => ({
|
||||
id: inbox.id,
|
||||
label: inbox.name,
|
||||
|
@ -158,10 +159,13 @@ export default {
|
|||
icon: 'ion-pound',
|
||||
label: 'LABELS',
|
||||
hasSubMenu: true,
|
||||
newLink: true,
|
||||
key: 'label',
|
||||
cssClass: 'menu-title align-justify',
|
||||
toState: frontendURL(`accounts/${this.accountId}/settings/labels`),
|
||||
toStateName: 'labels_list',
|
||||
showModalForNewItem: true,
|
||||
modalName: 'AddLabel',
|
||||
children: this.accountLabels.map(label => ({
|
||||
id: label.id,
|
||||
label: label.title,
|
||||
|
@ -178,10 +182,12 @@ export default {
|
|||
icon: 'ion-ios-people',
|
||||
label: 'TEAMS',
|
||||
hasSubMenu: true,
|
||||
newLink: true,
|
||||
key: 'team',
|
||||
cssClass: 'menu-title align-justify teams-sidebar-menu',
|
||||
toState: frontendURL(`accounts/${this.accountId}/settings/teams`),
|
||||
toStateName: 'teams_list',
|
||||
newLinkRouteName: 'settings_teams_new',
|
||||
children: this.teams.map(team => ({
|
||||
id: team.id,
|
||||
label: team.name,
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
<span
|
||||
v-if="showItem(menuItem)"
|
||||
class="child-icon ion-android-add-circle"
|
||||
@click.prevent="newLinkClick"
|
||||
@click.prevent="newLinkClick(menuItem)"
|
||||
/>
|
||||
</a>
|
||||
<ul v-if="menuItem.hasSubMenu" class="nested vertical menu">
|
||||
|
@ -52,6 +52,11 @@
|
|||
</a>
|
||||
</router-link>
|
||||
</ul>
|
||||
<add-label-modal
|
||||
v-if="showAddLabel"
|
||||
:show.sync="showAddLabel"
|
||||
:on-close="hideAddLabelPopup"
|
||||
/>
|
||||
</router-link>
|
||||
</template>
|
||||
|
||||
|
@ -61,8 +66,17 @@ import { mapGetters } from 'vuex';
|
|||
import router from '../../routes';
|
||||
import adminMixin from '../../mixins/isAdmin';
|
||||
import { getInboxClassByType } from 'dashboard/helper/inbox';
|
||||
import AddLabelModal from '../../routes/dashboard/settings/labels/AddLabel';
|
||||
export default {
|
||||
components: {
|
||||
AddLabelModal,
|
||||
},
|
||||
mixins: [adminMixin],
|
||||
data() {
|
||||
return {
|
||||
showAddLabel: false,
|
||||
};
|
||||
},
|
||||
props: {
|
||||
menuItem: {
|
||||
type: Object,
|
||||
|
@ -108,12 +122,24 @@ export default {
|
|||
if (!child.truncateLabel) return false;
|
||||
return child.label;
|
||||
},
|
||||
newLinkClick() {
|
||||
router.push({ name: 'settings_inbox_new', params: { page: 'new' } });
|
||||
newLinkClick(item) {
|
||||
if (item.newLinkRouteName) {
|
||||
router.push({ name: item.newLinkRouteName, params: { page: 'new' } });
|
||||
} else if (item.showModalForNewItem) {
|
||||
if (item.modalName === 'AddLabel') {
|
||||
this.showAddLabelPopup();
|
||||
}
|
||||
}
|
||||
},
|
||||
showItem(item) {
|
||||
return this.isAdmin && item.newLink !== undefined;
|
||||
},
|
||||
showAddLabelPopup() {
|
||||
this.showAddLabel = true;
|
||||
},
|
||||
hideAddLabelPopup() {
|
||||
this.showAddLabel = false;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
|
|
@ -3,11 +3,13 @@ import { createLocalVue, mount } from '@vue/test-utils';
|
|||
import Vuex from 'vuex';
|
||||
import VueI18n from 'vue-i18n';
|
||||
|
||||
import WootButton from 'dashboard/components/ui/WootButton';
|
||||
import i18n from 'dashboard/i18n';
|
||||
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(Vuex);
|
||||
localVue.use(VueI18n);
|
||||
localVue.component('woot-button', WootButton);
|
||||
|
||||
const i18nConfig = new VueI18n({
|
||||
locale: 'en',
|
||||
|
|
|
@ -4,7 +4,7 @@ import SidemenuIcon from '../SidemenuIcon';
|
|||
describe('SidemenuIcon', () => {
|
||||
test('matches snapshot', () => {
|
||||
const wrapper = mount(SidemenuIcon);
|
||||
expect(wrapper.isVueInstance()).toBeTruthy();
|
||||
expect(wrapper.vm).toBeTruthy();
|
||||
expect(wrapper.element).toMatchSnapshot();
|
||||
});
|
||||
});
|
||||
|
|
149
app/javascript/dashboard/components/ui/Label.vue
Normal file
149
app/javascript/dashboard/components/ui/Label.vue
Normal file
|
@ -0,0 +1,149 @@
|
|||
<template>
|
||||
<div :class="labelClass" :style="labelStyle" :title="description">
|
||||
<i v-if="icon" class="label--icon" :class="icon" @click="onClick" />
|
||||
<span v-if="!href">{{ title }}</span>
|
||||
<a v-else :href="href" :style="anchorStyle">{{ title }}</a>
|
||||
<i v-if="showClose" class="close--icon ion-close" @click="onClick" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getContrastingTextColor } from 'shared/helpers/ColorHelper';
|
||||
export default {
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
href: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
small: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
showClose: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
colorScheme: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
textColor() {
|
||||
return getContrastingTextColor(this.bgColor);
|
||||
},
|
||||
labelClass() {
|
||||
return `label ${this.colorScheme} ${this.small ? 'small' : ''}`;
|
||||
},
|
||||
labelStyle() {
|
||||
if (this.bgColor) {
|
||||
return { background: this.bgColor, color: this.textColor };
|
||||
}
|
||||
return {};
|
||||
},
|
||||
anchorStyle() {
|
||||
if (this.bgColor) {
|
||||
return { color: this.textColor };
|
||||
}
|
||||
return {};
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onClick() {
|
||||
this.$emit('click', this.title);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '~dashboard/assets/scss/variables';
|
||||
|
||||
.label {
|
||||
font-weight: var(--font-weight-medium);
|
||||
margin-right: var(--space-smaller);
|
||||
margin-bottom: var(--space-smaller);
|
||||
|
||||
&.small {
|
||||
font-size: var(--font-size-micro);
|
||||
}
|
||||
|
||||
.label--icon {
|
||||
cursor: pointer;
|
||||
}
|
||||
.label--icon,
|
||||
.close--icon {
|
||||
font-size: var(--font-size-micro);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
&.small .label--icon,
|
||||
&.small .close--icon {
|
||||
font-size: var(--font-size-nano);
|
||||
}
|
||||
|
||||
a {
|
||||
font-size: var(--font-size-mini);
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
/* Color Schemes */
|
||||
&.primary {
|
||||
background: var(--w-100);
|
||||
color: var(--w-900);
|
||||
border: 1px solid var(--w-200);
|
||||
a {
|
||||
color: var(--w-900);
|
||||
}
|
||||
}
|
||||
&.secondary {
|
||||
background: var(--s-100);
|
||||
color: var(--s-900);
|
||||
border: 1px solid var(--s-200);
|
||||
a {
|
||||
color: var(--s-900);
|
||||
}
|
||||
}
|
||||
&.success {
|
||||
background: var(--g-100);
|
||||
color: var(--g-900);
|
||||
border: 1px solid var(--g-200);
|
||||
a {
|
||||
color: var(--g-900);
|
||||
}
|
||||
}
|
||||
&.alert {
|
||||
background: var(--r-100);
|
||||
color: var(--r-900);
|
||||
border: 1px solid var(--r-200);
|
||||
a {
|
||||
color: var(--r-900);
|
||||
}
|
||||
}
|
||||
&.warning {
|
||||
background: var(--y-100);
|
||||
color: var(--y-900);
|
||||
border: 1px solid var(--y-300);
|
||||
a {
|
||||
color: var(--y-900);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -0,0 +1,50 @@
|
|||
import { action } from '@storybook/addon-actions';
|
||||
import WootButton from '../WootButton.vue';
|
||||
|
||||
export default {
|
||||
title: 'Components/Button',
|
||||
component: WootButton,
|
||||
argTypes: {
|
||||
colorScheme: {
|
||||
control: {
|
||||
type: 'select',
|
||||
options: ['primary', 'secondary', 'success', 'alert', 'warning'],
|
||||
},
|
||||
},
|
||||
size: {
|
||||
control: {
|
||||
type: 'select',
|
||||
options: ['tiny', 'small', 'medium', 'large', 'expanded'],
|
||||
},
|
||||
},
|
||||
variant: {
|
||||
control: {
|
||||
type: 'select',
|
||||
options: ['hollow', 'clear'],
|
||||
},
|
||||
},
|
||||
isLoading: {
|
||||
control: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
isDisabled: {
|
||||
control: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const Template = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
components: { WootButton },
|
||||
template:
|
||||
'<woot-button v-bind="$props" @click="onClick">{{label}}</woot-button>',
|
||||
});
|
||||
|
||||
export const Primary = Template.bind({});
|
||||
Primary.args = {
|
||||
label: 'New message',
|
||||
onClick: action('Hello'),
|
||||
};
|
|
@ -0,0 +1,64 @@
|
|||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
export default {
|
||||
title: 'Components/Label',
|
||||
argTypes: {
|
||||
title: {
|
||||
defaultValue: 'sales',
|
||||
control: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
colorScheme: {
|
||||
control: {
|
||||
type: 'select',
|
||||
options: ['primary', 'secondary', 'success', 'alert', 'warning'],
|
||||
},
|
||||
},
|
||||
description: {
|
||||
defaultValue: 'label',
|
||||
control: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
href: {
|
||||
control: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
bgColor: {
|
||||
defaultValue: '#a83262',
|
||||
control: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
small: {
|
||||
defaultValue: false,
|
||||
control: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
showClose: {
|
||||
defaultValue: false,
|
||||
control: {
|
||||
type: 'boolean',
|
||||
},
|
||||
},
|
||||
icon: {
|
||||
defaultValue: 'ion-close',
|
||||
control: {
|
||||
type: 'text',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const Template = (args, { argTypes }) => ({
|
||||
props: Object.keys(argTypes),
|
||||
template: '<woot-label v-bind="$props" @click="onClick"></woot-label>',
|
||||
});
|
||||
|
||||
export const DefaultLabel = Template.bind({});
|
||||
DefaultLabel.args = {
|
||||
onClick: action('clicked'),
|
||||
};
|
|
@ -1,87 +0,0 @@
|
|||
<template>
|
||||
<div
|
||||
:class="labelClass"
|
||||
:style="{ background: bgColor, color: textColor }"
|
||||
:title="description"
|
||||
>
|
||||
<span v-if="!href">{{ title }}</span>
|
||||
<a v-else :href="href" :style="{ color: textColor }">{{ title }}</a>
|
||||
<i v-if="showIcon" class="label--icon" :class="icon" @click="onClick" />
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getContrastingTextColor } from 'shared/helpers/ColorHelper';
|
||||
export default {
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
description: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
href: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
bgColor: {
|
||||
type: String,
|
||||
default: '#1f93ff',
|
||||
},
|
||||
small: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
showIcon: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
icon: {
|
||||
type: String,
|
||||
default: 'ion-close',
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
textColor() {
|
||||
return getContrastingTextColor(this.bgColor);
|
||||
},
|
||||
labelClass() {
|
||||
return `label ${this.small ? 'small' : ''}`;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onClick() {
|
||||
this.$emit('click', this.title);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '~dashboard/assets/scss/variables';
|
||||
|
||||
.label {
|
||||
display: inline-block;
|
||||
font-size: $font-size-small;
|
||||
line-height: 1;
|
||||
margin: $space-micro;
|
||||
|
||||
&.small {
|
||||
font-size: $font-size-mini;
|
||||
}
|
||||
|
||||
a {
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.label--icon {
|
||||
cursor: pointer;
|
||||
font-size: $font-size-micro;
|
||||
line-height: 1.5;
|
||||
margin-left: $space-smaller;
|
||||
}
|
||||
</style>
|
|
@ -12,39 +12,41 @@
|
|||
v-if="totalCount"
|
||||
class="primary button-group pagination-button-group"
|
||||
>
|
||||
<button
|
||||
class="button small goto-first"
|
||||
:class="firstPageButtonClass"
|
||||
<woot-button
|
||||
size="small"
|
||||
class-names="goto-first"
|
||||
:is-disabled="hasFirstPage"
|
||||
@click="onFirstPage"
|
||||
>
|
||||
<i class="ion-chevron-left" />
|
||||
<i class="ion-chevron-left" />
|
||||
</button>
|
||||
<button
|
||||
class="button small"
|
||||
:class="prevPageButtonClass"
|
||||
</woot-button>
|
||||
<woot-button
|
||||
size="small"
|
||||
:is-disabled="hasPrevPage"
|
||||
@click="onPrevPage"
|
||||
>
|
||||
<i class="ion-chevron-left" />
|
||||
</button>
|
||||
<button class="button" @click.prevent>
|
||||
</woot-button>
|
||||
<woot-button @click.prevent>
|
||||
{{ currentPage }}
|
||||
</button>
|
||||
<button
|
||||
class="button small"
|
||||
:class="nextPageButtonClass"
|
||||
</woot-button>
|
||||
<woot-button
|
||||
size="small"
|
||||
:is-disabled="hasNextPage"
|
||||
@click="onNextPage"
|
||||
>
|
||||
<i class="ion-chevron-right" />
|
||||
</button>
|
||||
<button
|
||||
class="button small goto-last"
|
||||
:class="lastPageButtonClass"
|
||||
</woot-button>
|
||||
<woot-button
|
||||
size="small"
|
||||
class-names="goto-last"
|
||||
:is-disabled="hasLastPage"
|
||||
@click="onLastPage"
|
||||
>
|
||||
<i class="ion-chevron-right" />
|
||||
<i class="ion-chevron-right" />
|
||||
</button>
|
||||
</woot-button>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
@ -91,35 +93,19 @@ export default {
|
|||
this.currentPage === Math.ceil(this.totalCount / this.pageSize);
|
||||
return isDisabled;
|
||||
},
|
||||
lastPageButtonClass() {
|
||||
const className = this.hasLastPage ? 'disabled' : '';
|
||||
return className;
|
||||
},
|
||||
hasFirstPage() {
|
||||
const isDisabled = this.currentPage === 1;
|
||||
return isDisabled;
|
||||
},
|
||||
firstPageButtonClass() {
|
||||
const className = this.hasFirstPage ? 'disabled' : '';
|
||||
return className;
|
||||
},
|
||||
hasNextPage() {
|
||||
const isDisabled =
|
||||
this.currentPage === Math.ceil(this.totalCount / this.pageSize);
|
||||
return isDisabled;
|
||||
},
|
||||
nextPageButtonClass() {
|
||||
const className = this.hasNextPage ? 'disabled' : '';
|
||||
return className;
|
||||
},
|
||||
hasPrevPage() {
|
||||
const isDisabled = this.currentPage === 1;
|
||||
return isDisabled;
|
||||
},
|
||||
prevPageButtonClass() {
|
||||
const className = this.hasPrevPage ? 'disabled' : '';
|
||||
return className;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
onNextPage() {
|
||||
|
|
|
@ -14,12 +14,12 @@ const chartOptions = {
|
|||
scales: {
|
||||
xAxes: [
|
||||
{
|
||||
barPercentage: 1.26,
|
||||
barPercentage: 1.1,
|
||||
ticks: {
|
||||
fontFamily,
|
||||
},
|
||||
gridLines: {
|
||||
display: false,
|
||||
drawOnChartArea: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
@ -30,7 +30,7 @@ const chartOptions = {
|
|||
beginAtZero: true,
|
||||
},
|
||||
gridLines: {
|
||||
display: false,
|
||||
drawOnChartArea: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<template>
|
||||
<div :class="`status-badge status-badge__${status}`" />
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
status: { type: String, default: '' },
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
@import '~dashboard/assets/scss/variables';
|
||||
.status-badge {
|
||||
width: var(--space-one);
|
||||
height: var(--space-one);
|
||||
margin-right: var(--space-micro);
|
||||
display: inline-block;
|
||||
border-radius: 50%;
|
||||
&__online {
|
||||
background: var(--g-400);
|
||||
}
|
||||
&__offline {
|
||||
background: var(--b-600);
|
||||
}
|
||||
&__busy {
|
||||
background: var(--y-700);
|
||||
}
|
||||
}
|
||||
</style>
|
|
@ -63,7 +63,7 @@ export default {
|
|||
watch: {
|
||||
'currentChat.inbox_id'(inboxId) {
|
||||
if (inboxId) {
|
||||
this.$store.dispatch('inboxMembers/fetch', { inboxId });
|
||||
this.$store.dispatch('inboxAssignableAgents/fetch', { inboxId });
|
||||
}
|
||||
},
|
||||
},
|
||||
|
@ -80,6 +80,7 @@ export default {
|
|||
.conversation-details-wrap {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
border-left: 1px solid var(--color-border);
|
||||
background: var(--color-background-light);
|
||||
|
|
|
@ -30,11 +30,13 @@
|
|||
<span v-if="lastMessageInChat.content">
|
||||
{{ parsedLastMessage }}
|
||||
</span>
|
||||
<span v-else-if="!lastMessageInChat.attachments">{{ ` ` }}</span>
|
||||
<span v-else>
|
||||
<span v-else-if="lastMessageInChat.attachments">
|
||||
<i :class="`small-icon ${this.$t(`${attachmentIconKey}.ICON`)}`"></i>
|
||||
{{ this.$t(`${attachmentIconKey}.CONTENT`) }}
|
||||
</span>
|
||||
<span v-else>
|
||||
{{ $t('CHAT_LIST.NO_CONTENT') }}
|
||||
</span>
|
||||
</p>
|
||||
<p v-else class="conversation--message">
|
||||
<i class="ion-android-alert"></i>
|
||||
|
|
|
@ -46,6 +46,14 @@
|
|||
@select="assignAgent"
|
||||
@remove="removeAgent"
|
||||
>
|
||||
<template slot="option" slot-scope="props">
|
||||
<div class="option__desc">
|
||||
<availability-status-badge
|
||||
:status="props.option.availability_status"
|
||||
/>
|
||||
<span class="option__title">{{ props.option.name }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<span slot="noResult">{{ $t('AGENT_MGMT.SEARCH.NO_RESULTS') }}</span>
|
||||
</multiselect>
|
||||
</div>
|
||||
|
@ -57,11 +65,13 @@
|
|||
import { mapGetters } from 'vuex';
|
||||
import MoreActions from './MoreActions';
|
||||
import Thumbnail from '../Thumbnail';
|
||||
import AvailabilityStatusBadge from '../conversation/AvailabilityStatusBadge';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
MoreActions,
|
||||
Thumbnail,
|
||||
AvailabilityStatusBadge,
|
||||
},
|
||||
|
||||
props: {
|
||||
|
@ -83,8 +93,8 @@ export default {
|
|||
|
||||
computed: {
|
||||
...mapGetters({
|
||||
getAgents: 'inboxMembers/getMembersByInbox',
|
||||
uiFlags: 'inboxMembers/getUIFlags',
|
||||
getAgents: 'inboxAssignableAgents/getAssignableAgents',
|
||||
uiFlags: 'inboxAssignableAgents/getUIFlags',
|
||||
currentChat: 'getSelectedChat',
|
||||
}),
|
||||
|
||||
|
@ -126,7 +136,6 @@ export default {
|
|||
bus.$emit('newToastMessage', this.$t('CONVERSATION.CHANGE_AGENT'));
|
||||
});
|
||||
},
|
||||
|
||||
removeAgent() {},
|
||||
},
|
||||
};
|
||||
|
@ -142,4 +151,17 @@ export default {
|
|||
.conv-header {
|
||||
flex: 0 0 var(--space-jumbo);
|
||||
}
|
||||
|
||||
.option__desc {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.option__desc {
|
||||
&::v-deep .status-badge {
|
||||
margin-right: var(--space-small);
|
||||
min-width: 0;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
|
@ -109,12 +109,14 @@ export default {
|
|||
);
|
||||
|
||||
const {
|
||||
email: { html_content: { full: fullHTMLContent } = {} } = {},
|
||||
email: {
|
||||
html_content: { full: fullHTMLContent, reply: replyHTMLContent } = {},
|
||||
} = {},
|
||||
} = this.contentAttributes;
|
||||
|
||||
if (fullHTMLContent && this.isIncoming) {
|
||||
if ((replyHTMLContent || fullHTMLContent) && this.isIncoming) {
|
||||
let parsedContent = new DOMParser().parseFromString(
|
||||
fullHTMLContent || '',
|
||||
replyHTMLContent || fullHTMLContent || '',
|
||||
'text/html'
|
||||
);
|
||||
if (!parsedContent.getElementsByTagName('parsererror').length) {
|
||||
|
|
|
@ -186,10 +186,12 @@ export default {
|
|||
if (this.isPrivate) {
|
||||
return MESSAGE_MAX_LENGTH.GENERAL;
|
||||
}
|
||||
|
||||
if (this.isAFacebookInbox) {
|
||||
return MESSAGE_MAX_LENGTH.FACEBOOK;
|
||||
}
|
||||
if (this.isATwilioWhatsappChannel) {
|
||||
return MESSAGE_MAX_LENGTH.TWILIO_WHATSAPP;
|
||||
}
|
||||
if (this.isATwilioSMSChannel) {
|
||||
return MESSAGE_MAX_LENGTH.TWILIO_SMS;
|
||||
}
|
||||
|
|
|
@ -10,8 +10,7 @@ class ActionCableConnector extends BaseActionCableConnector {
|
|||
'message.created': this.onMessageCreated,
|
||||
'message.updated': this.onMessageUpdated,
|
||||
'conversation.created': this.onConversationCreated,
|
||||
'conversation.opened': this.onStatusChange,
|
||||
'conversation.resolved': this.onStatusChange,
|
||||
'conversation.status_changed': this.onStatusChange,
|
||||
'user:logout': this.onLogout,
|
||||
'page:reload': this.onReload,
|
||||
'assignee.changed': this.onAssigneeChanged,
|
||||
|
|
|
@ -8,6 +8,7 @@ export const getSidebarItems = accountId => ({
|
|||
'inbox_conversation',
|
||||
'conversation_through_inbox',
|
||||
'contacts_dashboard',
|
||||
'contacts_dashboard_manage',
|
||||
'notifications_dashboard',
|
||||
'settings_account_reports',
|
||||
'profile_settings',
|
||||
|
|
79
app/javascript/dashboard/i18n/locale/ar/campaign.json
Normal file
79
app/javascript/dashboard/i18n/locale/ar/campaign.json
Normal file
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"CAMPAIGN": {
|
||||
"HEADER": "Campaigns",
|
||||
"SIDEBAR_TXT": "Proactive messages allow the customer to send outbound messages to their contacts which would trigger more conversations. Click on <b>Add Campaign</b> to create a new campaign. You can also edit or delete an existing campaign by clicking on the Edit or Delete button.",
|
||||
"HEADER_BTN_TXT": "Create a campaign",
|
||||
"ADD": {
|
||||
"TITLE": "Create a campaign",
|
||||
"DESC": "Proactive messages allow the customer to send outbound messages to their contacts which would trigger more conversations.",
|
||||
"CANCEL_BUTTON_TEXT": "إلغاء",
|
||||
"CREATE_BUTTON_TEXT": "إنشاء",
|
||||
"FORM": {
|
||||
"TITLE": {
|
||||
"LABEL": "Title",
|
||||
"PLACEHOLDER": "Please enter the title of campaign",
|
||||
"ERROR": "Title is required"
|
||||
},
|
||||
"MESSAGE": {
|
||||
"LABEL": "رسالة",
|
||||
"PLACEHOLDER": "Please enter the message of campaign",
|
||||
"ERROR": "Message is required"
|
||||
},
|
||||
"SENT_BY": {
|
||||
"LABEL": "أرسلت بواسطة",
|
||||
"PLACEHOLDER": "Please select the the content of campaign",
|
||||
"ERROR": "Sender is required"
|
||||
},
|
||||
"END_POINT": {
|
||||
"LABEL": "URL",
|
||||
"PLACEHOLDER": "Please enter the URL",
|
||||
"ERROR": "الرجاء إدخال عنوان URL صالح"
|
||||
},
|
||||
"TIME_ON_PAGE": {
|
||||
"LABEL": "Time on page(Seconds)",
|
||||
"PLACEHOLDER": "Please enter the time",
|
||||
"ERROR": "Time on page is required"
|
||||
},
|
||||
"ENABLED": "Enable campaign",
|
||||
"SUBMIT": "Add Campaign"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Campaign created successfully",
|
||||
"ERROR_MESSAGE": "There was an error. Please try again."
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Edit campaign",
|
||||
"UPDATE_BUTTON_TEXT": "تحديث",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Campaign updated successfully",
|
||||
"ERROR_MESSAGE": "حدث خطأ، الرجاء المحاولة مرة أخرى"
|
||||
}
|
||||
},
|
||||
"LIST": {
|
||||
"LOADING_MESSAGE": "Loading campaigns...",
|
||||
"404": "There are no campaigns created for this inbox.",
|
||||
"TABLE_HEADER": {
|
||||
"TITLE": "Title",
|
||||
"MESSAGE": "رسالة",
|
||||
"STATUS": "الحالة",
|
||||
"SENDER": "Sender",
|
||||
"URL": "URL",
|
||||
"TIME_ON_PAGE": "Time(Seconds)",
|
||||
"CREATED_AT": "Created at"
|
||||
},
|
||||
"BUTTONS": {
|
||||
"ADD": "Add",
|
||||
"EDIT": "تعديل",
|
||||
"DELETE": "حذف"
|
||||
},
|
||||
"STATUS": {
|
||||
"ENABLED": "مفعل",
|
||||
"DISABLED": "معطّل"
|
||||
},
|
||||
"SENDER": {
|
||||
"BOT": "رد آلي"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -80,6 +80,7 @@
|
|||
"RECEIVED_VIA_EMAIL": "تم تلقيه عبر البريد الإلكتروني",
|
||||
"VIEW_TWEET_IN_TWITTER": "عرض التغريدة في تويتر",
|
||||
"REPLY_TO_TWEET": "الرد على هذه التغريدة",
|
||||
"NO_MESSAGES": "لا توجد رسائل"
|
||||
"NO_MESSAGES": "لا توجد رسائل",
|
||||
"NO_CONTENT": "No content available"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,11 +28,17 @@
|
|||
"INACTIVE_LABELS": "الوسوم المتاحة في الحساب",
|
||||
"REMOVE": "انقر على أيقونة X لإزالة الوسم",
|
||||
"ADD": "اضغط على أيقونة + لإضافة وسوم",
|
||||
"ADD_BUTTON": "Add Labels",
|
||||
"UPDATE_BUTTON": "تحديث الوسوم",
|
||||
"UPDATE_ERROR": "تعذر تحديث الوسوم، الرجاء المحاولة مرة أخرى."
|
||||
},
|
||||
"NO_LABELS_TO_ADD": "لا يوجد وسوم في الحساب.",
|
||||
"NO_AVAILABLE_LABELS": "لا يوجد وسوم مضافة لهذه المحادثة."
|
||||
"NO_AVAILABLE_LABELS": "لا يوجد وسوم مضافة لهذه المحادثة.",
|
||||
"LABEL_SELECT": {
|
||||
"TITLE": "Add Labels",
|
||||
"PLACEHOLDER": "Search labels",
|
||||
"NO_RESULT": "No labels found"
|
||||
}
|
||||
},
|
||||
"MUTE_CONTACT": "كتم المحادثة",
|
||||
"UNMUTE_CONTACT": "إلغاء كتم المحادثة",
|
||||
|
@ -151,5 +157,18 @@
|
|||
},
|
||||
"VIEW_DETAILS": "عرض التفاصيل"
|
||||
}
|
||||
},
|
||||
"NOTES": {
|
||||
"HEADER": {
|
||||
"TITLE": "Notes"
|
||||
},
|
||||
"ADD": {
|
||||
"BUTTON": "Add",
|
||||
"PLACEHOLDER": "Add a note",
|
||||
"TITLE": "Shift + Enter to create a note"
|
||||
},
|
||||
"FOOTER": {
|
||||
"BUTTON": "View all notes"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
"SETTINGS": "الإعدادات",
|
||||
"COLLABORATORS": "المتعاونون",
|
||||
"CONFIGURATION": "الإعدادات",
|
||||
"CAMPAIGN": "Campaigns",
|
||||
"PRE_CHAT_FORM": "نموذج ما قبل الدردشة",
|
||||
"BUSINESS_HOURS": "ساعات العمل"
|
||||
},
|
||||
|
|
|
@ -1,33 +1,37 @@
|
|||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _labelsMgmt } from './labelsMgmt.json';
|
||||
import { default as _campaign } from './campaign.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
import { default as _conversation } from './conversation.json';
|
||||
import { default as _generalSettings } from './generalSettings.json';
|
||||
import { default as _inboxMgmt } from './inboxMgmt.json';
|
||||
import { default as _integrations } from './integrations.json';
|
||||
import { default as _labelsMgmt } from './labelsMgmt.json';
|
||||
import { default as _login } from './login.json';
|
||||
import { default as _report } from './report.json';
|
||||
import { default as _resetPassword } from './resetPassword.json';
|
||||
import { default as _setNewPassword } from './setNewPassword.json';
|
||||
import { default as _settings } from './settings.json';
|
||||
import { default as _signup } from './signup.json';
|
||||
import { default as _integrations } from './integrations.json';
|
||||
import { default as _generalSettings } from './generalSettings.json';
|
||||
import { default as _teamsSettings } from './teamsSettings.json';
|
||||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._campaign,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
..._conversation,
|
||||
..._generalSettings,
|
||||
..._inboxMgmt,
|
||||
..._integrations,
|
||||
..._labelsMgmt,
|
||||
..._login,
|
||||
..._report,
|
||||
..._labelsMgmt,
|
||||
..._resetPassword,
|
||||
..._setNewPassword,
|
||||
..._settings,
|
||||
..._signup,
|
||||
..._integrations,
|
||||
..._generalSettings,
|
||||
..._teamsSettings,
|
||||
};
|
||||
|
|
|
@ -38,6 +38,18 @@
|
|||
{
|
||||
"id": 1,
|
||||
"name": "آخر 30 يوماً"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Last 3 months"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Last 6 months"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Last year"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
79
app/javascript/dashboard/i18n/locale/ca/campaign.json
Normal file
79
app/javascript/dashboard/i18n/locale/ca/campaign.json
Normal file
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"CAMPAIGN": {
|
||||
"HEADER": "Campaigns",
|
||||
"SIDEBAR_TXT": "Proactive messages allow the customer to send outbound messages to their contacts which would trigger more conversations. Click on <b>Add Campaign</b> to create a new campaign. You can also edit or delete an existing campaign by clicking on the Edit or Delete button.",
|
||||
"HEADER_BTN_TXT": "Create a campaign",
|
||||
"ADD": {
|
||||
"TITLE": "Create a campaign",
|
||||
"DESC": "Proactive messages allow the customer to send outbound messages to their contacts which would trigger more conversations.",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel·la",
|
||||
"CREATE_BUTTON_TEXT": "Crear",
|
||||
"FORM": {
|
||||
"TITLE": {
|
||||
"LABEL": "Title",
|
||||
"PLACEHOLDER": "Please enter the title of campaign",
|
||||
"ERROR": "Title is required"
|
||||
},
|
||||
"MESSAGE": {
|
||||
"LABEL": "Missatge",
|
||||
"PLACEHOLDER": "Please enter the message of campaign",
|
||||
"ERROR": "Message is required"
|
||||
},
|
||||
"SENT_BY": {
|
||||
"LABEL": "Enviat per",
|
||||
"PLACEHOLDER": "Please select the the content of campaign",
|
||||
"ERROR": "Sender is required"
|
||||
},
|
||||
"END_POINT": {
|
||||
"LABEL": "URL",
|
||||
"PLACEHOLDER": "Please enter the URL",
|
||||
"ERROR": "Introduïu una URL vàlid"
|
||||
},
|
||||
"TIME_ON_PAGE": {
|
||||
"LABEL": "Time on page(Seconds)",
|
||||
"PLACEHOLDER": "Please enter the time",
|
||||
"ERROR": "Time on page is required"
|
||||
},
|
||||
"ENABLED": "Enable campaign",
|
||||
"SUBMIT": "Add Campaign"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Campaign created successfully",
|
||||
"ERROR_MESSAGE": "There was an error. Please try again."
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Edit campaign",
|
||||
"UPDATE_BUTTON_TEXT": "Actualitza",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Campaign updated successfully",
|
||||
"ERROR_MESSAGE": "S'ha produït un error; tornau-ho a provar"
|
||||
}
|
||||
},
|
||||
"LIST": {
|
||||
"LOADING_MESSAGE": "Loading campaigns...",
|
||||
"404": "There are no campaigns created for this inbox.",
|
||||
"TABLE_HEADER": {
|
||||
"TITLE": "Title",
|
||||
"MESSAGE": "Missatge",
|
||||
"STATUS": "Estat",
|
||||
"SENDER": "Sender",
|
||||
"URL": "URL",
|
||||
"TIME_ON_PAGE": "Time(Seconds)",
|
||||
"CREATED_AT": "Created at"
|
||||
},
|
||||
"BUTTONS": {
|
||||
"ADD": "Add",
|
||||
"EDIT": "Edita",
|
||||
"DELETE": "Esborrar"
|
||||
},
|
||||
"STATUS": {
|
||||
"ENABLED": "Habilita",
|
||||
"DISABLED": "Inhabilita"
|
||||
},
|
||||
"SENDER": {
|
||||
"BOT": "Bot"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -80,6 +80,7 @@
|
|||
"RECEIVED_VIA_EMAIL": "Rebut per correu electrònic",
|
||||
"VIEW_TWEET_IN_TWITTER": "Veure el tuit a Twitter",
|
||||
"REPLY_TO_TWEET": "Respon a aquest tuit",
|
||||
"NO_MESSAGES": "Cap Missatge"
|
||||
"NO_MESSAGES": "Cap Missatge",
|
||||
"NO_CONTENT": "No content available"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,11 +28,17 @@
|
|||
"INACTIVE_LABELS": "Etiquetes disponibles al compte",
|
||||
"REMOVE": "Fes clic a la icona X per eliminar l'etiqueta",
|
||||
"ADD": "Fes clic a la icona + per afegir l'etiqueta",
|
||||
"ADD_BUTTON": "Add Labels",
|
||||
"UPDATE_BUTTON": "Actualitza les etiquetes",
|
||||
"UPDATE_ERROR": "No s'han pogut actualitzar les etiquetes, torna-ho a provar."
|
||||
},
|
||||
"NO_LABELS_TO_ADD": "No hi ha cap etiqueta definida al compte.",
|
||||
"NO_AVAILABLE_LABELS": "No hi ha etiquetes afegides a aquesta conversa."
|
||||
"NO_AVAILABLE_LABELS": "No hi ha etiquetes afegides a aquesta conversa.",
|
||||
"LABEL_SELECT": {
|
||||
"TITLE": "Add Labels",
|
||||
"PLACEHOLDER": "Search labels",
|
||||
"NO_RESULT": "No labels found"
|
||||
}
|
||||
},
|
||||
"MUTE_CONTACT": "Silencia la conversa",
|
||||
"UNMUTE_CONTACT": "Desactiva el silenci de la conversa",
|
||||
|
@ -151,5 +157,18 @@
|
|||
},
|
||||
"VIEW_DETAILS": "View details"
|
||||
}
|
||||
},
|
||||
"NOTES": {
|
||||
"HEADER": {
|
||||
"TITLE": "Notes"
|
||||
},
|
||||
"ADD": {
|
||||
"BUTTON": "Add",
|
||||
"PLACEHOLDER": "Add a note",
|
||||
"TITLE": "Shift + Enter to create a note"
|
||||
},
|
||||
"FOOTER": {
|
||||
"BUTTON": "View all notes"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
"SETTINGS": "Configuracions",
|
||||
"COLLABORATORS": "Col·laboradors",
|
||||
"CONFIGURATION": "Configuració",
|
||||
"CAMPAIGN": "Campaigns",
|
||||
"PRE_CHAT_FORM": "Pre Chat Form",
|
||||
"BUSINESS_HOURS": "Business Hours"
|
||||
},
|
||||
|
|
|
@ -1,33 +1,37 @@
|
|||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _labelsMgmt } from './labelsMgmt.json';
|
||||
import { default as _campaign } from './campaign.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
import { default as _conversation } from './conversation.json';
|
||||
import { default as _generalSettings } from './generalSettings.json';
|
||||
import { default as _inboxMgmt } from './inboxMgmt.json';
|
||||
import { default as _integrations } from './integrations.json';
|
||||
import { default as _labelsMgmt } from './labelsMgmt.json';
|
||||
import { default as _login } from './login.json';
|
||||
import { default as _report } from './report.json';
|
||||
import { default as _resetPassword } from './resetPassword.json';
|
||||
import { default as _setNewPassword } from './setNewPassword.json';
|
||||
import { default as _settings } from './settings.json';
|
||||
import { default as _signup } from './signup.json';
|
||||
import { default as _integrations } from './integrations.json';
|
||||
import { default as _generalSettings } from './generalSettings.json';
|
||||
import { default as _teamsSettings } from './teamsSettings.json';
|
||||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._campaign,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
..._conversation,
|
||||
..._generalSettings,
|
||||
..._inboxMgmt,
|
||||
..._integrations,
|
||||
..._labelsMgmt,
|
||||
..._login,
|
||||
..._report,
|
||||
..._labelsMgmt,
|
||||
..._resetPassword,
|
||||
..._setNewPassword,
|
||||
..._settings,
|
||||
..._signup,
|
||||
..._integrations,
|
||||
..._generalSettings,
|
||||
..._teamsSettings,
|
||||
};
|
||||
|
|
|
@ -38,6 +38,18 @@
|
|||
{
|
||||
"id": 1,
|
||||
"name": "Últims 30 dies"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Last 3 months"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Last 6 months"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Last year"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
79
app/javascript/dashboard/i18n/locale/cs/campaign.json
Normal file
79
app/javascript/dashboard/i18n/locale/cs/campaign.json
Normal file
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"CAMPAIGN": {
|
||||
"HEADER": "Campaigns",
|
||||
"SIDEBAR_TXT": "Proactive messages allow the customer to send outbound messages to their contacts which would trigger more conversations. Click on <b>Add Campaign</b> to create a new campaign. You can also edit or delete an existing campaign by clicking on the Edit or Delete button.",
|
||||
"HEADER_BTN_TXT": "Create a campaign",
|
||||
"ADD": {
|
||||
"TITLE": "Create a campaign",
|
||||
"DESC": "Proactive messages allow the customer to send outbound messages to their contacts which would trigger more conversations.",
|
||||
"CANCEL_BUTTON_TEXT": "Zrušit",
|
||||
"CREATE_BUTTON_TEXT": "Create",
|
||||
"FORM": {
|
||||
"TITLE": {
|
||||
"LABEL": "Title",
|
||||
"PLACEHOLDER": "Please enter the title of campaign",
|
||||
"ERROR": "Title is required"
|
||||
},
|
||||
"MESSAGE": {
|
||||
"LABEL": "Zpráva",
|
||||
"PLACEHOLDER": "Please enter the message of campaign",
|
||||
"ERROR": "Message is required"
|
||||
},
|
||||
"SENT_BY": {
|
||||
"LABEL": "Odeslal",
|
||||
"PLACEHOLDER": "Please select the the content of campaign",
|
||||
"ERROR": "Sender is required"
|
||||
},
|
||||
"END_POINT": {
|
||||
"LABEL": "URL",
|
||||
"PLACEHOLDER": "Please enter the URL",
|
||||
"ERROR": "Zadejte prosím platnou URL"
|
||||
},
|
||||
"TIME_ON_PAGE": {
|
||||
"LABEL": "Time on page(Seconds)",
|
||||
"PLACEHOLDER": "Please enter the time",
|
||||
"ERROR": "Time on page is required"
|
||||
},
|
||||
"ENABLED": "Enable campaign",
|
||||
"SUBMIT": "Add Campaign"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Campaign created successfully",
|
||||
"ERROR_MESSAGE": "There was an error. Please try again."
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Edit campaign",
|
||||
"UPDATE_BUTTON_TEXT": "Aktualizovat",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Campaign updated successfully",
|
||||
"ERROR_MESSAGE": "Došlo k chybě, zkuste to prosím znovu"
|
||||
}
|
||||
},
|
||||
"LIST": {
|
||||
"LOADING_MESSAGE": "Loading campaigns...",
|
||||
"404": "There are no campaigns created for this inbox.",
|
||||
"TABLE_HEADER": {
|
||||
"TITLE": "Title",
|
||||
"MESSAGE": "Zpráva",
|
||||
"STATUS": "Stav",
|
||||
"SENDER": "Sender",
|
||||
"URL": "URL",
|
||||
"TIME_ON_PAGE": "Time(Seconds)",
|
||||
"CREATED_AT": "Created at"
|
||||
},
|
||||
"BUTTONS": {
|
||||
"ADD": "Add",
|
||||
"EDIT": "Upravit",
|
||||
"DELETE": "Vymazat"
|
||||
},
|
||||
"STATUS": {
|
||||
"ENABLED": "Povoleno",
|
||||
"DISABLED": "Zakázáno"
|
||||
},
|
||||
"SENDER": {
|
||||
"BOT": "Bot"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -80,6 +80,7 @@
|
|||
"RECEIVED_VIA_EMAIL": "Obdrženo e-mailem",
|
||||
"VIEW_TWEET_IN_TWITTER": "Zobrazit tweet na Twitteru",
|
||||
"REPLY_TO_TWEET": "Odpovědět na tento tweet",
|
||||
"NO_MESSAGES": "Žádné zprávy"
|
||||
"NO_MESSAGES": "Žádné zprávy",
|
||||
"NO_CONTENT": "No content available"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,11 +28,17 @@
|
|||
"INACTIVE_LABELS": "Štítky dostupné v účtu",
|
||||
"REMOVE": "Kliknutím na ikonu X odstraníte štítek",
|
||||
"ADD": "Kliknutím na ikonu + přidáte štítek",
|
||||
"ADD_BUTTON": "Add Labels",
|
||||
"UPDATE_BUTTON": "Aktualizovat štítky",
|
||||
"UPDATE_ERROR": "Nelze aktualizovat štítky, zkuste to znovu."
|
||||
},
|
||||
"NO_LABELS_TO_ADD": "V účtu nejsou definovány žádné další štítky.",
|
||||
"NO_AVAILABLE_LABELS": "Do této konverzace nebyly přidány žádné štítky."
|
||||
"NO_AVAILABLE_LABELS": "Do této konverzace nebyly přidány žádné štítky.",
|
||||
"LABEL_SELECT": {
|
||||
"TITLE": "Add Labels",
|
||||
"PLACEHOLDER": "Search labels",
|
||||
"NO_RESULT": "No labels found"
|
||||
}
|
||||
},
|
||||
"MUTE_CONTACT": "Ztlumit konverzaci",
|
||||
"UNMUTE_CONTACT": "Zrušit ztlumení konverzace",
|
||||
|
@ -151,5 +157,18 @@
|
|||
},
|
||||
"VIEW_DETAILS": "Zobrazit detaily"
|
||||
}
|
||||
},
|
||||
"NOTES": {
|
||||
"HEADER": {
|
||||
"TITLE": "Notes"
|
||||
},
|
||||
"ADD": {
|
||||
"BUTTON": "Add",
|
||||
"PLACEHOLDER": "Add a note",
|
||||
"TITLE": "Shift + Enter to create a note"
|
||||
},
|
||||
"FOOTER": {
|
||||
"BUTTON": "View all notes"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
"SETTINGS": "Nastavení",
|
||||
"COLLABORATORS": "Spolupracující",
|
||||
"CONFIGURATION": "Nastavení",
|
||||
"CAMPAIGN": "Campaigns",
|
||||
"PRE_CHAT_FORM": "Formulář před chatem",
|
||||
"BUSINESS_HOURS": "Pracovní doba"
|
||||
},
|
||||
|
|
|
@ -1,33 +1,37 @@
|
|||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _labelsMgmt } from './labelsMgmt.json';
|
||||
import { default as _campaign } from './campaign.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
import { default as _conversation } from './conversation.json';
|
||||
import { default as _generalSettings } from './generalSettings.json';
|
||||
import { default as _inboxMgmt } from './inboxMgmt.json';
|
||||
import { default as _integrations } from './integrations.json';
|
||||
import { default as _labelsMgmt } from './labelsMgmt.json';
|
||||
import { default as _login } from './login.json';
|
||||
import { default as _report } from './report.json';
|
||||
import { default as _resetPassword } from './resetPassword.json';
|
||||
import { default as _setNewPassword } from './setNewPassword.json';
|
||||
import { default as _settings } from './settings.json';
|
||||
import { default as _signup } from './signup.json';
|
||||
import { default as _integrations } from './integrations.json';
|
||||
import { default as _generalSettings } from './generalSettings.json';
|
||||
import { default as _teamsSettings } from './teamsSettings.json';
|
||||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._campaign,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
..._conversation,
|
||||
..._generalSettings,
|
||||
..._inboxMgmt,
|
||||
..._integrations,
|
||||
..._labelsMgmt,
|
||||
..._login,
|
||||
..._report,
|
||||
..._labelsMgmt,
|
||||
..._resetPassword,
|
||||
..._setNewPassword,
|
||||
..._settings,
|
||||
..._signup,
|
||||
..._integrations,
|
||||
..._generalSettings,
|
||||
..._teamsSettings,
|
||||
};
|
||||
|
|
|
@ -38,6 +38,18 @@
|
|||
{
|
||||
"id": 1,
|
||||
"name": "Posledních 30 dní"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Last 3 months"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Last 6 months"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Last year"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
79
app/javascript/dashboard/i18n/locale/da/campaign.json
Normal file
79
app/javascript/dashboard/i18n/locale/da/campaign.json
Normal file
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"CAMPAIGN": {
|
||||
"HEADER": "Campaigns",
|
||||
"SIDEBAR_TXT": "Proactive messages allow the customer to send outbound messages to their contacts which would trigger more conversations. Click on <b>Add Campaign</b> to create a new campaign. You can also edit or delete an existing campaign by clicking on the Edit or Delete button.",
|
||||
"HEADER_BTN_TXT": "Create a campaign",
|
||||
"ADD": {
|
||||
"TITLE": "Create a campaign",
|
||||
"DESC": "Proactive messages allow the customer to send outbound messages to their contacts which would trigger more conversations.",
|
||||
"CANCEL_BUTTON_TEXT": "Annuller",
|
||||
"CREATE_BUTTON_TEXT": "Opret",
|
||||
"FORM": {
|
||||
"TITLE": {
|
||||
"LABEL": "Title",
|
||||
"PLACEHOLDER": "Please enter the title of campaign",
|
||||
"ERROR": "Title is required"
|
||||
},
|
||||
"MESSAGE": {
|
||||
"LABEL": "Message",
|
||||
"PLACEHOLDER": "Please enter the message of campaign",
|
||||
"ERROR": "Message is required"
|
||||
},
|
||||
"SENT_BY": {
|
||||
"LABEL": "Sent by",
|
||||
"PLACEHOLDER": "Please select the the content of campaign",
|
||||
"ERROR": "Sender is required"
|
||||
},
|
||||
"END_POINT": {
|
||||
"LABEL": "URL",
|
||||
"PLACEHOLDER": "Please enter the URL",
|
||||
"ERROR": "Angiv en gyldig URL"
|
||||
},
|
||||
"TIME_ON_PAGE": {
|
||||
"LABEL": "Time on page(Seconds)",
|
||||
"PLACEHOLDER": "Please enter the time",
|
||||
"ERROR": "Time on page is required"
|
||||
},
|
||||
"ENABLED": "Enable campaign",
|
||||
"SUBMIT": "Add Campaign"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Campaign created successfully",
|
||||
"ERROR_MESSAGE": "There was an error. Please try again."
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Edit campaign",
|
||||
"UPDATE_BUTTON_TEXT": "Opdater",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Campaign updated successfully",
|
||||
"ERROR_MESSAGE": "Der opstod en fejl. Prøv venligst igen"
|
||||
}
|
||||
},
|
||||
"LIST": {
|
||||
"LOADING_MESSAGE": "Loading campaigns...",
|
||||
"404": "There are no campaigns created for this inbox.",
|
||||
"TABLE_HEADER": {
|
||||
"TITLE": "Title",
|
||||
"MESSAGE": "Message",
|
||||
"STATUS": "Status",
|
||||
"SENDER": "Sender",
|
||||
"URL": "URL",
|
||||
"TIME_ON_PAGE": "Time(Seconds)",
|
||||
"CREATED_AT": "Created at"
|
||||
},
|
||||
"BUTTONS": {
|
||||
"ADD": "Add",
|
||||
"EDIT": "Rediger",
|
||||
"DELETE": "Slet"
|
||||
},
|
||||
"STATUS": {
|
||||
"ENABLED": "Aktiveret",
|
||||
"DISABLED": "Deaktiveret"
|
||||
},
|
||||
"SENDER": {
|
||||
"BOT": "Bot"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -80,6 +80,7 @@
|
|||
"RECEIVED_VIA_EMAIL": "Modtaget via e-mail",
|
||||
"VIEW_TWEET_IN_TWITTER": "Se tweet på Twitter",
|
||||
"REPLY_TO_TWEET": "Svar på dette tweet",
|
||||
"NO_MESSAGES": "No Messages"
|
||||
"NO_MESSAGES": "No Messages",
|
||||
"NO_CONTENT": "No content available"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,11 +28,17 @@
|
|||
"INACTIVE_LABELS": "Etiketter tilgængelige på kontoen",
|
||||
"REMOVE": "Klik på X-ikonet for at fjerne etiketten",
|
||||
"ADD": "Klik på + ikonet for at tilføje etiketten",
|
||||
"ADD_BUTTON": "Add Labels",
|
||||
"UPDATE_BUTTON": "Opdater etiketter",
|
||||
"UPDATE_ERROR": "Etiketter kunne ikke opdateres. Prøv igen."
|
||||
},
|
||||
"NO_LABELS_TO_ADD": "Der er ikke defineret flere etiketter på kontoen.",
|
||||
"NO_AVAILABLE_LABELS": "Der er ingen etiketter tilføjet til denne samtale."
|
||||
"NO_AVAILABLE_LABELS": "Der er ingen etiketter tilføjet til denne samtale.",
|
||||
"LABEL_SELECT": {
|
||||
"TITLE": "Add Labels",
|
||||
"PLACEHOLDER": "Search labels",
|
||||
"NO_RESULT": "No labels found"
|
||||
}
|
||||
},
|
||||
"MUTE_CONTACT": "Gør Samtale Lydløs",
|
||||
"UNMUTE_CONTACT": "Fjern Lydløs",
|
||||
|
@ -151,5 +157,18 @@
|
|||
},
|
||||
"VIEW_DETAILS": "View details"
|
||||
}
|
||||
},
|
||||
"NOTES": {
|
||||
"HEADER": {
|
||||
"TITLE": "Notes"
|
||||
},
|
||||
"ADD": {
|
||||
"BUTTON": "Add",
|
||||
"PLACEHOLDER": "Add a note",
|
||||
"TITLE": "Shift + Enter to create a note"
|
||||
},
|
||||
"FOOTER": {
|
||||
"BUTTON": "View all notes"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
"SETTINGS": "Indstillinger",
|
||||
"COLLABORATORS": "Samarbejdspartnere",
|
||||
"CONFIGURATION": "Konfiguration",
|
||||
"CAMPAIGN": "Campaigns",
|
||||
"PRE_CHAT_FORM": "Pre Chat Form",
|
||||
"BUSINESS_HOURS": "Business Hours"
|
||||
},
|
||||
|
|
|
@ -1,33 +1,37 @@
|
|||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _labelsMgmt } from './labelsMgmt.json';
|
||||
import { default as _campaign } from './campaign.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
import { default as _conversation } from './conversation.json';
|
||||
import { default as _generalSettings } from './generalSettings.json';
|
||||
import { default as _inboxMgmt } from './inboxMgmt.json';
|
||||
import { default as _integrations } from './integrations.json';
|
||||
import { default as _labelsMgmt } from './labelsMgmt.json';
|
||||
import { default as _login } from './login.json';
|
||||
import { default as _report } from './report.json';
|
||||
import { default as _resetPassword } from './resetPassword.json';
|
||||
import { default as _setNewPassword } from './setNewPassword.json';
|
||||
import { default as _settings } from './settings.json';
|
||||
import { default as _signup } from './signup.json';
|
||||
import { default as _integrations } from './integrations.json';
|
||||
import { default as _generalSettings } from './generalSettings.json';
|
||||
import { default as _teamsSettings } from './teamsSettings.json';
|
||||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._campaign,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
..._conversation,
|
||||
..._generalSettings,
|
||||
..._inboxMgmt,
|
||||
..._integrations,
|
||||
..._labelsMgmt,
|
||||
..._login,
|
||||
..._report,
|
||||
..._labelsMgmt,
|
||||
..._resetPassword,
|
||||
..._setNewPassword,
|
||||
..._settings,
|
||||
..._signup,
|
||||
..._integrations,
|
||||
..._generalSettings,
|
||||
..._teamsSettings,
|
||||
};
|
||||
|
|
|
@ -38,6 +38,18 @@
|
|||
{
|
||||
"id": 1,
|
||||
"name": "Seneste 30 dage"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Last 3 months"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Last 6 months"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Last year"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
79
app/javascript/dashboard/i18n/locale/de/campaign.json
Normal file
79
app/javascript/dashboard/i18n/locale/de/campaign.json
Normal file
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"CAMPAIGN": {
|
||||
"HEADER": "Kampagnen",
|
||||
"SIDEBAR_TXT": "Proaktive Nachrichten erlauben dem Kunden, ausgehende Nachrichten an seine Kontakte zu senden, was weitere Unterhaltungen auslösen würde. Klicke auf <b>Kampagne hinzufügen</b> um eine neue Kampagne zu erstellen. Sie können auch eine bestehende Kampagne bearbeiten oder löschen, indem Sie auf die Schaltfläche Bearbeiten oder Löschen klicken.",
|
||||
"HEADER_BTN_TXT": "Kampagne erstellen",
|
||||
"ADD": {
|
||||
"TITLE": "Kampagne erstellen",
|
||||
"DESC": "Proaktive Nachrichten erlauben dem Kunden, ausgehende Nachrichten an seine Kontakte zu senden, was weitere Unterhaltungen auslösen würde.",
|
||||
"CANCEL_BUTTON_TEXT": "Stornieren",
|
||||
"CREATE_BUTTON_TEXT": "Erstellen",
|
||||
"FORM": {
|
||||
"TITLE": {
|
||||
"LABEL": "Titel",
|
||||
"PLACEHOLDER": "Bitte geben Sie den Titel der Kampagne ein",
|
||||
"ERROR": "Titel ist erforderlich"
|
||||
},
|
||||
"MESSAGE": {
|
||||
"LABEL": "Nachricht",
|
||||
"PLACEHOLDER": "Bitte geben Sie die Nachricht der Kampagne ein",
|
||||
"ERROR": "Nachricht ist erforderlich"
|
||||
},
|
||||
"SENT_BY": {
|
||||
"LABEL": "Gesendet von",
|
||||
"PLACEHOLDER": "Bitte wählen Sie den Inhalt der Kampagne aus",
|
||||
"ERROR": "Absender ist erforderlich"
|
||||
},
|
||||
"END_POINT": {
|
||||
"LABEL": "URL",
|
||||
"PLACEHOLDER": "Bitte URL eingeben",
|
||||
"ERROR": "Bitte geben Sie eine gültige URL ein"
|
||||
},
|
||||
"TIME_ON_PAGE": {
|
||||
"LABEL": "Zeit auf Seite (Sekunden)",
|
||||
"PLACEHOLDER": "Bitte die Uhrzeit eingeben",
|
||||
"ERROR": "Uhrzeit auf Seite ist erforderlich"
|
||||
},
|
||||
"ENABLED": "Kampagne aktivieren",
|
||||
"SUBMIT": "Kampagne hinzufügen"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Kampagne erfolgreich erstellt",
|
||||
"ERROR_MESSAGE": "Es ist ein Fehler aufgetreten, bitte versuchen Sie es erneut."
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Kampagne bearbeiten",
|
||||
"UPDATE_BUTTON_TEXT": "Aktualisieren",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Kampagne erfolgreich aktualisiert",
|
||||
"ERROR_MESSAGE": "Es ist ein Fehler aufgetreten, bitte versuchen Sie es erneut"
|
||||
}
|
||||
},
|
||||
"LIST": {
|
||||
"LOADING_MESSAGE": "Lade Kampagnen...",
|
||||
"404": "There are no campaigns created for this inbox.",
|
||||
"TABLE_HEADER": {
|
||||
"TITLE": "Titel",
|
||||
"MESSAGE": "Nachricht",
|
||||
"STATUS": "Status",
|
||||
"SENDER": "Absender",
|
||||
"URL": "URL",
|
||||
"TIME_ON_PAGE": "Zeit (Sekunden)",
|
||||
"CREATED_AT": "Erstellt am"
|
||||
},
|
||||
"BUTTONS": {
|
||||
"ADD": "Hinzufügen",
|
||||
"EDIT": "Bearbeiten",
|
||||
"DELETE": "Löschen"
|
||||
},
|
||||
"STATUS": {
|
||||
"ENABLED": "Aktiviert",
|
||||
"DISABLED": "Behindert"
|
||||
},
|
||||
"SENDER": {
|
||||
"BOT": "Bot"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -80,6 +80,7 @@
|
|||
"RECEIVED_VIA_EMAIL": "Per E-Mail empfangen",
|
||||
"VIEW_TWEET_IN_TWITTER": "Tweet auf Twitter anzeigen",
|
||||
"REPLY_TO_TWEET": "Auf diesen Tweet antworten",
|
||||
"NO_MESSAGES": "Keine Nachrichten"
|
||||
"NO_MESSAGES": "Keine Nachrichten",
|
||||
"NO_CONTENT": "Kein Inhalt verfügbar"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"INITIATED_FROM": "Initiiert von",
|
||||
"INITIATED_AT": "Initiiert bei",
|
||||
"IP_ADDRESS": "IP-Adresse",
|
||||
"NEW_MESSAGE": "New message",
|
||||
"NEW_MESSAGE": "Neue Nachricht",
|
||||
"CONVERSATIONS": {
|
||||
"NO_RECORDS_FOUND": "Es sind keine vorherigen Gespräche mit diesem Kontakt verbunden.",
|
||||
"TITLE": "Vorherige Gespräche"
|
||||
|
@ -28,11 +28,17 @@
|
|||
"INACTIVE_LABELS": "Verfügbare Labels im Konto",
|
||||
"REMOVE": "Klicken Sie auf das X-Symbol, um das Label zu entfernen",
|
||||
"ADD": "Klicken Sie auf das + Symbol, um ein Label hinzuzufügen",
|
||||
"ADD_BUTTON": "Label hinzufügen",
|
||||
"UPDATE_BUTTON": "Labels aktualisieren",
|
||||
"UPDATE_ERROR": "Etiketten konnten nicht aktualisiert werden. Versuchen Sie es erneut."
|
||||
},
|
||||
"NO_LABELS_TO_ADD": "Es sind keine weiteren Labels im Konto definiert.",
|
||||
"NO_AVAILABLE_LABELS": "Zu dieser Unterhaltung wurden noch keine Labels hinzugefügt."
|
||||
"NO_AVAILABLE_LABELS": "Zu dieser Unterhaltung wurden noch keine Labels hinzugefügt.",
|
||||
"LABEL_SELECT": {
|
||||
"TITLE": "Label hinzufügen",
|
||||
"PLACEHOLDER": "Labels suchen",
|
||||
"NO_RESULT": "Keine Labels gefunden"
|
||||
}
|
||||
},
|
||||
"MUTE_CONTACT": "Unterhaltung stummschalten",
|
||||
"UNMUTE_CONTACT": "Unterhaltung entmuten",
|
||||
|
@ -73,8 +79,8 @@
|
|||
"PHONE_NUMBER": {
|
||||
"PLACEHOLDER": "Geben Sie die Telefonnummer des Kontakts ein",
|
||||
"LABEL": "Telefonnummer",
|
||||
"HELP": "Phone number should be of E.164 format eg: +1415555555 [+][country code][area code][local phone number]",
|
||||
"ERROR": "Phone number should be either empty or of E.164 format"
|
||||
"HELP": "Telefonnummer sollte im E.164-Format sein, z. B.: +1415555555 [+][Landesvorwahl][Landesvorwahl][Ortsvorwahl]",
|
||||
"ERROR": "Telefonnummer muss leer sein oder im E.164-Format"
|
||||
},
|
||||
"LOCATION": {
|
||||
"PLACEHOLDER": "Geben Sie den Standort des Kontakts ein",
|
||||
|
@ -108,27 +114,27 @@
|
|||
"ERROR_MESSAGE": "Es ist ein Fehler aufgetreten, bitte versuche es erneut"
|
||||
},
|
||||
"NEW_CONVERSATION": {
|
||||
"BUTTON_LABEL": "Start conversation",
|
||||
"BUTTON_LABEL": "Gespräch starten",
|
||||
"TITLE": "Neue Unterhaltung",
|
||||
"DESC": "Start a new conversation by sending a new message.",
|
||||
"NO_INBOX": "Couldn't find an inbox to initiate a new conversation with this contact.",
|
||||
"DESC": "Starte eine Unterhaltung mit einer neuen Nachricht",
|
||||
"NO_INBOX": "Konnte keinen Posteingang finden, um eine neue Unterhaltung mit diesem Kontakt zu starten.",
|
||||
"FORM": {
|
||||
"TO": {
|
||||
"LABEL": "To"
|
||||
"LABEL": "An"
|
||||
},
|
||||
"INBOX": {
|
||||
"LABEL": "Inbox",
|
||||
"ERROR": "Select an inbox"
|
||||
"LABEL": "Posteingang",
|
||||
"ERROR": "Posteingang auswählen"
|
||||
},
|
||||
"MESSAGE": {
|
||||
"LABEL": "Nachricht",
|
||||
"PLACEHOLDER": "Write your message here",
|
||||
"ERROR": "Message can't be empty"
|
||||
"PLACEHOLDER": "Schreiben Sie Ihre Nachricht hier",
|
||||
"ERROR": "Nachricht darf nicht leer sein"
|
||||
},
|
||||
"SUBMIT": "Send message",
|
||||
"SUBMIT": "Nachricht senden",
|
||||
"CANCEL": "Stornieren",
|
||||
"SUCCESS_MESSAGE": "Message sent!",
|
||||
"ERROR_MESSAGE": "Couldn't send! try again"
|
||||
"SUCCESS_MESSAGE": "Nachricht gesendet!",
|
||||
"ERROR_MESSAGE": "Senden fehlgeschlagen! Bitte erneut versuchen"
|
||||
}
|
||||
},
|
||||
"CONTACTS_PAGE": {
|
||||
|
@ -151,5 +157,18 @@
|
|||
},
|
||||
"VIEW_DETAILS": "Details anzeigen"
|
||||
}
|
||||
},
|
||||
"NOTES": {
|
||||
"HEADER": {
|
||||
"TITLE": "Notizen"
|
||||
},
|
||||
"ADD": {
|
||||
"BUTTON": "Hinzufügen",
|
||||
"PLACEHOLDER": "Notiz hinzufügen",
|
||||
"TITLE": "Shift + Enter um eine Notiz zu erstellen"
|
||||
},
|
||||
"FOOTER": {
|
||||
"BUTTON": "Alle Notizen anzeigen"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
"SETTINGS": "Einstellungen",
|
||||
"COLLABORATORS": "Mitarbeitende",
|
||||
"CONFIGURATION": "Konfiguration",
|
||||
"CAMPAIGN": "Kampagnen",
|
||||
"PRE_CHAT_FORM": "Pre-Chat-Formular",
|
||||
"BUSINESS_HOURS": "Öffnungszeiten"
|
||||
},
|
||||
|
|
|
@ -1,33 +1,37 @@
|
|||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _labelsMgmt } from './labelsMgmt.json';
|
||||
import { default as _campaign } from './campaign.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
import { default as _conversation } from './conversation.json';
|
||||
import { default as _generalSettings } from './generalSettings.json';
|
||||
import { default as _inboxMgmt } from './inboxMgmt.json';
|
||||
import { default as _integrations } from './integrations.json';
|
||||
import { default as _labelsMgmt } from './labelsMgmt.json';
|
||||
import { default as _login } from './login.json';
|
||||
import { default as _report } from './report.json';
|
||||
import { default as _resetPassword } from './resetPassword.json';
|
||||
import { default as _setNewPassword } from './setNewPassword.json';
|
||||
import { default as _settings } from './settings.json';
|
||||
import { default as _signup } from './signup.json';
|
||||
import { default as _integrations } from './integrations.json';
|
||||
import { default as _generalSettings } from './generalSettings.json';
|
||||
import { default as _teamsSettings } from './teamsSettings.json';
|
||||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._campaign,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
..._conversation,
|
||||
..._generalSettings,
|
||||
..._inboxMgmt,
|
||||
..._integrations,
|
||||
..._labelsMgmt,
|
||||
..._login,
|
||||
..._report,
|
||||
..._labelsMgmt,
|
||||
..._resetPassword,
|
||||
..._setNewPassword,
|
||||
..._settings,
|
||||
..._signup,
|
||||
..._integrations,
|
||||
..._generalSettings,
|
||||
..._teamsSettings,
|
||||
};
|
||||
|
|
|
@ -38,6 +38,18 @@
|
|||
{
|
||||
"id": 1,
|
||||
"name": "Letzte 30 Tage"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Last 3 months"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Last 6 months"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Last year"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
},
|
||||
"AGENTS": {
|
||||
"BUTTON_TEXT": "Agenten im Team aktualisieren",
|
||||
"TITLE": "Agenten zu Team hinzufügen - %{teamName}",
|
||||
"TITLE": "Agenten zu Team %{teamName} hinzufügen",
|
||||
"DESC": "Fügen Sie Agenten zu Ihrem neu erstellten Team hinzu. Alle hinzugefügten Agenten werden benachrichtigt, wenn diesem Team eine Unterhaltung zugewiesen wird."
|
||||
},
|
||||
"WIZARD": [
|
||||
|
@ -77,8 +77,8 @@
|
|||
"SELECTED_COUNT": "%{selected} von %{total} Agenten ausgewählt."
|
||||
},
|
||||
"ADD": {
|
||||
"TITLE": "Agenten zu Team hinzufügen - %{teamName}",
|
||||
"DESC": "Fügen Sie Agenten zu Ihrem neu erstellten Team hinzu. So können Sie bei Gesprächen als Team zusammenarbeiten, erhalten Sie Benachrichtigungen über neue Ereignisse in der gleichen Unterhaltung.",
|
||||
"TITLE": "Agenten zu Team %{teamName} hinzufügen",
|
||||
"DESC": "Fügen Sie Agenten zu Ihrem neu erstellten Team hinzu. So können Sie bei Gesprächen als Team zusammenarbeiten und erhalten Benachrichtigungen über neue Ereignisse in der gleichen Unterhaltung.",
|
||||
"SELECT": "auswählen",
|
||||
"SELECT_ALL": "alle Agenten auswählen",
|
||||
"SELECTED_COUNT": "%{selected} von %{total} Agenten ausgewählt.",
|
||||
|
|
79
app/javascript/dashboard/i18n/locale/el/campaign.json
Normal file
79
app/javascript/dashboard/i18n/locale/el/campaign.json
Normal file
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"CAMPAIGN": {
|
||||
"HEADER": "Καμπάνιες",
|
||||
"SIDEBAR_TXT": "Τα προληπτικά μηνύματα επιτρέπουν την αποστολή εξερχόμενων μηνυμάτων στις επαφές, που θα ενεργοποιούν περισσότερες συνομιλίες. Κάντε κλικ στο <b>Προσθήκη Καμπάνιας</b> για να δημιουργήσετε μια νέα καμπάνια. Μπορείτε επίσης να επεξεργαστείτε ή να διαγράψετε μια ήδη υπάρχουσα καμπάνια κάνοντας κλικ στο κουμπί Επεξεργασία ή Διαγραφή.",
|
||||
"HEADER_BTN_TXT": "Δημιουργία Καμπάνιας",
|
||||
"ADD": {
|
||||
"TITLE": "Δημιουργία Καμπάνιας",
|
||||
"DESC": "Τα προληπτικά μηνύματα επιτρέπουν την αποστολή εξερχόμενων μηνυμάτων στις επαφές, που θα ενεργοποιούν περισσότερες συνομιλίες.",
|
||||
"CANCEL_BUTTON_TEXT": "Άκυρο",
|
||||
"CREATE_BUTTON_TEXT": "Δημιουργία",
|
||||
"FORM": {
|
||||
"TITLE": {
|
||||
"LABEL": "Τίτλος",
|
||||
"PLACEHOLDER": "Παρακαλώ εισάγετε τον τίτλο της καμπάνιας",
|
||||
"ERROR": "Ο τίτλος είναι απαραίτητος"
|
||||
},
|
||||
"MESSAGE": {
|
||||
"LABEL": "Μήνυμα",
|
||||
"PLACEHOLDER": "Παρακαλώ εισάγετε το μήνυμα της καμπάνιας",
|
||||
"ERROR": "Το μήνυμα είναι απαραίτητο"
|
||||
},
|
||||
"SENT_BY": {
|
||||
"LABEL": "Αποστολή από",
|
||||
"PLACEHOLDER": "Παρακαλώ επιλέξτε το περιεχόμενο της καμπάνιας",
|
||||
"ERROR": "Ο αποστολέας είναι απαραίτητος"
|
||||
},
|
||||
"END_POINT": {
|
||||
"LABEL": "URL",
|
||||
"PLACEHOLDER": "Παρακαλώ εισάγετε το URL",
|
||||
"ERROR": "Παρακαλώ εισάγετε ένα έγκυρο URL"
|
||||
},
|
||||
"TIME_ON_PAGE": {
|
||||
"LABEL": "Χρόνος στη σελίδα(δευτερόλεπτα)",
|
||||
"PLACEHOLDER": "Παρακαλώ εισάγετε το χρόνο",
|
||||
"ERROR": "Ο χρόνος στη σελίδα είναι απαραίτητος"
|
||||
},
|
||||
"ENABLED": "Ενεργοποίηση καμπάνιας",
|
||||
"SUBMIT": "Προσθήκη Καμπάνιας"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Η καμπάνια δημιουργήθηκε επιτυχώς",
|
||||
"ERROR_MESSAGE": "Παρουσιάστηκε σφάλμα. Παρακαλώ δοκιμάστε ξανά."
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Edit campaign",
|
||||
"UPDATE_BUTTON_TEXT": "Ενημέρωση",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Campaign updated successfully",
|
||||
"ERROR_MESSAGE": "Υπήρξε ένα σφάλμα, παρακαλώ προσπαθήστε ξανά"
|
||||
}
|
||||
},
|
||||
"LIST": {
|
||||
"LOADING_MESSAGE": "Φόρτωση καμπάνιας...",
|
||||
"404": "Δεν υπάρχουν εκστρατείες για αυτό το κιβώτιο εισερχόμενων.",
|
||||
"TABLE_HEADER": {
|
||||
"TITLE": "Τίτλος",
|
||||
"MESSAGE": "Μήνυμα",
|
||||
"STATUS": "Κατάσταση",
|
||||
"SENDER": "Αποστολέας",
|
||||
"URL": "URL",
|
||||
"TIME_ON_PAGE": "Χρόνος (δευτερόλεπτα)",
|
||||
"CREATED_AT": "Δημιουργήθηκε στις"
|
||||
},
|
||||
"BUTTONS": {
|
||||
"ADD": "Προσθήκη",
|
||||
"EDIT": "Επεξεργασία",
|
||||
"DELETE": "Διαγραφή"
|
||||
},
|
||||
"STATUS": {
|
||||
"ENABLED": "Ενεργό",
|
||||
"DISABLED": "Ανενεργό"
|
||||
},
|
||||
"SENDER": {
|
||||
"BOT": "Bot"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -80,6 +80,7 @@
|
|||
"RECEIVED_VIA_EMAIL": "Παραλήφθηκε από email",
|
||||
"VIEW_TWEET_IN_TWITTER": "Προβολή του tweet στο Twitter",
|
||||
"REPLY_TO_TWEET": "Απάντηση στο tweet",
|
||||
"NO_MESSAGES": "Κανένα Μήνυμα"
|
||||
"NO_MESSAGES": "Κανένα Μήνυμα",
|
||||
"NO_CONTENT": "Μη διαθέσιμο περιεχόμενο"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
"INITIATED_FROM": "Αρχικοποίηση από",
|
||||
"INITIATED_AT": "Αρχικοποίηση τις",
|
||||
"IP_ADDRESS": "Διεύθυνση IP",
|
||||
"NEW_MESSAGE": "New message",
|
||||
"NEW_MESSAGE": "Νέο Μήνυμα",
|
||||
"CONVERSATIONS": {
|
||||
"NO_RECORDS_FOUND": "Δεν υπάρχουν προηγούμενες συνομιλίες που σχετίζονται με αυτήν την επαφή.",
|
||||
"TITLE": "Προηγούμενες συνομιλίες"
|
||||
|
@ -28,11 +28,17 @@
|
|||
"INACTIVE_LABELS": "Υπάρχουν διαθέσιμες ετικέτες στον λογαριασμό",
|
||||
"REMOVE": "Πατήστε στο εικονίδιο X για να απομακρύνετε την ετικέτα",
|
||||
"ADD": "Πατήστε στο εικονίδιο + για να προσθέστε την ετικέτα",
|
||||
"ADD_BUTTON": "Add Labels",
|
||||
"UPDATE_BUTTON": "Ενημέρωση Ετικετών",
|
||||
"UPDATE_ERROR": "Δεν μπορούν να ενημερωθούν οι ετικέτες, προσπαθήστε ξανά."
|
||||
},
|
||||
"NO_LABELS_TO_ADD": "Δεν υπάρχουν άλλες ετικέτες στον λογαριασμό.",
|
||||
"NO_AVAILABLE_LABELS": "Δεν υπάρχουν προστεθεί ετικέτες στην συνομιλία."
|
||||
"NO_AVAILABLE_LABELS": "Δεν υπάρχουν προστεθεί ετικέτες στην συνομιλία.",
|
||||
"LABEL_SELECT": {
|
||||
"TITLE": "Add Labels",
|
||||
"PLACEHOLDER": "Search labels",
|
||||
"NO_RESULT": "No labels found"
|
||||
}
|
||||
},
|
||||
"MUTE_CONTACT": "Σίγαση Συνομιλίας",
|
||||
"UNMUTE_CONTACT": "Επαναφορά Συνομιλίας",
|
||||
|
@ -108,27 +114,27 @@
|
|||
"ERROR_MESSAGE": "Υπήρξε ένα σφάλμα, παρακαλώ προσπαθήστε ξανά"
|
||||
},
|
||||
"NEW_CONVERSATION": {
|
||||
"BUTTON_LABEL": "Start conversation",
|
||||
"BUTTON_LABEL": "Έναρξη Συνομιλίας",
|
||||
"TITLE": "Νέα συνομιλία",
|
||||
"DESC": "Start a new conversation by sending a new message.",
|
||||
"NO_INBOX": "Couldn't find an inbox to initiate a new conversation with this contact.",
|
||||
"DESC": "Ξεκινήστε μια νέα συνομιλία στέλνοντας ένα νέο μήνυμα.",
|
||||
"NO_INBOX": "Δεν βρέθηκε ένα κιβώτιο εισερχόμενων για να ξεκινήσει μια νέα συνομιλία με αυτήν την επαφή.",
|
||||
"FORM": {
|
||||
"TO": {
|
||||
"LABEL": "To"
|
||||
"LABEL": "Προς"
|
||||
},
|
||||
"INBOX": {
|
||||
"LABEL": "Inbox",
|
||||
"ERROR": "Select an inbox"
|
||||
"LABEL": "Εισερχόμενα",
|
||||
"ERROR": "Επιλέξτε ένα κιβώτιο εισερχόμενων"
|
||||
},
|
||||
"MESSAGE": {
|
||||
"LABEL": "Μήνυμα",
|
||||
"PLACEHOLDER": "Write your message here",
|
||||
"ERROR": "Message can't be empty"
|
||||
"PLACEHOLDER": "Γράψτε το μήνυμά σας εδώ",
|
||||
"ERROR": "Το μήνυμα δεν μπορεί να είναι άδειο"
|
||||
},
|
||||
"SUBMIT": "Send message",
|
||||
"SUBMIT": "Αποστολή μηνύματος",
|
||||
"CANCEL": "Άκυρο",
|
||||
"SUCCESS_MESSAGE": "Message sent!",
|
||||
"ERROR_MESSAGE": "Couldn't send! try again"
|
||||
"SUCCESS_MESSAGE": "Το μήνυμα στάλθηκε!",
|
||||
"ERROR_MESSAGE": "Αδυναμία αποστολής! Προσπαθήστε ξανά"
|
||||
}
|
||||
},
|
||||
"CONTACTS_PAGE": {
|
||||
|
@ -151,5 +157,18 @@
|
|||
},
|
||||
"VIEW_DETAILS": "Προβολή λεπτομεριών"
|
||||
}
|
||||
},
|
||||
"NOTES": {
|
||||
"HEADER": {
|
||||
"TITLE": "Σημειώσεις"
|
||||
},
|
||||
"ADD": {
|
||||
"BUTTON": "Προσθήκη",
|
||||
"PLACEHOLDER": "Προσθήκη σημείωσης",
|
||||
"TITLE": "Shift + Enter για δημιουργία σημείωσης"
|
||||
},
|
||||
"FOOTER": {
|
||||
"BUTTON": "Εμφάνιση όλων των σημειώσεων"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -92,7 +92,7 @@
|
|||
"DESC": "Ενσωματώστε το Twilio και αρχίστε να υποστηρίζετε τους πελάτες σας μέσω SMS.",
|
||||
"ACCOUNT_SID": {
|
||||
"LABEL": "SID Λογαριασμού",
|
||||
"PLACEHOLDER": "Παρακαλώ εισάγετε το SID του Λογαριασμού Twillio",
|
||||
"PLACEHOLDER": "Παρακαλώ εισάγετε το SID του Λογαριασμού Twilio",
|
||||
"ERROR": "Το πεδίο είναι απαραίτητο"
|
||||
},
|
||||
"CHANNEL_TYPE": {
|
||||
|
@ -118,7 +118,7 @@
|
|||
"TITLE": "URL επανάκλησης",
|
||||
"SUBTITLE": "Πρέπει να ρυθμίσετε το callback URL στο Twilio με το URL που αναφέρεται εδώ."
|
||||
},
|
||||
"SUBMIT_BUTTON": "Δημιουργία Καναλιού Twillio",
|
||||
"SUBMIT_BUTTON": "Δημιουργία Καναλιού Twilio",
|
||||
"API": {
|
||||
"ERROR_MESSAGE": "Δεν ήταν δυνατή η πιστοποίηση των διαπιστευτηρίων Twilio. Δοκιμάστε ξανά"
|
||||
}
|
||||
|
@ -227,6 +227,7 @@
|
|||
"SETTINGS": "Ρυθμίσεις",
|
||||
"COLLABORATORS": "Συνεργάτες",
|
||||
"CONFIGURATION": "Διαμόρφωση",
|
||||
"CAMPAIGN": "Καμπάνιες",
|
||||
"PRE_CHAT_FORM": "Φόρμα Προ-Συνομιλίας",
|
||||
"BUSINESS_HOURS": "Ώρες Εργασίας"
|
||||
},
|
||||
|
|
|
@ -1,33 +1,37 @@
|
|||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _labelsMgmt } from './labelsMgmt.json';
|
||||
import { default as _campaign } from './campaign.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
import { default as _conversation } from './conversation.json';
|
||||
import { default as _generalSettings } from './generalSettings.json';
|
||||
import { default as _inboxMgmt } from './inboxMgmt.json';
|
||||
import { default as _integrations } from './integrations.json';
|
||||
import { default as _labelsMgmt } from './labelsMgmt.json';
|
||||
import { default as _login } from './login.json';
|
||||
import { default as _report } from './report.json';
|
||||
import { default as _resetPassword } from './resetPassword.json';
|
||||
import { default as _setNewPassword } from './setNewPassword.json';
|
||||
import { default as _settings } from './settings.json';
|
||||
import { default as _signup } from './signup.json';
|
||||
import { default as _integrations } from './integrations.json';
|
||||
import { default as _generalSettings } from './generalSettings.json';
|
||||
import { default as _teamsSettings } from './teamsSettings.json';
|
||||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._campaign,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
..._conversation,
|
||||
..._generalSettings,
|
||||
..._inboxMgmt,
|
||||
..._integrations,
|
||||
..._labelsMgmt,
|
||||
..._login,
|
||||
..._report,
|
||||
..._labelsMgmt,
|
||||
..._resetPassword,
|
||||
..._setNewPassword,
|
||||
..._settings,
|
||||
..._signup,
|
||||
..._integrations,
|
||||
..._generalSettings,
|
||||
..._teamsSettings,
|
||||
};
|
||||
|
|
|
@ -38,6 +38,18 @@
|
|||
{
|
||||
"id": 1,
|
||||
"name": "Τελευταίες 30 ημέρες"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Τελευταίοι 3 μήνες"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Τελευταίοι 6 μήνες"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Τελευταίο έτος"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
79
app/javascript/dashboard/i18n/locale/en/campaign.json
Normal file
79
app/javascript/dashboard/i18n/locale/en/campaign.json
Normal file
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"CAMPAIGN": {
|
||||
"HEADER": "Campaigns",
|
||||
"SIDEBAR_TXT": "Proactive messages allow the customer to send outbound messages to their contacts which would trigger more conversations. Click on <b>Add Campaign</b> to create a new campaign. You can also edit or delete an existing campaign by clicking on the Edit or Delete button.",
|
||||
"HEADER_BTN_TXT": "Create a campaign",
|
||||
"ADD": {
|
||||
"TITLE": "Create a campaign",
|
||||
"DESC": "Proactive messages allow the customer to send outbound messages to their contacts which would trigger more conversations.",
|
||||
"CANCEL_BUTTON_TEXT": "Cancel",
|
||||
"CREATE_BUTTON_TEXT": "Create",
|
||||
"FORM": {
|
||||
"TITLE": {
|
||||
"LABEL": "Title",
|
||||
"PLACEHOLDER": "Please enter the title of campaign",
|
||||
"ERROR": "Title is required"
|
||||
},
|
||||
"MESSAGE": {
|
||||
"LABEL": "Message",
|
||||
"PLACEHOLDER": "Please enter the message of campaign",
|
||||
"ERROR": "Message is required"
|
||||
},
|
||||
"SENT_BY": {
|
||||
"LABEL": "Sent by",
|
||||
"PLACEHOLDER": "Please select the the content of campaign",
|
||||
"ERROR": "Sender is required"
|
||||
},
|
||||
"END_POINT": {
|
||||
"LABEL": "URL",
|
||||
"PLACEHOLDER": "Please enter the URL",
|
||||
"ERROR": "Please enter a valid URL"
|
||||
},
|
||||
"TIME_ON_PAGE": {
|
||||
"LABEL": "Time on page(Seconds)",
|
||||
"PLACEHOLDER": "Please enter the time",
|
||||
"ERROR": "Time on page is required"
|
||||
},
|
||||
"ENABLED": "Enable campaign",
|
||||
"SUBMIT": "Add Campaign"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Campaign created successfully",
|
||||
"ERROR_MESSAGE": "There was an error. Please try again."
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Edit campaign",
|
||||
"UPDATE_BUTTON_TEXT": "Update",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Campaign updated successfully",
|
||||
"ERROR_MESSAGE": "There was an error, please try again"
|
||||
}
|
||||
},
|
||||
"LIST": {
|
||||
"LOADING_MESSAGE": "Loading campaigns...",
|
||||
"404": "There are no campaigns created for this inbox.",
|
||||
"TABLE_HEADER": {
|
||||
"TITLE": "Title",
|
||||
"MESSAGE": "Message",
|
||||
"STATUS": "Status",
|
||||
"SENDER": "Sender",
|
||||
"URL": "URL",
|
||||
"TIME_ON_PAGE": "Time(Seconds)",
|
||||
"CREATED_AT": "Created at"
|
||||
},
|
||||
"BUTTONS": {
|
||||
"ADD": "Add",
|
||||
"EDIT": "Edit",
|
||||
"DELETE": "Delete"
|
||||
},
|
||||
"STATUS": {
|
||||
"ENABLED": "Enabled",
|
||||
"DISABLED": "Disabled"
|
||||
},
|
||||
"SENDER": {
|
||||
"BOT": "Bot"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -80,6 +80,7 @@
|
|||
"RECEIVED_VIA_EMAIL": "Received via email",
|
||||
"VIEW_TWEET_IN_TWITTER": "View tweet in Twitter",
|
||||
"REPLY_TO_TWEET": "Reply to this tweet",
|
||||
"NO_MESSAGES": "No Messages"
|
||||
"NO_MESSAGES": "No Messages",
|
||||
"NO_CONTENT": "No content available"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,11 +28,17 @@
|
|||
"INACTIVE_LABELS": "Labels available in the account",
|
||||
"REMOVE": "Click on X icon to remove the label",
|
||||
"ADD": "Click on + icon to add the label",
|
||||
"ADD_BUTTON": "Add Labels",
|
||||
"UPDATE_BUTTON": "Update labels",
|
||||
"UPDATE_ERROR": "Couldn't update labels, try again."
|
||||
},
|
||||
"NO_LABELS_TO_ADD": "There are no more labels defined in the account.",
|
||||
"NO_AVAILABLE_LABELS": "There are no labels added to this conversation."
|
||||
"NO_AVAILABLE_LABELS": "There are no labels added to this conversation.",
|
||||
"LABEL_SELECT": {
|
||||
"TITLE": "Add Labels",
|
||||
"PLACEHOLDER": "Search labels",
|
||||
"NO_RESULT": "No labels found"
|
||||
}
|
||||
},
|
||||
"MUTE_CONTACT": "Mute Conversation",
|
||||
"UNMUTE_CONTACT": "Unmute Conversation",
|
||||
|
@ -151,5 +157,18 @@
|
|||
},
|
||||
"VIEW_DETAILS": "View details"
|
||||
}
|
||||
},
|
||||
"NOTES": {
|
||||
"HEADER": {
|
||||
"TITLE": "Notes"
|
||||
},
|
||||
"ADD": {
|
||||
"BUTTON": "Add",
|
||||
"PLACEHOLDER": "Add a note",
|
||||
"TITLE": "Shift + Enter to create a note"
|
||||
},
|
||||
"FOOTER": {
|
||||
"BUTTON": "View all notes"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
"SETTINGS": "Settings",
|
||||
"COLLABORATORS": "Collaborators",
|
||||
"CONFIGURATION": "Configuration",
|
||||
"CAMPAIGN": "Campaigns",
|
||||
"PRE_CHAT_FORM": "Pre Chat Form",
|
||||
"BUSINESS_HOURS": "Business Hours"
|
||||
},
|
||||
|
|
|
@ -1,35 +1,37 @@
|
|||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _labelsMgmt } from './labelsMgmt.json';
|
||||
import { default as _campaign } from './campaign.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
import { default as _conversation } from './conversation.json';
|
||||
import { default as _generalSettings } from './generalSettings.json';
|
||||
import { default as _inboxMgmt } from './inboxMgmt.json';
|
||||
import { default as _integrations } from './integrations.json';
|
||||
import { default as _labelsMgmt } from './labelsMgmt.json';
|
||||
import { default as _login } from './login.json';
|
||||
import { default as _report } from './report.json';
|
||||
import { default as _resetPassword } from './resetPassword.json';
|
||||
import { default as _setNewPassword } from './setNewPassword.json';
|
||||
import { default as _settings } from './settings.json';
|
||||
import { default as _signup } from './signup.json';
|
||||
import { default as _integrations } from './integrations.json';
|
||||
import { default as _generalSettings } from './generalSettings.json';
|
||||
import { default as _teamsSettings } from './teamsSettings.json';
|
||||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._campaign,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
..._conversation,
|
||||
..._generalSettings,
|
||||
..._inboxMgmt,
|
||||
..._integrations,
|
||||
..._labelsMgmt,
|
||||
..._login,
|
||||
..._report,
|
||||
..._labelsMgmt,
|
||||
..._resetPassword,
|
||||
..._setNewPassword,
|
||||
..._settings,
|
||||
..._signup,
|
||||
..._integrations,
|
||||
..._generalSettings,
|
||||
..._teamsSettings,
|
||||
};
|
||||
|
|
|
@ -38,6 +38,18 @@
|
|||
{
|
||||
"id": 1,
|
||||
"name": "Last 30 days"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Last 3 months"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Last 6 months"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Last year"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
79
app/javascript/dashboard/i18n/locale/es/campaign.json
Normal file
79
app/javascript/dashboard/i18n/locale/es/campaign.json
Normal file
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"CAMPAIGN": {
|
||||
"HEADER": "Campañas",
|
||||
"SIDEBAR_TXT": "Los mensajes proactivos permiten al cliente enviar mensajes a sus contactos, lo que generaría más conversaciones. Haga clic en <b>Añadir Campaña</b> para crear una nueva campaña. También puede editar o borrar una campaña existente haciendo clic en el botón de Editar o Borrar.",
|
||||
"HEADER_BTN_TXT": "Crear campaña",
|
||||
"ADD": {
|
||||
"TITLE": "Crear campaña",
|
||||
"DESC": "Los mensajes proactivos permiten al cliente enviar mensajes a sus contactos, lo que generaría más conversaciones.",
|
||||
"CANCEL_BUTTON_TEXT": "Cancelar",
|
||||
"CREATE_BUTTON_TEXT": "Crear",
|
||||
"FORM": {
|
||||
"TITLE": {
|
||||
"LABEL": "Título",
|
||||
"PLACEHOLDER": "Por favor escriba un título para la campaña",
|
||||
"ERROR": "El título es obligatorio"
|
||||
},
|
||||
"MESSAGE": {
|
||||
"LABEL": "Mensaje",
|
||||
"PLACEHOLDER": "Por favor escriba el mensaje para la campaña",
|
||||
"ERROR": "El mensaje es obligatorio"
|
||||
},
|
||||
"SENT_BY": {
|
||||
"LABEL": "Enviado por",
|
||||
"PLACEHOLDER": "Por favor seleccione el contenido de la campaña",
|
||||
"ERROR": "El remitente es obligatorio"
|
||||
},
|
||||
"END_POINT": {
|
||||
"LABEL": "URL",
|
||||
"PLACEHOLDER": "Por favor escriba el URL",
|
||||
"ERROR": "Por favor, introduzca una URL válida"
|
||||
},
|
||||
"TIME_ON_PAGE": {
|
||||
"LABEL": "Tiempo en la página (segundos)",
|
||||
"PLACEHOLDER": "Por favor escriba la hora",
|
||||
"ERROR": "La hora en la página es obligatoria"
|
||||
},
|
||||
"ENABLED": "Habilitar campaña",
|
||||
"SUBMIT": "Añadir campaña"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "campaña creada satisfactoriamente",
|
||||
"ERROR_MESSAGE": "Se presentó un error. Por favor intente nuevamente."
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Editar campaña",
|
||||
"UPDATE_BUTTON_TEXT": "Actualizar",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Campaña actualizada satisfactoriamente",
|
||||
"ERROR_MESSAGE": "Hubo un error, por favor inténtelo de nuevo"
|
||||
}
|
||||
},
|
||||
"LIST": {
|
||||
"LOADING_MESSAGE": "Cargando campañas...",
|
||||
"404": "No hay campañas creadas en esta bandeja.",
|
||||
"TABLE_HEADER": {
|
||||
"TITLE": "Título",
|
||||
"MESSAGE": "Mensaje",
|
||||
"STATUS": "Estado",
|
||||
"SENDER": "Remitente",
|
||||
"URL": "URL",
|
||||
"TIME_ON_PAGE": "Tiempo (segundos)",
|
||||
"CREATED_AT": "Creado el"
|
||||
},
|
||||
"BUTTONS": {
|
||||
"ADD": "Añadir",
|
||||
"EDIT": "Editar",
|
||||
"DELETE": "Eliminar"
|
||||
},
|
||||
"STATUS": {
|
||||
"ENABLED": "Activado",
|
||||
"DISABLED": "Deshabilitado"
|
||||
},
|
||||
"SENDER": {
|
||||
"BOT": "Bot"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -80,6 +80,7 @@
|
|||
"RECEIVED_VIA_EMAIL": "Recibido por correo electrónico",
|
||||
"VIEW_TWEET_IN_TWITTER": "Ver trino en Twitter",
|
||||
"REPLY_TO_TWEET": "Responder a éste trino",
|
||||
"NO_MESSAGES": "No hay mensajes"
|
||||
"NO_MESSAGES": "No hay mensajes",
|
||||
"NO_CONTENT": "No hay contenido disponible"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,11 +28,17 @@
|
|||
"INACTIVE_LABELS": "Etiquetas disponibles en la cuenta",
|
||||
"REMOVE": "Haga clic en el icono X para quitar la etiqueta",
|
||||
"ADD": "Haga clic en el icono + para añadir la etiqueta",
|
||||
"ADD_BUTTON": "Añadir etiquetas",
|
||||
"UPDATE_BUTTON": "Actualizar etiquetas",
|
||||
"UPDATE_ERROR": "No se han podido actualizar las etiquetas, inténtelo de nuevo."
|
||||
},
|
||||
"NO_LABELS_TO_ADD": "No hay más etiquetas definidas en la cuenta.",
|
||||
"NO_AVAILABLE_LABELS": "No hay etiquetas añadidas a esta conversación."
|
||||
"NO_AVAILABLE_LABELS": "No hay etiquetas añadidas a esta conversación.",
|
||||
"LABEL_SELECT": {
|
||||
"TITLE": "Añadir etiquetas",
|
||||
"PLACEHOLDER": "Buscar etiquetas",
|
||||
"NO_RESULT": "No se encontraron etiquetas"
|
||||
}
|
||||
},
|
||||
"MUTE_CONTACT": "Silenciar Conversación",
|
||||
"UNMUTE_CONTACT": "Dessilenciar conversación",
|
||||
|
@ -151,5 +157,18 @@
|
|||
},
|
||||
"VIEW_DETAILS": "Ver detalles"
|
||||
}
|
||||
},
|
||||
"NOTES": {
|
||||
"HEADER": {
|
||||
"TITLE": "Notas"
|
||||
},
|
||||
"ADD": {
|
||||
"BUTTON": "Añadir",
|
||||
"PLACEHOLDER": "Añadir nota",
|
||||
"TITLE": "Shift + Enter para crear una nota"
|
||||
},
|
||||
"FOOTER": {
|
||||
"BUTTON": "Ver todas las notas"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"TITLE": "Buscar mensajes",
|
||||
"LOADING_MESSAGE": "Cruzando datos...",
|
||||
"PLACEHOLDER": "Escriba cualquier texto para buscar mensajes",
|
||||
"NO_MATCHING_RESULTS": "No results found."
|
||||
"NO_MATCHING_RESULTS": "No se encontraron resultados."
|
||||
},
|
||||
"UNREAD_MESSAGES": "Mensajes no leídos",
|
||||
"UNREAD_MESSAGE": "Mensaje sin leer",
|
||||
|
@ -57,7 +57,7 @@
|
|||
"VISIBLE_TO_AGENTS": "Nota privada: solo visible para ti y tu equipo",
|
||||
"CHANGE_STATUS": "Estado de la conversación cambiado",
|
||||
"CHANGE_AGENT": "Conversación cambiada de asignatario",
|
||||
"CHANGE_TEAM": "Conversation team changed",
|
||||
"CHANGE_TEAM": "Equipo de conversación cambiado",
|
||||
"FILE_SIZE_LIMIT": "El archivo excede el límite de los archivos adjuntos {MAXIMUM_FILE_UPLOAD_SIZE}",
|
||||
"SENT_BY": "Enviado por:",
|
||||
"ASSIGNMENT": {
|
||||
|
@ -108,11 +108,11 @@
|
|||
}
|
||||
},
|
||||
"CONVERSATION_SIDEBAR": {
|
||||
"DETAILS_TITLE": "Conversations Details",
|
||||
"ASSIGNEE_LABEL": "Assigned Agent",
|
||||
"TEAM_LABEL": "Assigned Team",
|
||||
"DETAILS_TITLE": "Detalles de la conversación",
|
||||
"ASSIGNEE_LABEL": "Agente asignado",
|
||||
"TEAM_LABEL": "Equipo asignado",
|
||||
"SELECT": {
|
||||
"PLACEHOLDER": "None"
|
||||
"PLACEHOLDER": "Ninguna"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -227,6 +227,7 @@
|
|||
"SETTINGS": "Ajustes",
|
||||
"COLLABORATORS": "Colaboradores",
|
||||
"CONFIGURATION": "Configuración",
|
||||
"CAMPAIGN": "Campañas",
|
||||
"PRE_CHAT_FORM": "Pre-formulario de chat",
|
||||
"BUSINESS_HOURS": "Horarios"
|
||||
},
|
||||
|
|
|
@ -1,33 +1,37 @@
|
|||
import { default as _agentMgmt } from './agentMgmt.json';
|
||||
import { default as _labelsMgmt } from './labelsMgmt.json';
|
||||
import { default as _campaign } from './campaign.json';
|
||||
import { default as _cannedMgmt } from './cannedMgmt.json';
|
||||
import { default as _chatlist } from './chatlist.json';
|
||||
import { default as _contact } from './contact.json';
|
||||
import { default as _conversation } from './conversation.json';
|
||||
import { default as _generalSettings } from './generalSettings.json';
|
||||
import { default as _inboxMgmt } from './inboxMgmt.json';
|
||||
import { default as _integrations } from './integrations.json';
|
||||
import { default as _labelsMgmt } from './labelsMgmt.json';
|
||||
import { default as _login } from './login.json';
|
||||
import { default as _report } from './report.json';
|
||||
import { default as _resetPassword } from './resetPassword.json';
|
||||
import { default as _setNewPassword } from './setNewPassword.json';
|
||||
import { default as _settings } from './settings.json';
|
||||
import { default as _signup } from './signup.json';
|
||||
import { default as _integrations } from './integrations.json';
|
||||
import { default as _generalSettings } from './generalSettings.json';
|
||||
import { default as _teamsSettings } from './teamsSettings.json';
|
||||
|
||||
export default {
|
||||
..._agentMgmt,
|
||||
..._campaign,
|
||||
..._cannedMgmt,
|
||||
..._chatlist,
|
||||
..._contact,
|
||||
..._conversation,
|
||||
..._generalSettings,
|
||||
..._inboxMgmt,
|
||||
..._integrations,
|
||||
..._labelsMgmt,
|
||||
..._login,
|
||||
..._report,
|
||||
..._labelsMgmt,
|
||||
..._resetPassword,
|
||||
..._setNewPassword,
|
||||
..._settings,
|
||||
..._signup,
|
||||
..._integrations,
|
||||
..._generalSettings,
|
||||
..._teamsSettings,
|
||||
};
|
||||
|
|
|
@ -38,6 +38,18 @@
|
|||
{
|
||||
"id": 1,
|
||||
"name": "Últimos 30 días"
|
||||
},
|
||||
{
|
||||
"id": 2,
|
||||
"name": "Últimos 3 meses"
|
||||
},
|
||||
{
|
||||
"id": 3,
|
||||
"name": "Últimos 6 meses"
|
||||
},
|
||||
{
|
||||
"id": 4,
|
||||
"name": "Último año"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"LINK": "Ajustes del perfil",
|
||||
"TITLE": "Ajustes del perfil",
|
||||
"BTN_TEXT": "Actualizar perfil",
|
||||
"UPDATE_SUCCESS": "Your profile has been updated successfully",
|
||||
"UPDATE_SUCCESS": "Tu perfil se ha actualizado correctamente",
|
||||
"PASSWORD_UPDATE_SUCCESS": "Su contraseña se ha cambiado correctamente",
|
||||
"AFTER_EMAIL_CHANGED": "Su perfil ha sido actualizado con éxito, por favor inicie sesión de nuevo cuando sus credenciales de inicio de sesión se hayan cambiado",
|
||||
"FORM": {
|
||||
|
@ -19,7 +19,7 @@
|
|||
"PASSWORD_SECTION": {
|
||||
"TITLE": "Contraseña",
|
||||
"NOTE": "Actualizar tu contraseña restablecería tus entradas en varios dispositivos.",
|
||||
"BTN_TEXT": "Change password"
|
||||
"BTN_TEXT": "Cambiar contraseña"
|
||||
},
|
||||
"ACCESS_TOKEN": {
|
||||
"TITLE": "Token de acceso",
|
||||
|
|
79
app/javascript/dashboard/i18n/locale/fa/campaign.json
Normal file
79
app/javascript/dashboard/i18n/locale/fa/campaign.json
Normal file
|
@ -0,0 +1,79 @@
|
|||
{
|
||||
"CAMPAIGN": {
|
||||
"HEADER": "Campaigns",
|
||||
"SIDEBAR_TXT": "Proactive messages allow the customer to send outbound messages to their contacts which would trigger more conversations. Click on <b>Add Campaign</b> to create a new campaign. You can also edit or delete an existing campaign by clicking on the Edit or Delete button.",
|
||||
"HEADER_BTN_TXT": "Create a campaign",
|
||||
"ADD": {
|
||||
"TITLE": "Create a campaign",
|
||||
"DESC": "Proactive messages allow the customer to send outbound messages to their contacts which would trigger more conversations.",
|
||||
"CANCEL_BUTTON_TEXT": "انصراف",
|
||||
"CREATE_BUTTON_TEXT": "ايجاد كردن",
|
||||
"FORM": {
|
||||
"TITLE": {
|
||||
"LABEL": "عنوان",
|
||||
"PLACEHOLDER": "Please enter the title of campaign",
|
||||
"ERROR": "Title is required"
|
||||
},
|
||||
"MESSAGE": {
|
||||
"LABEL": "پیام",
|
||||
"PLACEHOLDER": "Please enter the message of campaign",
|
||||
"ERROR": "Message is required"
|
||||
},
|
||||
"SENT_BY": {
|
||||
"LABEL": "ارسال شده توسط",
|
||||
"PLACEHOLDER": "Please select the the content of campaign",
|
||||
"ERROR": "Sender is required"
|
||||
},
|
||||
"END_POINT": {
|
||||
"LABEL": "URL",
|
||||
"PLACEHOLDER": "Please enter the URL",
|
||||
"ERROR": "لطفا آدرس URL صحیحی وارد کنید"
|
||||
},
|
||||
"TIME_ON_PAGE": {
|
||||
"LABEL": "Time on page(Seconds)",
|
||||
"PLACEHOLDER": "Please enter the time",
|
||||
"ERROR": "Time on page is required"
|
||||
},
|
||||
"ENABLED": "Enable campaign",
|
||||
"SUBMIT": "Add Campaign"
|
||||
},
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Campaign created successfully",
|
||||
"ERROR_MESSAGE": "There was an error. Please try again."
|
||||
}
|
||||
},
|
||||
"EDIT": {
|
||||
"TITLE": "Edit campaign",
|
||||
"UPDATE_BUTTON_TEXT": "اعمال شود",
|
||||
"API": {
|
||||
"SUCCESS_MESSAGE": "Campaign updated successfully",
|
||||
"ERROR_MESSAGE": "خطایی پیش آمد. لطفا دوباره امتحان کنید"
|
||||
}
|
||||
},
|
||||
"LIST": {
|
||||
"LOADING_MESSAGE": "Loading campaigns...",
|
||||
"404": "There are no campaigns created for this inbox.",
|
||||
"TABLE_HEADER": {
|
||||
"TITLE": "عنوان",
|
||||
"MESSAGE": "پیام",
|
||||
"STATUS": "وضعیت",
|
||||
"SENDER": "Sender",
|
||||
"URL": "URL",
|
||||
"TIME_ON_PAGE": "Time(Seconds)",
|
||||
"CREATED_AT": "Created at"
|
||||
},
|
||||
"BUTTONS": {
|
||||
"ADD": "افزودن",
|
||||
"EDIT": "ویرایش",
|
||||
"DELETE": "حذف"
|
||||
},
|
||||
"STATUS": {
|
||||
"ENABLED": "فعال",
|
||||
"DISABLED": "غیرفعال"
|
||||
},
|
||||
"SENDER": {
|
||||
"BOT": "ربات"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue