Skip to content

Commit

Permalink
Merge pull request #4866 from rubyforgood/elhalvers/4828-local-timezone
Browse files Browse the repository at this point in the history
Elhalvers/4828 local timezone
  • Loading branch information
compwron authored Jun 12, 2023
2 parents 017ed9d + a099c48 commit 28dfbad
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 14 deletions.
1 change: 1 addition & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
class ApplicationController < ActionController::Base
include Pundit::Authorization
include Organizational
include Users::TimeZone

protect_from_forgery
before_action :store_user_location!, if: :storable_location?
Expand Down
16 changes: 16 additions & 0 deletions app/controllers/concerns/users/time_zone.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module Users
module TimeZone
extend ActiveSupport::Concern

included do
helper_method :browser_time_zone
end

def browser_time_zone
browser_tz = ActiveSupport::TimeZone.find_tzinfo(cookies[:browser_time_zone])
ActiveSupport::TimeZone.all.find { |zone| zone.tzinfo == browser_tz } || Time.zone
rescue TZInfo::UnknownTimezone, TZInfo::InvalidTimezoneIdentifier
Time.zone
end
end
end
34 changes: 22 additions & 12 deletions app/decorators/user_decorator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,43 @@ def status
object.active ? "Active" : "Inactive"
end

def formatted_created_at
def local_time_zone
h.browser_time_zone
end

# helper method to 'DRY' up the other methods : )
def formatted_timestamp(attribute)
format_key = context[:format] || :full
I18n.l(object.created_at, format: format_key, default: nil)
timestamp = object.public_send(attribute)

if format_key == :edit_profile
I18n.l(timestamp&.in_time_zone(local_time_zone), format: format_key, default: nil)
else
I18n.l(timestamp, format: format_key, default: nil)
end
end

def formatted_created_at
formatted_timestamp(:created_at)
end

def formatted_updated_at
format_key = context[:format] || :full
I18n.l(object.updated_at, format: format_key, default: nil)
formatted_timestamp(:updated_at)
end

def formatted_current_sign_in_at
format_key = context[:format] || :full
I18n.l(object.current_sign_in_at, format: format_key, default: nil)
formatted_timestamp(:current_sign_in_at)
end

def formatted_invitation_accepted_at
format_key = context[:format] || :full
I18n.l(object.invitation_accepted_at, format: format_key, default: nil)
formatted_timestamp(:invitation_accepted_at)
end

def formatted_reset_password_sent_at
format_key = context[:format] || :full
I18n.l(object.reset_password_sent_at, format: format_key, default: nil)
formatted_timestamp(:reset_password_sent_at)
end

def formatted_invitation_sent_at
format_key = context[:format] || :full
I18n.l(object.invitation_sent_at, format: format_key, default: nil)
formatted_timestamp(:invitation_sent_at)
end
end
1 change: 1 addition & 0 deletions app/javascript/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ require('./src/require_communication_preference')
require('./src/select')
require('./src/sidebar')
require('./src/tooltip')
require('./src/time_zone')
require('./src/session_timeout_poller.js')
require('./src/display_app_metric.js')
20 changes: 20 additions & 0 deletions app/javascript/src/time_zone.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Cookies from 'js-cookie'
import jstz from 'jstz'

// Rails doesn't support every timezone that Intl supports
export function findTimeZone () {
const oldIntl = window.Intl
try {
window.Intl = undefined
const tz = jstz.determine().name()
window.Intl = oldIntl
return tz
} catch (e) {
// sometimes (on android) you can't override intl
return jstz.determine().name()
}
}

document.addEventListener('DOMContentLoaded', () => {
Cookies.set('browser_time_zone', findTimeZone(), { expires: 365, path: '/', secure: true, sameSite: 'strict' })
})
2 changes: 1 addition & 1 deletion config/locales/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ en:
full: "%B %-d, %Y"
youth_date_of_birth: "%B %Y"
short_date: "%-m/%d"
edit_profile: "%B %d, %Y at %-l:%M %p"
edit_profile: "%B %d, %Y at %I:%M %p %Z"
notifications:
emancipation_checklist_reminder_notification:
title: "Emancipation Checklist Reminder"
Expand Down
18 changes: 18 additions & 0 deletions db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,14 @@
t.index ["user_id"], name: "index_preference_sets_on_user_id"
end

