diff --git a/AGENTS.md b/AGENTS.md index e3b022a2e..ef1d3b26d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,6 +10,9 @@ - **Test Ruby**: `bundle exec rspec spec/path/to/file_spec.rb` - **Single Test**: `bundle exec rspec spec/path/to/file_spec.rb:LINE_NUMBER` - **Run Project**: `overmind start -f Procfile.dev` +- **Ruby Version**: Manage Ruby via `rbenv` and install the version listed in `.ruby-version` (e.g., `rbenv install $(cat .ruby-version)`) +- **rbenv setup**: Before running any `bundle` or `rspec` commands, init rbenv in your shell (`eval "$(rbenv init -)"`) so the correct Ruby/Bundler versions are used +- Always prefer `bundle exec` for Ruby CLI tasks (rspec, rake, rubocop, etc.) ## Code Style @@ -37,6 +40,8 @@ - MVP focus: Least code change, happy-path only - No unnecessary defensive programming +- Ship the happy path first: limit guards/fallbacks to what production has proven necessary, then iterate +- Prefer minimal, readable code over elaborate abstractions; clarity beats cleverness - Break down complex tasks into small, testable units - Iterate after confirmation - Avoid writing specs unless explicitly asked diff --git a/app/builders/contact_inbox_builder.rb b/app/builders/contact_inbox_builder.rb index 788ae39d1..40e571f43 100644 --- a/app/builders/contact_inbox_builder.rb +++ b/app/builders/contact_inbox_builder.rb @@ -103,3 +103,5 @@ class ContactInboxBuilder @inbox.email? || @inbox.sms? || @inbox.twilio? || @inbox.whatsapp? end end + +ContactInboxBuilder.prepend_mod_with('ContactInboxBuilder') diff --git a/app/builders/messages/message_builder.rb b/app/builders/messages/message_builder.rb index af31a0728..7df72e14a 100644 --- a/app/builders/messages/message_builder.rb +++ b/app/builders/messages/message_builder.rb @@ -138,6 +138,7 @@ class Messages::MessageBuilder private: @private, sender: sender, content_type: @params[:content_type], + content_attributes: content_attributes.presence, items: @items, in_reply_to: @in_reply_to, echo_id: @params[:echo_id], @@ -222,3 +223,5 @@ class Messages::MessageBuilder }) end end + +Messages::MessageBuilder.prepend_mod_with('Messages::MessageBuilder') diff --git a/app/javascript/dashboard/api/contacts.js b/app/javascript/dashboard/api/contacts.js index 025df2122..1e76ac987 100644 --- a/app/javascript/dashboard/api/contacts.js +++ b/app/javascript/dashboard/api/contacts.js @@ -47,6 +47,12 @@ class ContactAPI extends ApiClient { return axios.get(`${this.url}/${contactId}/labels`); } + initiateCall(contactId, inboxId) { + return axios.post(`${this.url}/${contactId}/call`, { + inbox_id: inboxId, + }); + } + updateContactLabels(contactId, labels) { return axios.post(`${this.url}/${contactId}/labels`, { labels }); } diff --git a/app/javascript/dashboard/components-next/Contacts/ContactsDetailsLayout.vue b/app/javascript/dashboard/components-next/Contacts/ContactsDetailsLayout.vue index 4c7b9249e..fd755022d 100644 --- a/app/javascript/dashboard/components-next/Contacts/ContactsDetailsLayout.vue +++ b/app/javascript/dashboard/components-next/Contacts/ContactsDetailsLayout.vue @@ -102,6 +102,7 @@ const closeMobileSidebar = () => { /> diff --git a/app/javascript/dashboard/components-next/Contacts/VoiceCallButton.vue b/app/javascript/dashboard/components-next/Contacts/VoiceCallButton.vue index 98e56ff8f..85738d9de 100644 --- a/app/javascript/dashboard/components-next/Contacts/VoiceCallButton.vue +++ b/app/javascript/dashboard/components-next/Contacts/VoiceCallButton.vue @@ -1,15 +1,18 @@ @@ -55,6 +96,8 @@ const onPickInbox = () => { v-if="shouldRender" v-tooltip.top-end="tooltipLabel || null" v-bind="attrs" + :disabled="isInitiatingCall" + :is-loading="isInitiatingCall" :label="label" :icon="icon" :size="size" diff --git a/app/javascript/dashboard/components-next/message/bubbles/VoiceCall.vue b/app/javascript/dashboard/components-next/message/bubbles/VoiceCall.vue index b7ede029f..5a7d39a4e 100644 --- a/app/javascript/dashboard/components-next/message/bubbles/VoiceCall.vue +++ b/app/javascript/dashboard/components-next/message/bubbles/VoiceCall.vue @@ -1,41 +1,102 @@