feat: Add support for minutes in auto resolve feature (#11269)

### Summary

- Converts conversation auto-resolution duration from days to minutes
for more
granular control
- Updates validation to allow values from 10 minutes (minimum) to 999
days (maximum)
- Implements smart messaging to show appropriate time units in activity
messages

###  Changes

- Created migration to convert existing durations from days to minutes
(x1440)
- Updated conversation resolver to use minutes instead of days
- Added dynamic translation key selection based on duration value
- Updated related specs and documentation
- Added support for displaying durations in days, hours, or minutes
based on value

###  Test plan

- Verify account validation accepts new minute-based ranges
- Confirm existing account settings are correctly migrated
- Test auto-resolution works properly with minute values
- Ensure proper time unit display in activity messages

---------

Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
This commit is contained in:
Shivam Mishra
2025-05-07 13:06:15 +05:30
committed by GitHub
parent e08436dde5
commit b533980880
34 changed files with 864 additions and 367 deletions

View File

@@ -56,13 +56,24 @@ module ActivityMessageHandler
::Conversations::ActivityMessageJob.perform_later(self, activity_message_params(content)) if content
end
def auto_resolve_message_key(minutes)
if minutes >= 1440 && (minutes % 1440).zero?
{ key: 'auto_resolved_days', count: minutes / 1440 }
elsif minutes >= 60 && (minutes % 60).zero?
{ key: 'auto_resolved_hours', count: minutes / 60 }
else
{ key: 'auto_resolved_minutes', count: minutes }
end
end
def user_status_change_activity_content(user_name)
if user_name
I18n.t("conversations.activity.status.#{status}", user_name: user_name)
elsif Current.contact.present? && resolved?
I18n.t('conversations.activity.status.contact_resolved', contact_name: Current.contact.name.capitalize)
elsif resolved?
I18n.t('conversations.activity.status.auto_resolved', duration: auto_resolve_duration)
message_data = auto_resolve_message_key(auto_resolve_after || 0)
I18n.t("conversations.activity.status.#{message_data[:key]}", count: message_data[:count])
end
end

View File

@@ -56,6 +56,8 @@ class JsonSchemaValidator < ActiveModel::Validator
def format_and_append_error(error, record)
return handle_required(error, record) if error['type'] == 'required'
return handle_minimum(error, record) if error['type'] == 'minimum'
return handle_maximum(error, record) if error['type'] == 'maximum'
type = error['type'] == 'object' ? 'hash' : error['type']
@@ -74,6 +76,16 @@ class JsonSchemaValidator < ActiveModel::Validator
record.errors.add(data, "must be of type #{expected_type}")
end
def handle_minimum(error, record)
data = get_name_from_data_pointer(error)
record.errors.add(data, "must be greater than or equal to #{error['schema']['minimum']}")
end
def handle_maximum(error, record)
data = get_name_from_data_pointer(error)
record.errors.add(data, "must be less than or equal to #{error['schema']['maximum']}")
end
def get_name_from_data_pointer(error)
data = error['data_pointer']