diff --git a/.circleci/config.yml b/.circleci/config.yml index 69ceb2772..e287574e9 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -7,7 +7,7 @@ defaults: &defaults working_directory: ~/build docker: # specify the version you desire here - - image: cimg/ruby:3.1.3-browsers + - image: cimg/ruby:3.2.2-browsers # Specify service dependencies here if necessary # CircleCI maintains a library of pre-built images diff --git a/.devcontainer/Dockerfile.base b/.devcontainer/Dockerfile.base index c0beb9eed..c9e3c8fcf 100644 --- a/.devcontainer/Dockerfile.base +++ b/.devcontainer/Dockerfile.base @@ -30,7 +30,7 @@ RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ npm # Install rbenv and ruby -ARG RUBY_VERSION="3.1.3" +ARG RUBY_VERSION="3.2.2" RUN git clone https://github.com/rbenv/rbenv.git ~/.rbenv \ && echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc \ && echo 'eval "$(rbenv init -)"' >> ~/.bashrc diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 26b053b5f..000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,78 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: 'Bug' -assignees: '' - ---- - -**Describe the bug** - -A clear and concise description of what the bug is. - -**To Reproduce** - -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See the error - -**Expected behavior** - -Share a clear and concise description of what you expected to happen. - -**Screenshots** - -If applicable, add screenshots to help explain your problem. - -**Browser logs** - -Share the browser logs to debug the issue further. - -**Server logs** - -Share the server logs to debug the issue further. - -**Environment** - -Describe whether you are using Chatwoot Cloud (app.chatwoot.com) or a self-hosted installation of Chatwoot. If you are using a self-hosted installation of Chatwoot, describe the type of deployment (Docker/Linux VM installation/Heroku/Kubernetes/Other). - -- [ ] app.chatwoot.com (Chatwoot Cloud) -- [ ] Self-hosted -- - [ ] Linux VM -- - [ ] Docker -- - [ ] Kubernetes -- - [ ] Heroku -- - [ ] Other (Please specify) - - -**Desktop (please complete the following information)** (If applicable) - - OS: [e.g. Linux, Windows, MacOS] - - Browser [e.g. chrome, firefox, safari] - - Version [e.g. 22] - -**Smartphone (please complete the following information)** (If applicable) - - Device: [e.g. iPhone6, Pixel7] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, firefox, safari] - - Version [e.g. 22] - -**Docker** (If applicable) - -Please share the output of the following. -- `docker version` -- `docker info` -- `docker-compose version` - -**Cloud Provider** (If applicable) -- [ ] AWS -- [ ] GCP -- [ ] Azure -- [ ] DigitalOcean -- [ ] Others - -**Additional context** - -Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 000000000..a0c213dde --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,78 @@ +name: 🐞 Bug report +description: Create a report to help us improve +labels: 'Bug' +body: + - type: textarea + attributes: + label: Describe the bug + description: A concise description of what you expected to happen along with screenshots if applicable. + validations: + required: true + - type: textarea + attributes: + label: To Reproduce + description: Steps to reproduce the behavior. + placeholder: | + 1. In this environment... + 2. With this config... + 3. Run '...' + 4. See error... + validations: + required: true + - type: textarea + attributes: + label: Expected behavior + description: A concise description of what you expected to happen. + - type: dropdown + id: environment + attributes: + label: Environment + description: Describe whether you are using Chatwoot Cloud (app.chatwoot.com) or a self-hosted installation of Chatwoot. If you are using a self-hosted installation of Chatwoot, describe the type of deployment (Docker/Linux VM installation/Heroku/Kubernetes/Other). + options: + - app.chatwoot.com + - Linux VM + - Docker + - Kubernetes + - Heroku + - Other [please specify in the description] + validations: + required: true + - type: dropdown + id: provider + attributes: + label: Cloud Provider + description: + options: + - AWS + - GCP + - Azure + - DigitalOcean + - Other [please specify in the description] + - type: dropdown + id: platform + attributes: + label: Platform + description: Describe the platform you are using + options: + - Browser + - Mobile + - type: input + attributes: + label: Operating system + description: The operating system and the version you are using. + - type: input + attributes: + label: Browser and version + description: The name of the browser and version you are using. + - type: textarea + attributes: + label: Docker (if applicable) + description: | + Please share the output of the following. + - `docker version` + - `docker info` + - `docker-compose version` + - type: textarea + attributes: + label: Additional context + description: Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 000000000..306f5e4a1 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Report a security issue + url: https://www.chatwoot.com/docs/contributing-guide/security-reports/ + about: Guidelines and steps to report a security vulnerability. Please report security vulnerabilities here. + - name: Product Documentation + url: https://www.chatwoot.com/help-center + about: If you have questions, are confused, or just want to understand our product better, please check out our documentation. diff --git a/.github/ISSUE_TEMPLATE/enhancement_request.md b/.github/ISSUE_TEMPLATE/enhancement_request.md deleted file mode 100644 index da1995668..000000000 --- a/.github/ISSUE_TEMPLATE/enhancement_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Enhancement request -about: Suggest any enhancements for this project -title: '' -labels: '' -assignees: '' - ---- - -**Is your enhancement request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions you've considered. - -**Additional context** -Add any other context or screenshots about the enhancement request here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index bbcbbe7d6..000000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: '' -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.yml b/.github/ISSUE_TEMPLATE/feature_request.yml new file mode 100644 index 000000000..f549bccd7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.yml @@ -0,0 +1,28 @@ +name: 🧙 Feature request +description: Suggest an idea for this project +labels: 'feature-request' +body: + - type: textarea + attributes: + label: Is your feature or enhancement related to a problem? Please describe. + description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + validations: + required: true + - type: textarea + attributes: + label: Describe the solution you'd like + description: A clear and concise description of what you want to happen. + validations: + required: true + - type: textarea + attributes: + label: Describe alternatives you've considered + description: A clear and concise description of any alternative solutions or features you've considered. + validations: + required: false + - type: textarea + attributes: + label: Additional context + description: Add any other context or screenshots about the feature request here. + validations: + required: false diff --git a/.gitignore b/.gitignore index e59f13b8f..82f4a4df5 100644 --- a/.gitignore +++ b/.gitignore @@ -67,3 +67,10 @@ test/cypress/videos/* # yalc for local testing .yalc yalc.lock + +/public/packs +/public/packs-test +/node_modules +/yarn-error.log +yarn-debug.log* +.yarn-integrity diff --git a/.rubocop.yml b/.rubocop.yml index 8b41dd5fd..70c927242 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -71,6 +71,10 @@ Rails/ApplicationController: - 'app/controllers/platform_controller.rb' - 'app/controllers/public_controller.rb' - 'app/controllers/survey/responses_controller.rb' +Rails/FindEach: + Enabled: true + Include: + - 'app/**/*.rb' Rails/CompactBlank: Enabled: false Rails/EnvironmentVariableAccess: @@ -160,6 +164,39 @@ Performance/CollectionLiteralInLoop: - 'db/migrate/20210315101919_enable_email_channel.rb' RSpec/NamedSubject: Enabled: false +Style/RedundantConstantBase: + Enabled: false +Rails/RootPathnameMethods: + Enabled: false +RSpec/Rails/MinitestAssertions: + Enabled: false +RSpec/Rails/InferredSpecType: + Enabled: false +RSpec/IndexedLet: + Enabled: false +RSpec/MatchArray: + Enabled: false +Rails/ResponseParsedBody: + Enabled: false +RSpec/FactoryBot/ConsistentParenthesesStyle: + Enabled: false +Rails/ThreeStateBooleanColumn: + Enabled: false +Rails/Pluck: + Enabled: false +Rails/TopLevelHashWithIndifferentAccess: + Enabled: false +Rails/ActionOrder: + Enabled: false +Style/ArrayIntersect: + Enabled: false +RSpec/NoExpectationExample: + Enabled: false +Style/RedundantReturn: + Enabled: false +Rails/I18nLocaleTexts: + Enabled: false + # we should bring this down RSpec/MultipleMemoizedHelpers: Max: 14 diff --git a/.ruby-version b/.ruby-version index ff365e06b..be94e6f53 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -3.1.3 +3.2.2 diff --git a/.slugignore b/.slugignore new file mode 100644 index 000000000..eaecc7e34 --- /dev/null +++ b/.slugignore @@ -0,0 +1 @@ +/spec diff --git a/Gemfile b/Gemfile index 7a61c39fe..d635d3809 100644 --- a/Gemfile +++ b/Gemfile @@ -1,10 +1,10 @@ source 'https://rubygems.org' -ruby '3.1.3' +ruby '3.2.2' ##-- base gems for rails --## gem 'rack-cors', require: 'rack/cors' -gem 'rails', '~> 6.1', '>= 6.1.7.3' +gem 'rails', '~> 7' # Reduces boot times through caching; required in config/boot.rb gem 'bootsnap', require: false @@ -36,19 +36,19 @@ gem 'json_schemer' # Rack middleware for blocking & throttling abusive requests gem 'rack-attack' # a utility tool for streaming, flexible and safe downloading of remote files -gem 'down', '~> 5.0' +gem 'down' # authentication type to fetch and send mail over oauth2.0 gem 'gmail_xoauth' # Prevent CSV injection gem 'csv-safe' -# Support message translation -gem 'google-cloud-translate' ##-- for active storage --## gem 'aws-sdk-s3', require: false -gem 'azure-storage-blob', require: false +# original gem isn't maintained actively +# we wanted updated version of faraday which is a dependency for slack-ruby-client +gem 'azure-storage-blob', git: 'https://github.com/chatwoot/azure-storage-ruby', branch: 'chatwoot', require: false gem 'google-cloud-storage', require: false -gem 'image_processing', '~> 1.12.2' +gem 'image_processing' ##-- gems for database --# gem 'groupdate' @@ -62,13 +62,13 @@ gem 'activerecord-import' gem 'dotenv-rails' gem 'foreman' gem 'puma' -gem 'webpacker', '~> 5.4', '>= 5.4.3' +gem 'webpacker' # metrics on heroku gem 'barnes' ##--- gems for authentication & authorization ---## gem 'devise' -gem 'devise-secure_password', '~> 2.0', git: 'https://github.com/chatwoot/devise-secure_password' +gem 'devise-secure_password', git: 'https://github.com/chatwoot/devise-secure_password', branch: 'chatwoot' gem 'devise_token_auth' # authorization gem 'jwt' @@ -81,7 +81,6 @@ gem 'administrate' gem 'wisper', '2.0.0' ##--- gems for channels ---## -# TODO: bump up gem to 2.0 gem 'facebook-messenger' gem 'line-bot-api' gem 'twilio-ruby', '~> 5.66' @@ -91,9 +90,14 @@ gem 'twitty', '~> 0.1.5' # facebook client gem 'koala' # slack client -gem 'slack-ruby-client' +gem 'slack-ruby-client', '~> 2.0.0' # for dialogflow integrations -gem 'google-cloud-dialogflow' +gem 'google-cloud-dialogflow-v2' +gem 'grpc' +# Translate integrations +# 'google-cloud-translate' gem depends on faraday 2.0 version +# this dependency breaks the slack-ruby-client gem +gem 'google-cloud-translate-v3' ##-- apm and error monitoring ---# # loaded only when environment variables are set. @@ -108,9 +112,9 @@ gem 'sentry-ruby', require: false gem 'sentry-sidekiq', require: false ##-- background job processing --## -gem 'sidekiq', '~> 6.4.2' +gem 'sidekiq' # We want cron jobs -gem 'sidekiq-cron', '~> 1.6', '>= 1.6.0' +gem 'sidekiq-cron' ##-- Push notification service --## gem 'fcm' @@ -129,7 +133,10 @@ gem 'procore-sift' # parse email gem 'email_reply_trimmer' -gem 'html2text' + +# TODO: we might have to fork this gem since 0.3.1 has hard depency on nokogir 1.10. +# and this gem hasn't been updated for a while. +gem 'html2text', git: 'https://github.com/chatwoot/html2text_ruby', branch: 'chatwoot' # to calculate working hours gem 'working_hours' @@ -144,18 +151,13 @@ gem 'stripe' ## to populate db with sample data gem 'faker' -# Can remove this in rails 7 -gem 'net-imap', require: false -gem 'net-pop', require: false -gem 'net-smtp', require: false - # Include logrange conditionally in intializer using env variable gem 'lograge', '~> 0.12.0', require: false # worked with microsoft refresh token gem 'omniauth-oauth2' -gem 'audited', '~> 5.2' +gem 'audited', '~> 5.3' # need for google auth gem 'omniauth' @@ -174,6 +176,7 @@ group :development do gem 'annotate' gem 'bullet' gem 'letter_opener' + gem 'scss_lint', require: false gem 'web-console' # used in swagger build @@ -189,7 +192,7 @@ end group :test do # Cypress in rails. - gem 'cypress-on-rails', '~> 1.13', '>= 1.13.1' + gem 'cypress-on-rails' # fast cleaning of database gem 'database_cleaner' # mock http calls @@ -211,7 +214,7 @@ group :development, :test do gem 'mock_redis' gem 'pry-rails' gem 'rspec_junit_formatter' - gem 'rspec-rails', '~> 5.0.3' + gem 'rspec-rails' gem 'rubocop', require: false gem 'rubocop-performance', require: false gem 'rubocop-rails', require: false diff --git a/Gemfile.lock b/Gemfile.lock index 3fa0dddca..3723a738c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,132 +1,153 @@ +GIT + remote: https://github.com/chatwoot/azure-storage-ruby + revision: 9957cf899d33a285b5dfe15bdb875292398e392b + branch: chatwoot + specs: + azure-storage-blob (2.0.3) + azure-storage-common (~> 2.0) + nokogiri (~> 1, >= 1.10.8) + azure-storage-common (2.0.4) + faraday (~> 2.0) + faraday-follow_redirects (~> 0.3.0) + faraday-net_http_persistent (~> 2.0) + net-http-persistent (~> 4.0) + nokogiri (~> 1, >= 1.10.8) + GIT remote: https://github.com/chatwoot/devise-secure_password - revision: d777b04f12652d576b1272b8f39857e3e0b3fc26 + revision: adcc85fe1babfe40feae73dbcae64d14fff86e69 + branch: chatwoot specs: devise-secure_password (2.0.1) devise (>= 4.0.0, < 5.0.0) - railties (>= 5.0.0, < 7.0.0) + railties (>= 5.0.0, < 8.0.0) + +GIT + remote: https://github.com/chatwoot/html2text_ruby + revision: cdbdbbbf898d846d0136d69d688a003c6b26074b + branch: chatwoot + specs: + html2text (0.3.1) + nokogiri (>= 1.13.6) GEM remote: https://rubygems.org/ specs: - actioncable (6.1.7.3) - actionpack (= 6.1.7.3) - activesupport (= 6.1.7.3) + actioncable (7.0.4.3) + actionpack (= 7.0.4.3) + activesupport (= 7.0.4.3) nio4r (~> 2.0) websocket-driver (>= 0.6.1) - actionmailbox (6.1.7.3) - actionpack (= 6.1.7.3) - activejob (= 6.1.7.3) - activerecord (= 6.1.7.3) - activestorage (= 6.1.7.3) - activesupport (= 6.1.7.3) + actionmailbox (7.0.4.3) + actionpack (= 7.0.4.3) + activejob (= 7.0.4.3) + activerecord (= 7.0.4.3) + activestorage (= 7.0.4.3) + activesupport (= 7.0.4.3) mail (>= 2.7.1) - actionmailer (6.1.7.3) - actionpack (= 6.1.7.3) - actionview (= 6.1.7.3) - activejob (= 6.1.7.3) - activesupport (= 6.1.7.3) + net-imap + net-pop + net-smtp + actionmailer (7.0.4.3) + actionpack (= 7.0.4.3) + actionview (= 7.0.4.3) + activejob (= 7.0.4.3) + activesupport (= 7.0.4.3) mail (~> 2.5, >= 2.5.4) + net-imap + net-pop + net-smtp rails-dom-testing (~> 2.0) - actionpack (6.1.7.3) - actionview (= 6.1.7.3) - activesupport (= 6.1.7.3) - rack (~> 2.0, >= 2.0.9) + actionpack (7.0.4.3) + actionview (= 7.0.4.3) + activesupport (= 7.0.4.3) + rack (~> 2.0, >= 2.2.0) rack-test (>= 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.2.0) - actiontext (6.1.7.3) - actionpack (= 6.1.7.3) - activerecord (= 6.1.7.3) - activestorage (= 6.1.7.3) - activesupport (= 6.1.7.3) + actiontext (7.0.4.3) + actionpack (= 7.0.4.3) + activerecord (= 7.0.4.3) + activestorage (= 7.0.4.3) + activesupport (= 7.0.4.3) + globalid (>= 0.6.0) nokogiri (>= 1.8.5) - actionview (6.1.7.3) - activesupport (= 6.1.7.3) + actionview (7.0.4.3) + activesupport (= 7.0.4.3) builder (~> 3.1) erubi (~> 1.4) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.1, >= 1.2.0) active_record_query_trace (1.8) - activejob (6.1.7.3) - activesupport (= 6.1.7.3) + activejob (7.0.4.3) + activesupport (= 7.0.4.3) globalid (>= 0.3.6) - activemodel (6.1.7.3) - activesupport (= 6.1.7.3) - activerecord (6.1.7.3) - activemodel (= 6.1.7.3) - activesupport (= 6.1.7.3) - activerecord-import (1.4.0) + activemodel (7.0.4.3) + activesupport (= 7.0.4.3) + activerecord (7.0.4.3) + activemodel (= 7.0.4.3) + activesupport (= 7.0.4.3) + activerecord-import (1.4.1) activerecord (>= 4.2) - activestorage (6.1.7.3) - actionpack (= 6.1.7.3) - activejob (= 6.1.7.3) - activerecord (= 6.1.7.3) - activesupport (= 6.1.7.3) + activestorage (7.0.4.3) + actionpack (= 7.0.4.3) + activejob (= 7.0.4.3) + activerecord (= 7.0.4.3) + activesupport (= 7.0.4.3) marcel (~> 1.0) mini_mime (>= 1.1.0) - activesupport (6.1.7.3) + activesupport (7.0.4.3) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (>= 1.6, < 2) minitest (>= 5.1) tzinfo (~> 2.0) - zeitwerk (~> 2.3) acts-as-taggable-on (9.0.1) activerecord (>= 6.0, < 7.1) - addressable (2.8.1) + addressable (2.8.4) public_suffix (>= 2.0.2, < 6.0) - administrate (0.17.0) + administrate (0.18.0) actionpack (>= 5.0) actionview (>= 5.0) activerecord (>= 5.0) - datetime_picker_rails (~> 0.0.7) jquery-rails (>= 4.0) kaminari (>= 1.0) - momentjs-rails (~> 2.8) sassc-rails (~> 2.1) selectize-rails (~> 0.6) annotate (3.2.0) activerecord (>= 3.2, < 8.0) rake (>= 10.4, < 14.0) ast (2.4.2) - attr_extras (6.2.5) - audited (5.2.0) + attr_extras (7.1.0) + audited (5.3.3) activerecord (>= 5.0, < 7.1) + request_store (~> 1.2) aws-eventstream (1.2.0) - aws-partitions (1.605.0) - aws-sdk-core (3.131.2) + aws-partitions (1.760.0) + aws-sdk-core (3.171.1) aws-eventstream (~> 1, >= 1.0.2) - aws-partitions (~> 1, >= 1.525.0) - aws-sigv4 (~> 1.1) + aws-partitions (~> 1, >= 1.651.0) + aws-sigv4 (~> 1.5) jmespath (~> 1, >= 1.6.1) - aws-sdk-kms (1.57.0) - aws-sdk-core (~> 3, >= 3.127.0) + aws-sdk-kms (1.64.0) + aws-sdk-core (~> 3, >= 3.165.0) aws-sigv4 (~> 1.1) - aws-sdk-s3 (1.114.0) - aws-sdk-core (~> 3, >= 3.127.0) + aws-sdk-s3 (1.122.0) + aws-sdk-core (~> 3, >= 3.165.0) aws-sdk-kms (~> 1) aws-sigv4 (~> 1.4) - aws-sigv4 (1.5.0) + aws-sigv4 (1.5.2) aws-eventstream (~> 1, >= 1.0.2) - azure-storage-blob (2.0.3) - azure-storage-common (~> 2.0) - nokogiri (~> 1, >= 1.10.8) - azure-storage-common (2.0.4) - faraday (~> 1.0) - faraday_middleware (~> 1.0, >= 1.0.0.rc1) - net-http-persistent (~> 4.0) - nokogiri (~> 1, >= 1.10.8) barnes (0.0.9) multi_json (~> 1) statsd-ruby (~> 1.1) bcrypt (3.1.18) bindex (0.8.1) - bootsnap (1.12.0) + bootsnap (1.16.0) msgpack (~> 1.2) - brakeman (5.2.3) + brakeman (5.4.1) browser (5.3.1) builder (3.2.4) - bullet (7.0.2) + bullet (7.0.7) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) bundle-audit (0.1.0) @@ -135,59 +156,59 @@ GEM bundler (>= 1.2.0, < 3) thor (~> 1.0) byebug (11.1.3) - climate_control (1.1.1) + climate_control (1.2.0) coderay (1.1.3) commonmarker (0.23.9) concurrent-ruby (1.2.2) - connection_pool (2.2.5) + connection_pool (2.4.0) crack (0.4.5) rexml crass (1.0.6) - csv-safe (3.1.1) + csv-safe (3.2.1) cypress-on-rails (1.13.1) rack - database_cleaner (2.0.1) - database_cleaner-active_record (~> 2.0.0) - database_cleaner-active_record (2.0.1) + database_cleaner (2.0.2) + database_cleaner-active_record (>= 2, < 3) + database_cleaner-active_record (2.1.0) activerecord (>= 5.a) database_cleaner-core (~> 2.0.0) database_cleaner-core (2.0.1) - datetime_picker_rails (0.0.7) - momentjs-rails (>= 2.8.1) - ddtrace (1.2.0) - debase-ruby_core_source (= 0.10.16) - libddprof (~> 0.6.0.1.0) - libddwaf (~> 1.3.0.2.0) + date (3.3.3) + ddtrace (1.11.1) + debase-ruby_core_source (>= 0.10.16, <= 3.2.0) + libdatadog (~> 2.0.0.1.0) + libddwaf (~> 1.8.2.0.0) msgpack - debase-ruby_core_source (0.10.16) + debase-ruby_core_source (3.2.0) declarative (0.0.20) - devise (4.8.1) + devise (4.9.2) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0) responders warden (~> 1.2.3) - devise_token_auth (1.2.0) + devise_token_auth (1.2.1) bcrypt (~> 3.0) devise (> 3.5.2, < 5) - rails (>= 4.2.0, < 6.2) + rails (>= 4.2.0, < 7.1) diff-lcs (1.5.0) digest-crc (0.6.4) rake (>= 12.0.0, < 14.0.0) docile (1.4.0) domain_name (0.5.20190701) unf (>= 0.0.5, < 1.0.0) - dotenv (2.7.6) - dotenv-rails (2.7.6) - dotenv (= 2.7.6) + dotenv (2.8.1) + dotenv-rails (2.8.1) + dotenv (= 2.8.1) railties (>= 3.2) - down (5.3.1) + down (5.4.0) addressable (~> 2.8) ecma-re-validator (0.4.0) regexp_parser (~> 2.2) - elastic-apm (4.5.1) + elastic-apm (4.6.2) concurrent-ruby (~> 1.0) http (>= 3.0) + ruby2_keywords email_reply_trimmer (0.1.13) erubi (1.12.0) et-orbi (1.2.7) @@ -201,33 +222,24 @@ GEM factory_bot_rails (6.2.0) factory_bot (~> 6.2.0) railties (>= 5.0.0) - faker (2.21.0) + faker (3.2.0) i18n (>= 1.8.11, < 2) - faraday (1.10.0) - faraday-em_http (~> 1.0) - faraday-em_synchrony (~> 1.0) - faraday-excon (~> 1.1) - faraday-httpclient (~> 1.0) - faraday-multipart (~> 1.0) - faraday-net_http (~> 1.0) - faraday-net_http_persistent (~> 1.0) - faraday-patron (~> 1.0) - faraday-rack (~> 1.0) - faraday-retry (~> 1.0) + faraday (2.7.4) + faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) - faraday-em_http (1.0.0) - faraday-em_synchrony (1.0.0) - faraday-excon (1.1.0) - faraday-httpclient (1.0.1) + faraday-follow_redirects (0.3.0) + faraday (>= 1, < 3) + faraday-mashify (0.1.1) + faraday (~> 2.0) + hashie faraday-multipart (1.0.4) multipart-post (~> 2) - faraday-net_http (1.0.1) - faraday-net_http_persistent (1.2.0) - faraday-patron (1.0.0) - faraday-rack (1.0.0) - faraday-retry (1.0.3) - faraday_middleware (1.2.0) - faraday (~> 1.0) + faraday-net_http (3.0.2) + faraday-net_http_persistent (2.1.0) + faraday (~> 2.5) + net-http-persistent (~> 4.0) + faraday-retry (2.1.0) + faraday (~> 2.0) fcm (1.0.8) faraday (>= 1.0.0, < 3.0) googleauth (~> 1) @@ -237,10 +249,10 @@ GEM rake flag_shih_tzu (0.3.23) foreman (0.87.2) - fugit (1.5.3) + fugit (1.8.1) et-orbi (~> 1, >= 1.2.7) raabro (~> 1.4) - gapic-common (0.10.0) + gapic-common (0.18.0) faraday (>= 1.9, < 3.a) faraday-retry (>= 1.0, < 3.a) google-protobuf (~> 3.14) @@ -248,13 +260,13 @@ GEM googleapis-common-protos-types (>= 1.3.1, < 2.a) googleauth (~> 1.0) grpc (~> 1.36) - geocoder (1.8.0) + geocoder (1.8.1) gli (2.21.0) globalid (1.1.0) activesupport (>= 5.0) gmail_xoauth (0.4.2) oauth (>= 0.3.6) - google-apis-core (0.7.0) + google-apis-core (0.11.0) addressable (~> 2.5, >= 2.5.1) googleauth (>= 0.16.2, < 2.a) httpclient (>= 2.8.1, < 3.a) @@ -263,86 +275,72 @@ GEM retriable (>= 2.0, < 4.a) rexml webrick - google-apis-iamcredentials_v1 (0.13.0) - google-apis-core (>= 0.7, < 2.a) - google-apis-storage_v1 (0.18.0) - google-apis-core (>= 0.7, < 2.a) + google-apis-iamcredentials_v1 (0.17.0) + google-apis-core (>= 0.11.0, < 2.a) + google-apis-storage_v1 (0.19.0) + google-apis-core (>= 0.9.0, < 2.a) google-cloud-core (1.6.0) google-cloud-env (~> 1.0) google-cloud-errors (~> 1.0) - google-cloud-dialogflow (1.5.0) - google-cloud-core (~> 1.6) - google-cloud-dialogflow-v2 (>= 0.15, < 2.a) - google-cloud-dialogflow-v2 (0.17.0) - gapic-common (>= 0.10, < 2.a) + google-cloud-dialogflow-v2 (0.23.0) + gapic-common (>= 0.18.0, < 2.a) google-cloud-errors (~> 1.0) - google-cloud-location (>= 0.0, < 2.a) + google-cloud-location (>= 0.4, < 2.a) google-cloud-env (1.6.0) faraday (>= 0.17.3, < 3.0) - google-cloud-errors (1.2.0) - google-cloud-location (0.2.0) - gapic-common (>= 0.10, < 2.a) + google-cloud-errors (1.3.1) + google-cloud-location (0.4.0) + gapic-common (>= 0.17.1, < 2.a) google-cloud-errors (~> 1.0) - google-cloud-storage (1.37.0) + google-cloud-storage (1.44.0) addressable (~> 2.8) digest-crc (~> 0.4) google-apis-iamcredentials_v1 (~> 0.1) - google-apis-storage_v1 (~> 0.1) + google-apis-storage_v1 (~> 0.19.0) google-cloud-core (~> 1.6) googleauth (>= 0.16.2, < 2.a) mini_mime (~> 1.0) - google-cloud-translate (3.3.0) - google-cloud-core (~> 1.6) - google-cloud-translate-v2 (>= 0.0, < 2.a) - google-cloud-translate-v3 (>= 0.0, < 2.a) - google-cloud-translate-v2 (0.4.0) - faraday (>= 0.17.3, < 2.a) - google-cloud-core (~> 1.6) - googleapis-common-protos (>= 1.3.10, < 2.a) - googleapis-common-protos-types (>= 1.0.5, < 2.a) - googleauth (>= 0.16.2, < 2.a) - google-cloud-translate-v3 (0.5.0) - gapic-common (>= 0.10, < 2.a) + google-cloud-translate-v3 (0.6.0) + gapic-common (>= 0.17.1, < 2.a) google-cloud-errors (~> 1.0) - google-protobuf (3.21.7) - google-protobuf (3.21.7-x86_64-darwin) - google-protobuf (3.21.7-x86_64-linux) - googleapis-common-protos (1.3.12) + google-protobuf (3.22.3) + google-protobuf (3.22.3-arm64-darwin) + google-protobuf (3.22.3-x86_64-darwin) + google-protobuf (3.22.3-x86_64-linux) + googleapis-common-protos (1.4.0) google-protobuf (~> 3.14) googleapis-common-protos-types (~> 1.2) grpc (~> 1.27) - googleapis-common-protos-types (1.3.2) + googleapis-common-protos-types (1.6.0) google-protobuf (~> 3.14) - googleauth (1.2.0) + googleauth (1.5.2) faraday (>= 0.17.3, < 3.a) jwt (>= 1.4, < 3.0) memoist (~> 0.16) multi_json (~> 1.11) os (>= 0.9, < 2.0) signet (>= 0.16, < 2.a) - groupdate (6.1.0) + groupdate (6.2.1) activesupport (>= 5.2) - grpc (1.47.0) - google-protobuf (~> 3.19) + grpc (1.54.0) + google-protobuf (~> 3.21) googleapis-common-protos-types (~> 1.0) - grpc (1.47.0-x86_64-darwin) - google-protobuf (~> 3.19) + grpc (1.54.0-x86_64-darwin) + google-protobuf (~> 3.21) googleapis-common-protos-types (~> 1.0) - grpc (1.47.0-x86_64-linux) - google-protobuf (~> 3.19) + grpc (1.54.0-x86_64-linux) + google-protobuf (~> 3.21) googleapis-common-protos-types (~> 1.0) haikunator (1.1.1) - hairtrigger (0.2.25) - activerecord (>= 5.0, < 8) + hairtrigger (1.0.0) + activerecord (>= 6.0, < 8) ruby2ruby (~> 2.4) ruby_parser (~> 3.10) hana (1.3.7) hashdiff (1.0.1) hashie (5.0.0) hkdf (1.0.0) - html2text (0.2.1) - nokogiri (~> 1.6) - http (5.1.0) + http (5.1.1) addressable (~> 2.8) http-cookie (~> 1.0) http-form_data (~> 2.2) @@ -355,7 +353,7 @@ GEM mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) httpclient (2.8.3) - i18n (1.12.0) + i18n (1.13.0) concurrent-ruby (~> 1.0) image_processing (1.12.2) mini_magick (>= 4.9.5, < 5) @@ -363,20 +361,20 @@ GEM jbuilder (2.11.5) actionview (>= 5.0.0) activesupport (>= 5.0.0) - jmespath (1.6.1) - jquery-rails (4.5.0) + jmespath (1.6.2) + jquery-rails (4.5.1) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) - json (2.6.2) - json_refs (0.1.7) + json (2.6.3) + json_refs (0.1.8) hana - json_schemer (0.2.21) + json_schemer (0.2.24) ecma-re-validator (~> 0.3) hana (~> 1.3) regexp_parser (~> 2.0) uri_template (~> 0.7) - jwt (2.5.0) + jwt (2.7.0) kaminari (1.2.2) activesupport (>= 4.1.0) kaminari-actionview (= 1.2.2) @@ -389,28 +387,29 @@ GEM activerecord kaminari-core (= 1.2.2) kaminari-core (1.2.2) - koala (3.2.0) + koala (3.4.0) addressable - faraday (< 2) + faraday + faraday-multipart json (>= 1.8) rexml - launchy (2.5.0) - addressable (~> 2.7) + launchy (2.5.2) + addressable (~> 2.8) letter_opener (1.8.1) launchy (>= 2.2, < 3) - libddprof (0.6.0.1.0) - libddprof (0.6.0.1.0-x86_64-linux) - libddwaf (1.3.0.2.0) + libdatadog (2.0.0.1.0) + libdatadog (2.0.0.1.0-x86_64-linux) + libddwaf (1.8.2.0.0) ffi (~> 1.0) - libddwaf (1.3.0.2.0-arm64-darwin) + libddwaf (1.8.2.0.0-arm64-darwin) ffi (~> 1.0) - libddwaf (1.3.0.2.0-x86_64-darwin) + libddwaf (1.8.2.0.0-x86_64-darwin) ffi (~> 1.0) - libddwaf (1.3.0.2.0-x86_64-linux) + libddwaf (1.8.2.0.0-x86_64-linux) ffi (~> 1.0) - line-bot-api (1.25.0) - liquid (5.3.0) - listen (3.7.1) + line-bot-api (1.28.0) + liquid (5.4.0) + listen (3.8.0) rb-fsevent (~> 0.10, >= 0.10.3) rb-inotify (~> 0.9, >= 0.9.10) llhttp-ffi (0.4.0) @@ -421,7 +420,7 @@ GEM activesupport (>= 4) railties (>= 4) request_store (~> 1.0) - loofah (2.19.1) + loofah (2.20.0) crass (~> 1.0.2) nokogiri (>= 1.5.9) mail (2.8.1) @@ -435,22 +434,21 @@ GEM method_source (1.0.0) mime-types (3.4.1) mime-types-data (~> 3.2015) - mime-types-data (3.2022.0105) - mini_magick (4.11.0) + mime-types-data (3.2023.0218.1) + mini_magick (4.12.0) mini_mime (1.1.2) - mini_portile2 (2.8.1) + mini_portile2 (2.8.2) minitest (5.18.0) - mock_redis (0.32.0) + mock_redis (0.36.0) ruby2_keywords - momentjs-rails (2.29.1.1) - railties (>= 3.1) - msgpack (1.5.3) + msgpack (1.7.0) multi_json (1.15.0) multi_xml (0.6.0) - multipart-post (2.2.3) - net-http-persistent (4.0.1) + multipart-post (2.3.0) + net-http-persistent (4.0.2) connection_pool (~> 2.2) - net-imap (0.3.1) + net-imap (0.3.4) + date net-protocol net-pop (0.1.2) net-protocol @@ -462,8 +460,8 @@ GEM newrelic-sidekiq-metrics (1.6.1) newrelic_rpm (~> 8) sidekiq - newrelic_rpm (8.15.0) - nio4r (2.5.8) + newrelic_rpm (8.16.0) + nio4r (2.5.9) nokogiri (1.14.3) mini_portile2 (~> 2.8.0) racc (~> 1.4) @@ -473,7 +471,12 @@ GEM racc (~> 1.4) nokogiri (1.14.3-x86_64-linux) racc (~> 1.4) - oauth (0.5.10) + oauth (1.1.0) + oauth-tty (~> 1.0, >= 1.0.1) + snaky_hash (~> 2.0) + version_gem (~> 1.1) + oauth-tty (1.0.5) + version_gem (~> 1.1, >= 1.1.1) oauth2 (2.0.9) faraday (>= 0.17.3, < 3.0) jwt (>= 1.0, < 3.0) @@ -481,7 +484,7 @@ GEM rack (>= 1.2, < 4) snaky_hash (~> 2.0) version_gem (~> 1.1) - omniauth (2.1.0) + omniauth (2.1.1) hashie (>= 3.4.6) rack (>= 2.2.3) rack-protection @@ -499,85 +502,88 @@ GEM openssl (3.1.0) orm_adapter (0.5.0) os (1.1.4) - parallel (1.22.1) - parser (3.1.2.0) + parallel (1.23.0) + parser (3.2.2.1) ast (~> 2.4.1) - pg (1.4.1) + pg (1.5.3) pg_search (2.3.6) activerecord (>= 5.2) activesupport (>= 5.2) - procore-sift (0.16.0) - rails (> 4.2.0) - pry (0.14.1) + procore-sift (1.0.0) + activerecord (>= 6.1) + pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) pry-rails (0.3.9) pry (>= 0.10.4) public_suffix (5.0.1) - puma (5.6.4) + puma (6.2.2) nio4r (~> 2.0) - pundit (2.2.0) + pundit (2.3.0) activesupport (>= 3.0.0) raabro (1.4.0) racc (1.6.2) - rack (2.2.6.4) + rack (2.2.7) rack-attack (6.6.1) rack (>= 1.0, < 3) - rack-cors (1.1.1) + rack-cors (2.0.1) rack (>= 2.0.0) - rack-mini-profiler (3.0.0) + rack-mini-profiler (3.1.0) rack (>= 1.2.0) - rack-protection (3.0.5) + rack-protection (3.0.6) rack - rack-proxy (0.7.2) + rack-proxy (0.7.6) rack rack-test (2.1.0) rack (>= 1.3) rack-timeout (0.6.3) - rails (6.1.7.3) - actioncable (= 6.1.7.3) - actionmailbox (= 6.1.7.3) - actionmailer (= 6.1.7.3) - actionpack (= 6.1.7.3) - actiontext (= 6.1.7.3) - actionview (= 6.1.7.3) - activejob (= 6.1.7.3) - activemodel (= 6.1.7.3) - activerecord (= 6.1.7.3) - activestorage (= 6.1.7.3) - activesupport (= 6.1.7.3) + rails (7.0.4.3) + actioncable (= 7.0.4.3) + actionmailbox (= 7.0.4.3) + actionmailer (= 7.0.4.3) + actionpack (= 7.0.4.3) + actiontext (= 7.0.4.3) + actionview (= 7.0.4.3) + activejob (= 7.0.4.3) + activemodel (= 7.0.4.3) + activerecord (= 7.0.4.3) + activestorage (= 7.0.4.3) + activesupport (= 7.0.4.3) bundler (>= 1.15.0) - railties (= 6.1.7.3) - sprockets-rails (>= 2.0.0) + railties (= 7.0.4.3) rails-dom-testing (2.0.3) activesupport (>= 4.2.0) nokogiri (>= 1.6) rails-html-sanitizer (1.5.0) loofah (~> 2.19, >= 2.19.1) - railties (6.1.7.3) - actionpack (= 6.1.7.3) - activesupport (= 6.1.7.3) + railties (7.0.4.3) + actionpack (= 7.0.4.3) + activesupport (= 7.0.4.3) method_source rake (>= 12.2) thor (~> 1.0) + zeitwerk (~> 2.5) rainbow (3.1.1) rake (13.0.6) - rb-fsevent (0.11.1) + rb-fsevent (0.11.2) rb-inotify (0.10.1) ffi (~> 1.0) - redis (4.7.1) - redis-namespace (1.8.2) - redis (>= 3.0.4) - regexp_parser (2.5.0) + redis (5.0.6) + redis-client (>= 0.9.0) + redis-client (0.14.1) + connection_pool + redis-namespace (1.10.0) + redis (>= 4) + regexp_parser (2.8.0) representable (3.2.0) declarative (< 0.1.0) trailblazer-option (>= 0.1.1, < 0.2.0) uber (< 0.2.0) request_store (1.5.1) rack (>= 1.4) - responders (3.0.1) - actionpack (>= 5.0) - railties (>= 5.0) + responders (3.1.0) + actionpack (>= 5.2) + railties (>= 5.2) rest-client (2.1.0) http-accept (>= 1.7.0, < 2.0) http-cookie (>= 1.0.2, < 2.0) @@ -585,55 +591,63 @@ GEM netrc (~> 0.8) retriable (3.1.2) rexml (3.2.5) - rspec-core (3.11.0) - rspec-support (~> 3.11.0) - rspec-expectations (3.11.0) + rspec-core (3.12.2) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.3) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.11.0) - rspec-mocks (3.11.1) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.5) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.11.0) - rspec-rails (5.0.3) - actionpack (>= 5.2) - activesupport (>= 5.2) - railties (>= 5.2) - rspec-core (~> 3.10) - rspec-expectations (~> 3.10) - rspec-mocks (~> 3.10) - rspec-support (~> 3.10) - rspec-support (3.11.0) + rspec-support (~> 3.12.0) + rspec-rails (6.0.2) + actionpack (>= 6.1) + activesupport (>= 6.1) + railties (>= 6.1) + rspec-core (~> 3.12) + rspec-expectations (~> 3.12) + rspec-mocks (~> 3.12) + rspec-support (~> 3.12) + rspec-support (3.12.0) rspec_junit_formatter (0.6.0) rspec-core (>= 2, < 4, != 2.12.0) - rubocop (1.31.2) + rubocop (1.50.2) json (~> 2.3) parallel (~> 1.10) - parser (>= 3.1.0.0) + parser (>= 3.2.0.0) rainbow (>= 2.2.2, < 4.0) regexp_parser (>= 1.8, < 3.0) rexml (>= 3.2.5, < 4.0) - rubocop-ast (>= 1.18.0, < 2.0) + rubocop-ast (>= 1.28.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 3.0) - rubocop-ast (1.19.1) - parser (>= 3.1.1.0) - rubocop-performance (1.14.2) + unicode-display_width (>= 2.4.0, < 3.0) + rubocop-ast (1.28.1) + parser (>= 3.2.1.0) + rubocop-capybara (2.18.0) + rubocop (~> 1.41) + rubocop-performance (1.17.1) rubocop (>= 1.7.0, < 2.0) rubocop-ast (>= 0.4.0) - rubocop-rails (2.15.2) + rubocop-rails (2.19.1) activesupport (>= 4.2.0) rack (>= 1.1) - rubocop (>= 1.7.0, < 2.0) - rubocop-rspec (2.12.1) - rubocop (~> 1.31) - ruby-progressbar (1.11.0) + rubocop (>= 1.33.0, < 2.0) + rubocop-rspec (2.21.0) + rubocop (~> 1.33) + rubocop-capybara (~> 2.17) + ruby-progressbar (1.13.0) ruby-vips (2.1.4) ffi (~> 1.12) ruby2_keywords (0.0.5) - ruby2ruby (2.4.4) + ruby2ruby (2.5.0) ruby_parser (~> 3.1) sexp_processor (~> 4.6) - ruby_parser (3.19.1) + ruby_parser (3.20.0) sexp_processor (~> 4.16) + sass (3.7.4) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) sassc (2.4.0) ffi (~> 1.9) sassc-rails (2.1.2) @@ -642,34 +656,35 @@ GEM sprockets (> 3.0) sprockets-rails tilt - scout_apm (5.2.0) + scout_apm (5.3.3) parser + scss_lint (0.60.0) + sass (~> 3.5, >= 3.5.5) seed_dump (3.3.1) activerecord (>= 4) activesupport (>= 4) selectize-rails (0.12.6) semantic_range (3.0.0) - sentry-rails (5.3.1) + sentry-rails (5.9.0) railties (>= 5.0) - sentry-ruby-core (~> 5.3.1) - sentry-ruby (5.3.1) + sentry-ruby (~> 5.9.0) + sentry-ruby (5.9.0) concurrent-ruby (~> 1.0, >= 1.0.2) - sentry-ruby-core (= 5.3.1) - sentry-ruby-core (5.3.1) - concurrent-ruby - sentry-sidekiq (5.3.1) - sentry-ruby-core (~> 5.3.1) + sentry-sidekiq (5.9.0) + sentry-ruby (~> 5.9.0) sidekiq (>= 3.0) - sexp_processor (4.16.1) - shoulda-matchers (5.1.0) + sexp_processor (4.17.0) + shoulda-matchers (5.3.0) activesupport (>= 5.2.0) - sidekiq (6.4.2) - connection_pool (>= 2.2.2) - rack (~> 2.0) - redis (>= 4.2.0) - sidekiq-cron (1.6.0) - fugit (~> 1) - sidekiq (>= 4.2.1) + sidekiq (7.1.0) + concurrent-ruby (< 2) + connection_pool (>= 2.3.0) + rack (>= 2.2.4) + redis-client (>= 0.14.0) + sidekiq-cron (1.10.0) + fugit (~> 1.8) + globalid (>= 1.0.1) + sidekiq (>= 6) signet (0.17.0) addressable (~> 2.8) faraday (>= 0.17.5, < 3.a) @@ -680,19 +695,20 @@ GEM json (>= 1.8, < 3) simplecov-html (~> 0.10.0) simplecov-html (0.10.2) - slack-ruby-client (1.0.0) - faraday (>= 1.0) - faraday_middleware + slack-ruby-client (2.0.0) + faraday (>= 2.0) + faraday-mashify + faraday-multipart gli hashie websocket-driver snaky_hash (2.0.1) hashie version_gem (~> 1.1, >= 1.1.1) - spring (2.1.1) - spring-watcher-listen (2.0.1) + spring (4.1.1) + spring-watcher-listen (2.1.0) listen (>= 2.7, < 4.0) - spring (>= 1.2, < 3.0) + spring (>= 4) sprockets (4.2.0) concurrent-ruby (~> 1.0) rack (>= 2.2.4, < 4) @@ -700,28 +716,28 @@ GEM actionpack (>= 5.2) activesupport (>= 5.2) sprockets (>= 3.0.0) - squasher (0.6.2) - stackprof (0.2.24) + squasher (0.7.2) + stackprof (0.2.25) statsd-ruby (1.5.0) - stripe (6.5.0) - telephone_number (1.4.16) - test-prof (1.0.11) + stripe (8.5.0) + telephone_number (1.4.20) + test-prof (1.2.1) thor (1.2.1) - tilt (2.0.10) + tilt (2.1.0) time_diff (0.3.0) activesupport i18n - timeout (0.3.1) + timeout (0.3.2) trailblazer-option (0.1.2) - twilio-ruby (5.68.0) + twilio-ruby (5.77.0) faraday (>= 0.9, < 3.0) - jwt (>= 1.5, <= 2.5) + jwt (>= 1.5, < 3.0) nokogiri (>= 1.6, < 2.0) twitty (0.1.5) oauth tzinfo (2.0.6) concurrent-ruby (~> 1.0) - tzinfo-data (1.2022.1) + tzinfo-data (1.2023.3) tzinfo (>= 1.0.0) uber (0.1.0) uglifier (4.2.0) @@ -729,13 +745,13 @@ GEM unf (0.1.4) unf_ext unf_ext (0.0.8.2) - unicode-display_width (2.2.0) + unicode-display_width (2.4.2) uniform_notifier (1.16.0) uri_template (0.7.0) - valid_email2 (4.0.3) + valid_email2 (4.0.6) activemodel (>= 3.2) mail (~> 2.5) - version_gem (1.1.1) + version_gem (1.1.2) warden (1.2.9) rack (>= 2.0.9) web-console (4.2.0) @@ -751,12 +767,12 @@ GEM addressable (>= 2.8.0) crack (>= 0.3.2) hashdiff (>= 0.4.0, < 2.0.0) - webpacker (5.4.3) + webpacker (5.4.4) activesupport (>= 5.2) rack-proxy (>= 0.6.1) railties (>= 5.2) semantic_range (>= 2.3.0) - webrick (1.7.0) + webrick (1.8.1) websocket-driver (0.7.5) websocket-extensions (>= 0.1.0) websocket-extensions (0.1.5) @@ -764,14 +780,16 @@ GEM working_hours (1.4.1) activesupport (>= 3.2) tzinfo - zeitwerk (2.6.7) + zeitwerk (2.6.8) PLATFORMS arm64-darwin-20 + arm64-darwin-21 ruby x86_64-darwin-18 x86_64-darwin-20 x86_64-darwin-21 + x86_64-darwin-22 x86_64-linux DEPENDENCIES @@ -781,9 +799,9 @@ DEPENDENCIES administrate annotate attr_extras - audited (~> 5.2) + audited (~> 5.3) aws-sdk-s3 - azure-storage-blob + azure-storage-blob! barnes bootsnap brakeman @@ -794,14 +812,14 @@ DEPENDENCIES climate_control commonmarker csv-safe - cypress-on-rails (~> 1.13, >= 1.13.1) + cypress-on-rails database_cleaner ddtrace devise - devise-secure_password (~> 2.0)! + devise-secure_password! devise_token_auth dotenv-rails - down (~> 5.0) + down elastic-apm email_reply_trimmer facebook-messenger @@ -812,15 +830,16 @@ DEPENDENCIES foreman geocoder gmail_xoauth - google-cloud-dialogflow + google-cloud-dialogflow-v2 google-cloud-storage - google-cloud-translate + google-cloud-translate-v3 groupdate + grpc haikunator hairtrigger hashie - html2text - image_processing (~> 1.12.2) + html2text! + image_processing jbuilder json_refs json_schemer @@ -834,9 +853,6 @@ DEPENDENCIES lograge (~> 0.12.0) maxminddb mock_redis - net-imap - net-pop - net-smtp newrelic-sidekiq-metrics newrelic_rpm omniauth @@ -853,27 +869,28 @@ DEPENDENCIES rack-cors rack-mini-profiler rack-timeout - rails (~> 6.1, >= 6.1.7.3) + rails (~> 7) redis redis-namespace responders rest-client - rspec-rails (~> 5.0.3) + rspec-rails rspec_junit_formatter rubocop rubocop-performance rubocop-rails rubocop-rspec scout_apm + scss_lint seed_dump sentry-rails sentry-ruby sentry-sidekiq shoulda-matchers - sidekiq (~> 6.4.2) - sidekiq-cron (~> 1.6, >= 1.6.0) + sidekiq + sidekiq-cron simplecov (= 0.17.1) - slack-ruby-client + slack-ruby-client (~> 2.0.0) spring spring-watcher-listen squasher @@ -890,12 +907,12 @@ DEPENDENCIES web-console web-push webmock - webpacker (~> 5.4, >= 5.4.3) + webpacker wisper (= 2.0.0) working_hours RUBY VERSION - ruby 3.1.3p185 + ruby 3.2.2p185 BUNDLED WITH - 2.3.26 + 2.4.10 diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..499d0ab6b --- /dev/null +++ b/Makefile @@ -0,0 +1,38 @@ +# Variables +APP_NAME := chatwoot +RAILS_ENV ?= development + +# Targets +setup: + gem install bundler + bundle install + yarn install + +db_create: + RAILS_ENV=$(RAILS_ENV) bundle exec rails db:create + +db_migrate: + RAILS_ENV=$(RAILS_ENV) bundle exec rails db:migrate + +db_seed: + RAILS_ENV=$(RAILS_ENV) bundle exec rails db:seed + +db: + RAILS_ENV=$(RAILS_ENV) bundle exec rails db:chatwoot_prepare + +console: + RAILS_ENV=$(RAILS_ENV) bundle exec rails console + +server: + RAILS_ENV=$(RAILS_ENV) bundle exec rails server -b 0.0.0.0 -p 3000 + +burn: + bundle && yarn + +run: + overmind start -f Procfile.dev + +docker: + docker build -t $(APP_NAME) -f ./docker/Dockerfile . + +.PHONY: setup db_create db_migrate db_seed db console server burn docker run diff --git a/app/builders/messages/instagram/message_builder.rb b/app/builders/messages/instagram/message_builder.rb index 1be960d21..eb34d4052 100644 --- a/app/builders/messages/instagram/message_builder.rb +++ b/app/builders/messages/instagram/message_builder.rb @@ -63,28 +63,42 @@ class Messages::Instagram::MessageBuilder < Messages::Messenger::MessageBuilder end def conversation - @conversation ||= Conversation.find_by(conversation_params) || build_conversation + @conversation ||= Conversation.where( + "additional_attributes ->> 'type' = 'instagram_direct_message'" + ).find_by(conversation_params) || build_conversation end def message_content @messaging[:message][:text] end + def story_reply_attributes + message[:reply_to][:story] if message[:reply_to].present? && message[:reply_to][:story].present? + end + def build_message return if @outgoing_echo && already_sent_from_chatwoot? return if message_content.blank? && all_unsupported_files? @message = conversation.messages.create!(message_params) + save_story_id attachments.each do |attachment| process_attachment(attachment) end end + def save_story_id + return if story_reply_attributes.blank? + + @message.save_story_info(story_reply_attributes) + end + def build_conversation @contact_inbox ||= contact.contact_inboxes.find_by!(source_id: message_source_id) Conversation.create!(conversation_params.merge( - contact_inbox_id: @contact_inbox.id + contact_inbox_id: @contact_inbox.id, + additional_attributes: { type: 'instagram_direct_message' } )) end @@ -92,10 +106,7 @@ class Messages::Instagram::MessageBuilder < Messages::Messenger::MessageBuilder { account_id: @inbox.account_id, inbox_id: @inbox.id, - contact_id: contact.id, - additional_attributes: { - type: 'instagram_direct_message' - } + contact_id: contact.id } end diff --git a/app/builders/messages/message_builder.rb b/app/builders/messages/message_builder.rb index ba5861859..aca06cd04 100644 --- a/app/builders/messages/message_builder.rb +++ b/app/builders/messages/message_builder.rb @@ -49,10 +49,10 @@ class Messages::MessageBuilder return unless @conversation.inbox&.inbox_type == 'Email' cc_emails = [] - cc_emails = @params[:cc_emails].split(',') if @params[:cc_emails].present? + cc_emails = @params[:cc_emails].gsub(/\s+/, '').split(',') if @params[:cc_emails].present? bcc_emails = [] - bcc_emails = @params[:bcc_emails].split(',') if @params[:bcc_emails].present? + bcc_emails = @params[:bcc_emails].gsub(/\s+/, '').split(',') if @params[:bcc_emails].present? all_email_addresses = cc_emails + bcc_emails validate_email_addresses(all_email_addresses) diff --git a/app/controllers/api/v1/accounts/conversations_controller.rb b/app/controllers/api/v1/accounts/conversations_controller.rb index 10a676738..ebd673d6f 100644 --- a/app/controllers/api/v1/accounts/conversations_controller.rb +++ b/app/controllers/api/v1/accounts/conversations_controller.rb @@ -22,6 +22,10 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro @conversations_count = result[:count] end + def attachments + @attachments = @conversation.attachments + end + def create ActiveRecord::Base.transaction do @conversation = ConversationBuilder.new(params: params, contact_inbox: @contact_inbox).perform @@ -64,13 +68,14 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro assign_conversation if @conversation.status == 'open' && Current.user.is_a?(User) && Current.user&.agent? end + def toggle_priority + @conversation.toggle_priority(params[:priority]) + head :ok + end + def toggle_typing_status - case params[:typing_status] - when 'on' - trigger_typing_event(CONVERSATION_TYPING_ON, params[:is_private]) - when 'off' - trigger_typing_event(CONVERSATION_TYPING_OFF, params[:is_private]) - end + typing_status_manager = ::Conversations::TypingStatusManager.new(@conversation, current_user, params) + typing_status_manager.toggle_typing_status head :ok end @@ -111,11 +116,6 @@ class Api::V1::Accounts::ConversationsController < Api::V1::Accounts::BaseContro @conversation.update_assignee(@agent) end - def trigger_typing_event(event, is_private) - user = current_user.presence || @resource - Rails.configuration.dispatcher.dispatch(event, Time.zone.now, conversation: @conversation, user: user, is_private: is_private) - end - def conversation @conversation ||= Current.account.conversations.find_by!(display_id: params[:id]) authorize @conversation.inbox, :show? diff --git a/app/controllers/api/v1/accounts/inboxes_controller.rb b/app/controllers/api/v1/accounts/inboxes_controller.rb index 20402b5d1..9b5cafc4c 100644 --- a/app/controllers/api/v1/accounts/inboxes_controller.rb +++ b/app/controllers/api/v1/accounts/inboxes_controller.rb @@ -114,10 +114,13 @@ class Api::V1::Accounts::InboxesController < Api::V1::Accounts::BaseController def inbox_attributes [:name, :avatar, :greeting_enabled, :greeting_message, :enable_email_collect, :csat_survey_enabled, :enable_auto_assignment, :working_hours_enabled, :out_of_office_message, :timezone, :allow_messages_after_resolved, - :lock_to_single_conversation] + :lock_to_single_conversation, :portal_id] end def permitted_params(channel_attributes = []) + # We will remove this line after fixing https://linear.app/chatwoot/issue/CW-1567/null-value-passed-as-null-string-to-backend + params.each { |k, v| params[k] = params[k] == 'null' ? nil : v } + params.permit( *inbox_attributes, channel: [:type, *channel_attributes] diff --git a/app/controllers/api/v1/accounts/integrations/hooks_controller.rb b/app/controllers/api/v1/accounts/integrations/hooks_controller.rb index dd2af4ef2..d09ea2f00 100644 --- a/app/controllers/api/v1/accounts/integrations/hooks_controller.rb +++ b/app/controllers/api/v1/accounts/integrations/hooks_controller.rb @@ -1,5 +1,5 @@ class Api::V1::Accounts::Integrations::HooksController < Api::V1::Accounts::BaseController - before_action :fetch_hook, only: [:update, :destroy] + before_action :fetch_hook, except: [:create] before_action :check_authorization def create @@ -10,6 +10,10 @@ class Api::V1::Accounts::Integrations::HooksController < Api::V1::Accounts::Base @hook.update!(permitted_params.slice(:status, :settings)) end + def process_event + render json: { message: @hook.process_event(params[:event]) } + end + def destroy @hook.destroy! head :ok diff --git a/app/controllers/api/v1/accounts/portals_controller.rb b/app/controllers/api/v1/accounts/portals_controller.rb index b1837acbd..fcc02c6ec 100644 --- a/app/controllers/api/v1/accounts/portals_controller.rb +++ b/app/controllers/api/v1/accounts/portals_controller.rb @@ -30,7 +30,7 @@ class Api::V1::Accounts::PortalsController < Api::V1::Accounts::BaseController ActiveRecord::Base.transaction do @portal.update!(portal_params) if params[:portal].present? # @portal.custom_domain = parsed_custom_domain - process_attached_logo + process_attached_logo if params[:blob_id].present? rescue StandardError => e Rails.logger.error e render json: { error: @portal.errors.messages }.to_json, status: :unprocessable_entity diff --git a/app/controllers/api/v1/widget/messages_controller.rb b/app/controllers/api/v1/widget/messages_controller.rb index 6287c94ee..76efb2c42 100644 --- a/app/controllers/api/v1/widget/messages_controller.rb +++ b/app/controllers/api/v1/widget/messages_controller.rb @@ -48,7 +48,8 @@ class Api::V1::Widget::MessagesController < Api::V1::Widget::BaseController def message_finder_params { filter_internal_messages: true, - before: permitted_params[:before] + before: permitted_params[:before], + after: permitted_params[:after] } end @@ -62,7 +63,7 @@ class Api::V1::Widget::MessagesController < Api::V1::Widget::BaseController def permitted_params # timestamp parameter is used in create conversation method - params.permit(:id, :before, :website_token, contact: [:name, :email], message: [:content, :referer_url, :timestamp, :echo_id]) + params.permit(:id, :before, :after, :website_token, contact: [:name, :email], message: [:content, :referer_url, :timestamp, :echo_id]) end def set_message diff --git a/app/controllers/api/v2/accounts/reports_controller.rb b/app/controllers/api/v2/accounts/reports_controller.rb index 8e95ea594..260400feb 100644 --- a/app/controllers/api/v2/accounts/reports_controller.rb +++ b/app/controllers/api/v2/accounts/reports_controller.rb @@ -72,14 +72,16 @@ class Api::V2::Accounts::ReportsController < Api::V1::Accounts::BaseController def current_summary_params common_params.merge({ since: range[:current][:since], - until: range[:current][:until] + until: range[:current][:until], + timezone_offset: params[:timezone_offset] }) end def previous_summary_params common_params.merge({ since: range[:previous][:since], - until: range[:previous][:until] + until: range[:previous][:until], + timezone_offset: params[:timezone_offset] }) end diff --git a/app/controllers/api_controller.rb b/app/controllers/api_controller.rb index 23178b5f3..eb6f776f1 100644 --- a/app/controllers/api_controller.rb +++ b/app/controllers/api_controller.rb @@ -3,7 +3,7 @@ class ApiController < ApplicationController def index render json: { version: Chatwoot.config[:version], - timestamp: Time.now.utc.to_formatted_s(:db), + timestamp: Time.now.utc.to_fs(:db), queue_services: redis_status, data_services: postgres_status } end diff --git a/app/controllers/public/api/v1/portals/articles_controller.rb b/app/controllers/public/api/v1/portals/articles_controller.rb index af5410fc3..b4739e0d1 100644 --- a/app/controllers/public/api/v1/portals/articles_controller.rb +++ b/app/controllers/public/api/v1/portals/articles_controller.rb @@ -1,7 +1,7 @@ class Public::Api::V1::Portals::ArticlesController < Public::Api::V1::Portals::BaseController before_action :ensure_custom_domain_request, only: [:show, :index] before_action :portal - before_action :set_category, except: [:index] + before_action :set_category, except: [:index, :show] before_action :set_article, only: [:show] layout 'portal' @@ -16,7 +16,7 @@ class Public::Api::V1::Portals::ArticlesController < Public::Api::V1::Portals::B private def set_article - @article = @category.articles.find(permitted_params[:id]) + @article = @portal.articles.find_by(slug: permitted_params[:article_slug]) @article.increment_view_count @parsed_content = render_article_content(@article.content) end @@ -39,7 +39,7 @@ class Public::Api::V1::Portals::ArticlesController < Public::Api::V1::Portals::B end def permitted_params - params.permit(:slug, :category_slug, :locale, :id) + params.permit(:slug, :category_slug, :locale, :id, :article_slug) end def render_article_content(content) diff --git a/app/controllers/public/api/v1/portals/base_controller.rb b/app/controllers/public/api/v1/portals/base_controller.rb index 35dbc3ff9..21b605396 100644 --- a/app/controllers/public/api/v1/portals/base_controller.rb +++ b/app/controllers/public/api/v1/portals/base_controller.rb @@ -5,6 +5,7 @@ class Public::Api::V1::Portals::BaseController < PublicController def set_locale(&) switch_locale_with_portal(&) if params[:locale].present? + switch_locale_with_article(&) if params[:article_slug].present? end def switch_locale_with_portal(&) @@ -19,4 +20,16 @@ class Public::Api::V1::Portals::BaseController < PublicController I18n.with_locale(@locale, &) end + + def switch_locale_with_article(&) + article = Article.find_by(slug: params[:article_slug]) + + @locale = if article.category.present? + article.category.locale + else + 'en' + end + + I18n.with_locale(@locale, &) + end end diff --git a/app/controllers/widgets_controller.rb b/app/controllers/widgets_controller.rb index a4e40eb9c..70e4c967b 100644 --- a/app/controllers/widgets_controller.rb +++ b/app/controllers/widgets_controller.rb @@ -41,7 +41,7 @@ class WidgetsController < ActionController::Base source_id: @auth_token_params[:source_id] ) - @contact = @contact_inbox ? @contact_inbox.contact : nil + @contact = @contact_inbox&.contact end def build_contact diff --git a/app/drops/account_drop.rb b/app/drops/account_drop.rb index 2e3a2530f..d784475db 100644 --- a/app/drops/account_drop.rb +++ b/app/drops/account_drop.rb @@ -1,2 +1,5 @@ class AccountDrop < BaseDrop + def name + @obj.try(:name) + end end diff --git a/app/finders/conversation_finder.rb b/app/finders/conversation_finder.rb index 9472dc623..7ec0a6d30 100644 --- a/app/finders/conversation_finder.rb +++ b/app/finders/conversation_finder.rb @@ -5,7 +5,8 @@ class ConversationFinder SORT_OPTIONS = { latest: 'latest', sort_on_created_at: 'sort_on_created_at', - last_user_message_at: 'last_user_message_at' + last_user_message_at: 'last_user_message_at', + sort_on_priority: 'sort_on_priority' }.with_indifferent_access # assumptions @@ -53,9 +54,10 @@ class ConversationFinder find_all_conversations filter_by_status unless params[:q] - filter_by_team if @team - filter_by_labels if params[:labels] - filter_by_query if params[:q] + filter_by_team + filter_by_labels + filter_by_query + filter_by_source_id end def set_inboxes @@ -106,6 +108,8 @@ class ConversationFinder end def filter_by_query + return unless params[:q] + allowed_message_types = [Message.message_types[:incoming], Message.message_types[:outgoing]] @conversations = conversations.joins(:messages).where('messages.content ILIKE :search', search: "%#{params[:q]}%") .where(messages: { message_type: allowed_message_types }).includes(:messages) @@ -120,13 +124,24 @@ class ConversationFinder end def filter_by_team + return unless @team + @conversations = @conversations.where(team: @team) end def filter_by_labels + return unless params[:labels] + @conversations = @conversations.tagged_with(params[:labels], any: true) end + def filter_by_source_id + return unless params[:source_id] + + @conversations = @conversations.joins(:contact_inbox) + @conversations = @conversations.where(contact_inboxes: { source_id: params[:source_id] }) + end + def set_count_for_all_conversations [ @conversations.assigned_to(current_user).count, diff --git a/app/helpers/date_range_helper.rb b/app/helpers/date_range_helper.rb index 175d6c72b..090512c4f 100644 --- a/app/helpers/date_range_helper.rb +++ b/app/helpers/date_range_helper.rb @@ -7,7 +7,7 @@ module DateRangeHelper def range return if params[:since].blank? || params[:until].blank? - parse_date_time(params[:since])..parse_date_time(params[:until]) + parse_date_time(params[:since])...parse_date_time(params[:until]) end def parse_date_time(datetime) diff --git a/app/helpers/email_helper.rb b/app/helpers/email_helper.rb index 46689ba00..05b6a53e3 100644 --- a/app/helpers/email_helper.rb +++ b/app/helpers/email_helper.rb @@ -10,4 +10,26 @@ module EmailHelper def normalize_email_with_plus_addressing(email) "#{email.split('@').first.split('+').first}@#{email.split('@').last}".downcase end + + def parse_email_variables(conversation, email) + case email + when modified_liquid_content(email) + template = Liquid::Template.parse(modified_liquid_content(email)) + template.render(message_drops(conversation)) + when URI::MailTo::EMAIL_REGEXP + email + end + end + + def modified_liquid_content(email) + # This regex is used to match the code blocks in the content + # We don't want to process liquid in code blocks + email.gsub(/`(.*?)`/m, '{% raw %}`\\1`{% endraw %}') + end + + def message_drops(conversation) + { + 'contact' => ContactDrop.new(conversation.contact) + } + end end diff --git a/app/javascript/dashboard/api/inbox/conversation.js b/app/javascript/dashboard/api/inbox/conversation.js index 8d5f5b82c..bee3cd23b 100644 --- a/app/javascript/dashboard/api/inbox/conversation.js +++ b/app/javascript/dashboard/api/inbox/conversation.js @@ -14,6 +14,7 @@ class ConversationApi extends ApiClient { labels, teamId, conversationType, + sortBy, }) { return axios.get(this.url, { params: { @@ -24,6 +25,7 @@ class ConversationApi extends ApiClient { page, labels, conversation_type: conversationType, + sort_by: sortBy, }, }); } @@ -52,6 +54,12 @@ class ConversationApi extends ApiClient { }); } + togglePriority({ conversationId, priority }) { + return axios.post(`${this.url}/${conversationId}/toggle_priority`, { + priority, + }); + } + assignAgent({ conversationId, agentId }) { return axios.post( `${this.url}/${conversationId}/assignments?assignee_id=${agentId}`, diff --git a/app/javascript/dashboard/api/integrations/openapi.js b/app/javascript/dashboard/api/integrations/openapi.js new file mode 100644 index 000000000..641cfcfbd --- /dev/null +++ b/app/javascript/dashboard/api/integrations/openapi.js @@ -0,0 +1,31 @@ +/* global axios */ + +import ApiClient from '../ApiClient'; + +class OpenAIAPI extends ApiClient { + constructor() { + super('integrations', { accountScoped: true }); + } + + processEvent({ type = 'rephrase', content, tone, conversationId, hookId }) { + let data = { + tone, + content, + }; + + if (type === 'reply_suggestion' || type === 'summarize') { + data = { + conversation_display_id: conversationId, + }; + } + + return axios.post(`${this.url}/hooks/${hookId}/process_event`, { + event: { + name: type, + data, + }, + }); + } +} + +export default new OpenAIAPI(); diff --git a/app/javascript/dashboard/api/reports.js b/app/javascript/dashboard/api/reports.js index 89b8554a5..7bc07b565 100644 --- a/app/javascript/dashboard/api/reports.js +++ b/app/javascript/dashboard/api/reports.js @@ -40,6 +40,7 @@ class ReportsAPI extends ApiClient { id, group_by: groupBy, business_hours: businessHours, + timezone_offset: getTimeOffset(), }, }); } diff --git a/app/javascript/dashboard/api/search.js b/app/javascript/dashboard/api/search.js index 2e4c3b198..7dc98dcf2 100644 --- a/app/javascript/dashboard/api/search.js +++ b/app/javascript/dashboard/api/search.js @@ -13,6 +13,30 @@ class SearchAPI extends ApiClient { }, }); } + + contacts({ q }) { + return axios.get(`${this.url}/contacts`, { + params: { + q, + }, + }); + } + + conversations({ q }) { + return axios.get(`${this.url}/conversations`, { + params: { + q, + }, + }); + } + + messages({ q }) { + return axios.get(`${this.url}/messages`, { + params: { + q, + }, + }); + } } export default new SearchAPI(); diff --git a/app/javascript/dashboard/api/specs/reports.spec.js b/app/javascript/dashboard/api/specs/reports.spec.js index b59a23ad5..368997859 100644 --- a/app/javascript/dashboard/api/specs/reports.spec.js +++ b/app/javascript/dashboard/api/specs/reports.spec.js @@ -42,9 +42,13 @@ describe('#Reports API', () => { '/api/v2/reports/summary', { params: { + business_hours: undefined, + group_by: undefined, + id: undefined, since: 1621103400, - until: 1621621800, + timezone_offset: -0, type: 'account', + until: 1621621800, }, } ); diff --git a/app/javascript/dashboard/assets/scss/_foundation-settings.scss b/app/javascript/dashboard/assets/scss/_foundation-settings.scss index 28defb4fd..a6e0b1aa3 100644 --- a/app/javascript/dashboard/assets/scss/_foundation-settings.scss +++ b/app/javascript/dashboard/assets/scss/_foundation-settings.scss @@ -254,7 +254,7 @@ $button-sizes: (tiny: var(--font-size-micro), default: var(--font-size-small), large: var(--font-size-medium)); $button-palette: $foundation-palette; -$button-opacity-disabled: 0.25; +$button-opacity-disabled: 0.4; $button-background-hover-lightness: -20%; $button-hollow-hover-lightness: -50%; $button-transition: background-color 0.25s ease-out, diff --git a/app/javascript/dashboard/assets/scss/_rtl.scss b/app/javascript/dashboard/assets/scss/_rtl.scss index 48790f715..0ed2fe2f4 100644 --- a/app/javascript/dashboard/assets/scss/_rtl.scss +++ b/app/javascript/dashboard/assets/scss/_rtl.scss @@ -85,7 +85,7 @@ } } - .settings.back-button { + .header-section.back-button { direction: initial; margin-left: var(--space-normal); margin-right: var(--space-smaller); diff --git a/app/javascript/dashboard/assets/scss/plugins/_multiselect.scss b/app/javascript/dashboard/assets/scss/plugins/_multiselect.scss index 4e534bc99..3167b2085 100644 --- a/app/javascript/dashboard/assets/scss/plugins/_multiselect.scss +++ b/app/javascript/dashboard/assets/scss/plugins/_multiselect.scss @@ -21,7 +21,7 @@ .multiselect--active { >.multiselect__tags { - border-color: $color-woot; + border-color: var(--w-500); } } @@ -75,16 +75,13 @@ } &.multiselect__option--selected { - background: var(--w-400); - color: var(--white); + background: var(--w-75); &.multiselect__option--highlight:hover { - background: var(--w-600); - color: var(--white); + background: var(--w-75); &::after { background: transparent; - color: var(--white); } &::after:hover { @@ -196,6 +193,7 @@ display: flex; font-size: var(--font-size-small); margin: 0; + max-height: 3.8rem; padding: var(--space-smaller) var(--space-micro); } diff --git a/app/javascript/dashboard/assets/scss/widgets/_conversation-view.scss b/app/javascript/dashboard/assets/scss/widgets/_conversation-view.scss index 97adeed4c..6c37e5677 100644 --- a/app/javascript/dashboard/assets/scss/widgets/_conversation-view.scss +++ b/app/javascript/dashboard/assets/scss/widgets/_conversation-view.scss @@ -95,10 +95,6 @@ align-items: center; justify-content: space-between; padding: 0 var(--space-normal); - - .page-title { - margin-bottom: 0; - } } .content-box { diff --git a/app/javascript/dashboard/components/ChatList.vue b/app/javascript/dashboard/components/ChatList.vue index dd9e353b8..7995c91fd 100644 --- a/app/javascript/dashboard/components/ChatList.vue +++ b/app/javascript/dashboard/components/ChatList.vue @@ -11,15 +11,23 @@ class="chat-list__top" :class="{ filter__applied: hasAppliedFiltersOrActiveFolders }" > -