Files
gochat/frontend/config/initializers/01_inject_enterprise_edition_module.rb
T
rogee 321c61aaae Vendor Chatwoot Vue 3 frontend into frontend/
Copy the Chatwoot (v4.14.0) frontend runnable subset into frontend/ for
customization:
- app/javascript/ (Vue SPA: dashboard, widget, sdk, portal, superadmin)
- app/views/ (ERB templates for vite-plugin-ruby entrypoint resolution)
- app/helpers/, app/assets/ (Rails view helpers, static assets)
- enterprise/ (Enterprise edition frontend overlay)
- config/vite.json, vite.config.ts, bin/vite (Vite-Rails toolchain)
- package.json, pnpm-lock.yaml, tailwind/postcss/eslint configs
- Gemfile, Gemfile.lock (vite_rails gem for bin/vite binstub)

Excluded Rails backend: controllers, models, services, jobs, mailers,
policies, db, lib, spec, public, node_modules.

Update references to the new frontend location:
- .gitignore: exclude frontend build artifacts (node_modules, tmp, packs),
  keep frontend/bin/ and frontend/vendor/ via negation
- backend/scripts/parity_frontend_smoke.sh: CHATWOOT_DIR default
  reference/chatwoot -> ../frontend
- backend/scripts/parity_frontend_browser_smoke.mjs: same default update
- AGENTS.md: add frontend section with Rails/Vite coupling notes
- README: architecture tree includes frontend/
2026-07-07 14:56:01 +08:00

88 lines
2.5 KiB
Ruby

# frozen_string_literal: true
# original Authors: Gitlab
# https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/initializers/0_inject_enterprise_edition_module.rb
#
### Ref: https://medium.com/@leo_hetsch/ruby-modules-include-vs-prepend-vs-extend-f09837a5b073
# Ancestors chain : it holds a list of constant names which are its ancestors
# example, by calling ancestors on the String class,
# String.ancestors => [String, Comparable, Object, PP::ObjectMixin, Kernel, BasicObject]
#
# Include: Ruby will insert the module into the ancestors chain of the class, just after its superclass
# ancestor chain : [OriginalClass, IncludedModule, ...]
#
# Extend: class will actually import the module methods as class methods
#
# Prepend: Ruby will look into the module methods before looking into the class.
# ancestor chain : [PrependedModule, OriginalClass, ...]
########
require 'active_support/inflector'
module InjectEnterpriseEditionModule
def prepend_mod_with(constant_name, namespace: Object, with_descendants: false)
each_extension_for(constant_name, namespace) do |constant|
prepend_module(constant, with_descendants)
end
end
def extend_mod_with(constant_name, namespace: Object)
# rubocop:disable Performance/MethodObjectAsBlock
each_extension_for(
constant_name,
namespace,
&method(:extend)
)
# rubocop:enable Performance/MethodObjectAsBlock
end
def include_mod_with(constant_name, namespace: Object)
# rubocop:disable Performance/MethodObjectAsBlock
each_extension_for(
constant_name,
namespace,
&method(:include)
)
# rubocop:enable Performance/MethodObjectAsBlock
end
def prepend_mod(with_descendants: false)
prepend_mod_with(name, with_descendants: with_descendants)
end
def extend_mod
extend_mod_with(name)
end
def include_mod
include_mod_with(name)
end
private
def prepend_module(mod, with_descendants)
prepend(mod)
descendants.each { |descendant| descendant.prepend(mod) } if with_descendants
end
def each_extension_for(constant_name, namespace)
ChatwootApp.extensions.each do |extension_name|
extension_namespace =
const_get_maybe_false(namespace, extension_name.camelize)
extension_module =
const_get_maybe_false(extension_namespace, constant_name)
yield(extension_module) if extension_module
end
end
def const_get_maybe_false(mod, name)
mod&.const_defined?(name, false) && mod&.const_get(name, false)
end
end
Module.prepend(InjectEnterpriseEditionModule)