Module: Glib::Json::Libs
- Extended by:
- ActiveSupport::Concern
- Defined in:
- app/controllers/concerns/glib/json/libs.rb
Defined Under Namespace
Modules: ClassMethods
Constant Summary collapse
- REDIRECT_BACK_KEY =
:glib_return_to_url
Instance Method Summary collapse
- #__delete_redirect_back_url(url) ⇒ Object
-
#__glib_error_dialog(title, message, style_classes, bottom_views = []) ⇒ Object
def json_ui_redirect_back_or_to(default_url, json_action) redirect_url = __delete_redirect_back_url(default_url) json_action.windows_closeAll onClose: ->(subaction) do puts "***** R2: #redirect_url" subaction.windows_open url: redirect_url end end.
- #delete_redirect_back_url(url) ⇒ Object
- #glib_force_json_ui ⇒ Object
- #glib_handle_401(sign_in_url, **redirect_options) ⇒ Object
-
#glib_handle_403(user_default_url) ⇒ Object
The behaviour provided by this convenience method assumes that user is logged in.
- #glib_handle_404 ⇒ Object
- #glib_html_url(url) ⇒ Object
- #glib_json_handle_404(exception, preview_mode) ⇒ Object
- #glib_json_handle_500(exception, preview_mode) ⇒ Object
- #glib_redirect_to(url, return_to_previous: false, status: :ok) ⇒ Object
- #json_ui_app_build_version ⇒ Object
- #json_ui_app_bundle_id ⇒ Object
- #json_ui_app_device_os ⇒ Object
- #json_ui_app_is_android? ⇒ Boolean
- #json_ui_app_is_ios? ⇒ Boolean
- #json_ui_app_is_web? ⇒ Boolean
- #json_ui_etag ⇒ Object
- #json_ui_redirect_to(url, status: :ok) ⇒ Object
- #json_ui_render(template, args = {}) ⇒ Object
- #json_ui_save_return_url(url = nil) ⇒ Object
- #redirect_back_url ⇒ Object
Instance Method Details
#__delete_redirect_back_url(url) ⇒ Object
228 229 230 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 228 def __delete_redirect_back_url(url) session.delete(REDIRECT_BACK_KEY) || url end |
#__glib_error_dialog(title, message, style_classes, bottom_views = []) ⇒ Object
def json_ui_redirect_back_or_to(default_url, json_action) redirect_url = __delete_redirect_back_url(default_url) json_action.windows_closeAll onClose: ->(subaction) do puts "***** R2: #redirect_url" subaction.windows_open url: redirect_url end end
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 249 def __glib_error_dialog(title, , style_classes, bottom_views = []) { action: Glib::JsonUi::Name.for('dialogs/show'), # Don't show another dialog, just use the current one since it's a new dialog anyway, which means # that it wouldn't contain existing user data. updateExisting: glib_json_dialog_mode?, title: title, body: { childViews: [ { view: Glib::JsonUi::Name.for('panels/vertical'), styleClasses: ['glib-error-dialog'].concat(style_classes), childViews: [ { view: 'label', text: }, ].concat(bottom_views), } ] # Set this in the project's custom CSS. # padding: { # x: 20, # y: 22, # }, } } end |
#delete_redirect_back_url(url) ⇒ Object
232 233 234 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 232 def delete_redirect_back_url(url) __delete_redirect_back_url(url) end |
#glib_force_json_ui ⇒ Object
114 115 116 117 118 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 114 def glib_force_json_ui if params[:_render] != 'v1' redirect_to url_for(params.to_unsafe_h.merge(_render: 'v1')) end end |
#glib_handle_401(sign_in_url, **redirect_options) ⇒ Object
136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 136 def glib_handle_401(sign_in_url, **) if !glib_json_dialog_mode? && request.get? json_ui_save_return_url end respond_to do |format| format.html do redirect_to sign_in_url, ** end format.json do render \ json: json_ui_401_response(sign_in_url, **), status: Rails.env.test? ? :unauthorized : :ok end format.csv do if Rails.env.test? head :unauthorized else redirect_to sign_in_url, ** end end # Other non-HTML/JSON formats (a protected file link whose filename sets the # request format, an XML export, ...) used to raise UnknownFormat -> a bare 406. # Mirrors the csv branch: a clean gate status in test, a redirect in production. # MUST stay the LAST block -- see glib_redirect_to. format.any do if Rails.env.test? head :unauthorized else redirect_to sign_in_url, ** end end end end |
#glib_handle_403(user_default_url) ⇒ Object
The behaviour provided by this convenience method assumes that user is logged in.
When accessing a forbidden page, redirects to user_default_url because we don't
want the user to get confused in the scenario where after logging in,
glib_redirect_back_or_to tries to open a page that the user doesn't have access of.
175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 175 def glib_handle_403(user_default_url) respond_to do |format| format.html do redirect_to user_default_url end format.json do if __json_ui_rendering? redirect_to user_default_url return end json_response = \ if glib_json_dialog_mode? { onLoad: __glib_error_dialog( 'Access denied', "Make sure you're logged in with the correct account.", ['dialog-403-error'] ) } else { onResponse: { action: Glib::JsonUi::Name.for('windows/open'), url: user_default_url } } end render json: json_response, status: Rails.env.test? ? :forbidden : :ok end format.csv do if Rails.env.test? head :forbidden else redirect_to user_default_url end end # Other non-HTML/JSON formats -- mirrors the csv branch (clean gate status in # test, redirect in production); previously raised UnknownFormat -> a bare 406. # MUST stay the LAST block -- see glib_redirect_to. format.any do if Rails.env.test? head :forbidden else redirect_to user_default_url end end end end |
#glib_handle_404 ⇒ Object
120 121 122 123 124 125 126 127 128 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 120 def glib_handle_404 raise ActionController::RoutingError.new('Not Found') # if json_ui_activated? # render file: Rails.root.join('public', '404.html'), status: :not_found # else # raise exception # end end |
#glib_html_url(url) ⇒ Object
66 67 68 69 70 71 72 73 74 75 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 66 def glib_html_url(url) url = url.include?('?') ? url.sub(/.json\?/, '?') : url.sub(/.json$/, '') # As much as possible, try retaining the front fragment by matching the back, because # the front could be either a `?` or `&` url = url.sub(/format=json\&/, '') # If no match, then we replace the front fragment url.sub(/[\&\?]format=json/, '') end |
#glib_json_handle_404(exception, preview_mode) ⇒ Object
301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 301 def glib_json_handle_404(exception, preview_mode) if json_ui_activated? if Rails.env.production? || preview_mode # As with glib_json_handle_500: if a response was already rendered (e.g. an # after_action raised RecordNotFound), rendering the 404 page on top would raise # AbstractController::DoubleRenderError and mask the real exception. Keep the # already-rendered response instead of double-rendering. return if performed? render file: Rails.root.join('public', '404.html'), status: :not_found else raise exception end else raise exception end end |
#glib_json_handle_500(exception, preview_mode) ⇒ Object
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 278 def glib_json_handle_500(exception, preview_mode) if json_ui_activated? if Rails.env.production? || preview_mode if defined?(Rollbar) && !preview_mode Rollbar.error(exception, use_exception_level_filters: true) end # The exception may have been raised AFTER a response was already rendered # (e.g. from an after_action injection). Rendering the error page on top of that # would raise AbstractController::DoubleRenderError, which masks the genuine # exception reported above. The real cause is already logged, so leave the # already-rendered response in place rather than double-rendering. return if performed? render file: Rails.root.join('public', '500.html'), status: :internal_server_error else raise exception end else raise exception end end |
#glib_redirect_to(url, return_to_previous: false, status: :ok) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 77 def glib_redirect_to(url, return_to_previous: false, status: :ok) url = __delete_redirect_back_url(url) if return_to_previous respond_to do |format| format.html do redirect_to url end format.json do if __json_ui_rendering? redirect_to glib_html_url(url) return end # Inside a dialog, it's easier to simply use HTTP redirect, as opposed to trying to # get the dialog to perform manual redirection. if glib_json_dialog_mode? redirect_to url return end json_ui_redirect_to url, status: status end # Any other request format (e.g. a browser tab opening a protected file link # `/temp_blobs/:id/report.pdf`, where the filename sets the format) used to raise # ActionController::UnknownFormat -> a bare 406 with an empty body. Mirror the html # branch instead: whatever opened the URL (browser tab, iframe, img) is redirected # to the target, which the browser follows natively. # # MUST stay the LAST block. `negotiate_mime` answers `Accept: */*` requests with # the FIRST declared format, so an `any` block placed before html would capture # ordinary browser page loads and leave request.format as `*/*` for the action. format.any do redirect_to url end end end |
#json_ui_app_build_version ⇒ Object
20 21 22 23 24 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 20 def json_ui_app_build_version @json_ui_app_build_version ||= request.headers['GApp-Build-Version'] || request.headers['JsonUiApp-Build-Version'] @json_ui_app_build_version = params[:build_version] if @json_ui_app_build_version.nil? && Rails.env.development? # For easy testing @json_ui_app_build_version end |
#json_ui_app_bundle_id ⇒ Object
16 17 18 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 16 def json_ui_app_bundle_id @json_ui_app_bundle_id ||= request.headers['GApp-Bundle-Id'] || request.headers['JsonUiApp-Bundle-Id'] end |
#json_ui_app_device_os ⇒ Object
26 27 28 29 30 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 26 def json_ui_app_device_os @json_ui_app_device_os ||= request.headers['GApp-Device-Os'] || request.headers['JsonUiApp-Device-Os'] @json_ui_app_device_os = params[:device_os] if @json_ui_app_device_os.nil? && Rails.env.development? # For easy testing @json_ui_app_device_os || 'web' end |
#json_ui_app_is_android? ⇒ Boolean
32 33 34 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 32 def json_ui_app_is_android? json_ui_app_device_os == 'android' end |
#json_ui_app_is_ios? ⇒ Boolean
36 37 38 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 36 def json_ui_app_is_ios? json_ui_app_device_os == 'ios' end |
#json_ui_app_is_web? ⇒ Boolean
40 41 42 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 40 def json_ui_app_is_web? json_ui_app_device_os == 'web' end |
#json_ui_etag ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 44 def json_ui_etag template = "#{controller_name}/#{action_name}" # 1) It's necessary to pass in the template explicitly because of the switching between JSON # and HTML rendering. # # 2) When a model is not provided, two pages the use the same template (e.g. `projects#show`) # will produce the exact same ETAG, even though their content might be different. Presumably # this is because the ETAG is calculated based on the static template as opposed to the # generated output. # # However, this is not a problem because the browser will still treat these pages as # separate because they have different URLs (e.g. `projects/1` vs `projects/2`), meaning # that it will not accidentally use the cache from a different URL even though the ETAG # is exactly the same. fresh_when nil, template: template end |
#json_ui_redirect_to(url, status: :ok) ⇒ Object
319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 319 def json_ui_redirect_to(url, status: :ok) # Use windows_reload instead of windows_open so clicking back will skip the bridging page. # on_response = { action: 'windows/open', url: url } on_response = { action: Glib::JsonUi::Name.for('windows/reload'), url: url } if glib_json_dialog_mode? # Only do this in dialog mode because this seems to add to the rendering time # (i.e. longer flicker time), presumably due to the use of things like `nextTick()`. on_response = { action: Glib::JsonUi::Name.for('dialogs/close'), onClose: on_response } end # Use onResponse because it is harder to guarantee that `onLoad` executes in Vuejs because it relies # on app.vue's reactivity. render json: { onResponse: on_response }, status: status end |
#json_ui_render(template, args = {}) ⇒ Object
62 63 64 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 62 def json_ui_render(template, args = {}) JSON.parse(render_to_string(template, locals: args)) end |
#json_ui_save_return_url(url = nil) ⇒ Object
132 133 134 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 132 def json_ui_save_return_url(url = nil) session[REDIRECT_BACK_KEY] = url || url_for(params.to_unsafe_h.merge(format: nil)) end |
#redirect_back_url ⇒ Object
224 225 226 |
# File 'app/controllers/concerns/glib/json/libs.rb', line 224 def redirect_back_url session[REDIRECT_BACK_KEY] end |