create_table "preferences", force: :cascade do |t|
t.bigint "user_id"
t.jsonb "case_volunteer_columns", default: "{}", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["user_id"], name: "index_preferences_on_user_id"
end

create_table "sent_emails", force: :cascade do |t|
t.bigint "user_id"
t.bigint "casa_org_id", null: false
Expand Down Expand Up @@ -552,6 +560,16 @@
t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
end

create_table "versions", force: :cascade do |t|
t.string "item_type", null: false
t.bigint "item_id", null: false
t.string "event", null: false
t.string "whodunnit"
t.text "object"
t.datetime "created_at", precision: nil
t.index ["item_type", "item_id"], name: "index_versions_on_item_type_and_item_id"
end

add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
add_foreign_key "additional_expenses", "case_contacts"
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@
"esbuild": "^0.17.19",
"faker": "^5.5.3",
"jquery": "^3.6.4",
"js-cookie": "^3.0.5",
"jstz": "^2.1.1",
"lodash": "^4.17.21",
"luxon": "^3.3.0",
"popper.js": "^1.16.1",
Expand Down
40 changes: 40 additions & 0 deletions spec/controllers/concerns/users/time_zone_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
require "rails_helper"

class MockController < ApplicationController
include Users::TimeZone
end

RSpec.describe MockController, type: :controller do
let(:browser_time_zone) { "America/Los_Angeles" }
before do
allow(controller).to receive(:cookies).and_return(browser_time_zone: browser_time_zone)
end

describe "#browser_time_zone" do
it "returns the matching time zone" do
browser_tz = ActiveSupport::TimeZone.find_tzinfo(browser_time_zone)
matching_zone = ActiveSupport::TimeZone.all.find { |zone| zone.tzinfo == browser_tz }
expect(controller.browser_time_zone).to eq(matching_zone || Time.zone)
end

context "when browser_time_zone cookie is not set" do
before do
allow(controller).to receive(:cookies).and_return({})
end

it "returns the default time zone" do
expect(controller.browser_time_zone).to eq(Time.zone)
end
end

context "when browser_time_zone cookie contains an invalid value" do
before do
allow(controller).to receive(:cookies).and_return(browser_time_zone: "Invalid/Timezone")
end

it "returns the default time zone" do
expect(controller.browser_time_zone).to eq(Time.zone)
end
end
end
end
2 changes: 1 addition & 1 deletion spec/system/users/edit_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@
.to match("Your CASA password has been changed.")
end

it "is able to send a confrimation email when Volunteer updates their email" do
it "is able to send a confirmation email when Volunteer updates their email" do
click_on "Change Email"
expect(page).to have_field("New Email", disabled: false)

Expand Down
10 changes: 10 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4033,6 +4033,11 @@ jquery@>=1.7, "jquery@>=3.4.0 <4.0.0", jquery@^3.6.4:
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.7.0.tgz#fe2c01a05da500709006d8790fe21c8a39d75612"
integrity sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ==

js-cookie@^3.0.5:
version "3.0.5"
resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-3.0.5.tgz#0b7e2fd0c01552c58ba86e0841f94dc2557dcdbc"
integrity sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==

js-sdsl@^4.1.4:
version "4.1.4"
resolved "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz"
Expand Down Expand Up @@ -4133,6 +4138,11 @@ json5@^2.2.1:
resolved "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz"
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==

jstz@^2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/jstz/-/jstz-2.1.1.tgz#fff3373a518fa7cce69299930466f5a2b980389d"
integrity sha512-8hfl5RD6P7rEeIbzStBz3h4f+BQHfq/ABtoU6gXKQv5OcZhnmrIpG7e1pYaZ8hS9e0mp+bxUj08fnDUbKctYyA==

"jsx-ast-utils@^2.4.1 || ^3.0.0":
version "3.3.3"
resolved "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz"
Expand Down

0 comments on commit 28dfbad

Please sign in to comment.