glib-web 6.12.0 → 7.0.0.beta1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/app/controllers/concerns/glib/auth/policy.rb +1 -5
- data/app/controllers/concerns/glib/json/libs.rb +0 -33
- data/app/helpers/glib/json_ui/action_builder/bottom_banners.rb +0 -1
- data/app/helpers/glib/json_ui/action_builder/components.rb +1 -16
- data/app/helpers/glib/json_ui/action_builder/logics.rb +1 -2
- data/app/helpers/glib/json_ui/action_builder/snackbars.rb +0 -16
- data/app/helpers/glib/json_ui/response_helper.rb +0 -12
- data/app/helpers/glib/json_ui/view_builder/fields.rb +4 -133
- data/app/helpers/glib/json_ui/view_builder/panels.rb +144 -8
- data/app/views/json_ui/garage/actions/_components.json.jbuilder +2 -2
- data/app/views/json_ui/garage/forms/bulk_edit_post.json.jbuilder +1 -1
- data/app/views/json_ui/garage/forms/checkboxes.json.jbuilder +3 -3
- data/app/views/json_ui/garage/forms/selects.json.jbuilder +5 -5
- data/app/views/json_ui/garage/forms/update_options.json.jbuilder +1 -1
- data/app/views/json_ui/garage/panels/flow.json.jbuilder +6 -6
- data/app/views/json_ui/garage/panels/horizontal.json.jbuilder +10 -10
- data/app/views/json_ui/garage/panels/responsive.json.jbuilder +10 -10
- data/app/views/json_ui/garage/panels/ul.json.jbuilder +2 -2
- data/app/views/json_ui/garage/panels/vertical.json.jbuilder +10 -10
- data/app/views/json_ui/garage/tables/bulk_edit.json.jbuilder +14 -14
- data/app/views/json_ui/garage/test_page/_header.json.jbuilder +1 -1
- data/app/views/json_ui/garage/test_page/calendar.json.jbuilder +6 -6
- data/app/views/json_ui/garage/test_page/carousel.json.jbuilder +4 -4
- data/app/views/json_ui/garage/test_page/charts.json.jbuilder +4 -4
- data/app/views/json_ui/garage/test_page/column.json.jbuilder +3 -3
- data/app/views/json_ui/garage/test_page/components.json.jbuilder +7 -7
- data/app/views/json_ui/garage/test_page/custom.json.jbuilder +3 -3
- data/app/views/json_ui/garage/test_page/dialog.json.jbuilder +0 -21
- data/app/views/json_ui/garage/test_page/fields_creditCard.json.jbuilder +6 -6
- data/app/views/json_ui/garage/test_page/fields_date_time.json.jbuilder +8 -8
- data/app/views/json_ui/garage/test_page/fields_dynamicSelect.json.jbuilder +8 -8
- data/app/views/json_ui/garage/test_page/fields_location.json.jbuilder +6 -6
- data/app/views/json_ui/garage/test_page/fields_otp.json.jbuilder +8 -8
- data/app/views/json_ui/garage/test_page/fields_phone.json.jbuilder +9 -9
- data/app/views/json_ui/garage/test_page/fields_radio.json.jbuilder +4 -4
- data/app/views/json_ui/garage/test_page/fields_rating.json.jbuilder +10 -10
- data/app/views/json_ui/garage/test_page/fields_richText.json.jbuilder +10 -10
- data/app/views/json_ui/garage/test_page/fields_select.json.jbuilder +8 -8
- data/app/views/json_ui/garage/test_page/fields_sign.json.jbuilder +8 -56
- data/app/views/json_ui/garage/test_page/fields_stripeExternalAccount.json.jbuilder +6 -6
- data/app/views/json_ui/garage/test_page/fields_stripeToken.json.jbuilder +6 -6
- data/app/views/json_ui/garage/test_page/fields_text.json.jbuilder +5 -5
- data/app/views/json_ui/garage/test_page/fields_timer.json.jbuilder +6 -6
- data/app/views/json_ui/garage/test_page/flow.json.jbuilder +6 -6
- data/app/views/json_ui/garage/test_page/form.json.jbuilder +9 -9
- data/app/views/json_ui/garage/test_page/grid.json.jbuilder +4 -4
- data/app/views/json_ui/garage/test_page/horizontal.json.jbuilder +5 -5
- data/app/views/json_ui/garage/test_page/image.json.jbuilder +9 -9
- data/app/views/json_ui/garage/test_page/lifecycle.json.jbuilder +6 -6
- data/app/views/json_ui/garage/test_page/list.json.jbuilder +6 -6
- data/app/views/json_ui/garage/test_page/multimedia_docx.json.jbuilder +5 -5
- data/app/views/json_ui/garage/test_page/multimedia_video.json.jbuilder +6 -6
- data/app/views/json_ui/garage/test_page/pagination.json.jbuilder +6 -6
- data/app/views/json_ui/garage/test_page/panels_bulkEdit2.json.jbuilder +244 -0
- data/app/views/json_ui/garage/test_page/panels_bulkEdit3.json.jbuilder +3 -3
- data/app/views/json_ui/garage/test_page/progressCircle.json.jbuilder +8 -8
- data/app/views/json_ui/garage/test_page/responsive.json.jbuilder +4 -4
- data/app/views/json_ui/garage/test_page/scroll.json.jbuilder +5 -5
- data/app/views/json_ui/garage/test_page/split.json.jbuilder +1 -1
- data/app/views/json_ui/garage/test_page/table.json.jbuilder +5 -5
- data/app/views/json_ui/garage/test_page/timeline.json.jbuilder +5 -5
- data/app/views/json_ui/garage/test_page/ul.json.jbuilder +4 -4
- data/app/views/json_ui/garage/test_page/vertical.json.jbuilder +5 -5
- data/app/views/json_ui/garage/test_page/web.json.jbuilder +5 -5
- data/app/views/json_ui/garage/views/_expand_shrink_ex.json.jbuilder +4 -4
- data/app/views/json_ui/garage/views/controls.json.jbuilder +4 -4
- data/app/views/json_ui/garage/views/{components_set.json.jbuilder → logics_set.json.jbuilder} +2 -2
- data/lib/glib/engine.rb +0 -32
- data/lib/glib/json_crawler/action_crawlers/forms_submit.rb +1 -1
- data/lib/glib/json_crawler/router.rb +0 -24
- data/lib/glib/json_ui/config.rb +1 -1
- data/lib/glib/test/changed_files_rubocop.rb +55 -0
- data/lib/glib/test_helpers.rb +7 -9
- data/lib/glib-web.rb +2 -4
- metadata +6 -37
- data/app/controllers/concerns/glib/auth/token_authenticatable.rb +0 -37
- data/app/controllers/glib/api_controller.rb +0 -52
- data/app/jobs/glib/purge_unattached_job.rb +0 -32
- data/app/models/concerns/glib/snapshot_v2.rb +0 -514
- data/app/models/glib/model.rb +0 -40
- data/app/models/glib/plain_model.rb +0 -23
- data/app/models/snapshot_blob_reference.rb +0 -20
- data/app/views/json_ui/garage/test_page/fields_change_trigger.json.jbuilder +0 -128
- data/lib/generators/glib/snapshot_v2_generator.rb +0 -54
- data/lib/generators/templates/snapshot_v2/add_snapshot_v2_columns.rb +0 -18
- data/lib/generators/templates/snapshot_v2/create_snapshot_blob_references.rb +0 -10
- data/lib/glib/purge_unattached/config.rb +0 -38
- data/lib/glib/test/full_suite_rubocop.rb +0 -87
- data/lib/glib/test/rubocop_guards.rb +0 -42
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 38b655bd80465e224c8ed56c8e63694af4786e89a4028da3915737bf8ac96120
|
|
4
|
+
data.tar.gz: 6baa89e800c1223673fe1d9bbad61694e6a59c46123f42faff344d819e143dbf
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 30a1adca1ba187b2f23ff52f54b41259742e15582abf95404b07b658e6eb4a408e2a236b8ffe7b4b45459e7ad3abfb9f8017e8701887fe5b4f5028d045834d23
|
|
7
|
+
data.tar.gz: c4645773a9b5aea3d3b3ba0aea2e24c609e09b45bc7b4904b76bad3af3dd486ed9b4b1b38dba4b956da4620656127462970a1b73c960c231a21da42685fd6f71
|
|
@@ -22,11 +22,7 @@ module Glib::Auth
|
|
|
22
22
|
# - Need to find a solution where we can reuse a single public policy
|
|
23
23
|
# after_action :verify_authorized
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
# does, but bare ActionController::API does not (gems like jbuilder may include
|
|
27
|
-
# ActionController::Helpers into it in a booted app, and a plain non-controller
|
|
28
|
-
# class never has it). Same guard Pundit's own included block uses.
|
|
29
|
-
helper_method :policy, :can?, :cannot? if respond_to?(:helper_method)
|
|
25
|
+
helper_method :policy, :can?, :cannot?
|
|
30
26
|
end
|
|
31
27
|
|
|
32
28
|
def assert_current_user_present
|
|
@@ -96,18 +96,6 @@ module Glib::Json::Libs
|
|
|
96
96
|
|
|
97
97
|
json_ui_redirect_to url, status: status
|
|
98
98
|
end
|
|
99
|
-
# Any other request format (e.g. a browser tab opening a protected file link
|
|
100
|
-
# `/temp_blobs/:id/report.pdf`, where the filename sets the format) used to raise
|
|
101
|
-
# ActionController::UnknownFormat -> a bare 406 with an empty body. Mirror the html
|
|
102
|
-
# branch instead: whatever opened the URL (browser tab, iframe, img) is redirected
|
|
103
|
-
# to the target, which the browser follows natively.
|
|
104
|
-
#
|
|
105
|
-
# MUST stay the LAST block. `negotiate_mime` answers `Accept: */*` requests with
|
|
106
|
-
# the FIRST declared format, so an `any` block placed before html would capture
|
|
107
|
-
# ordinary browser page loads and leave request.format as `*/*` for the action.
|
|
108
|
-
format.any do
|
|
109
|
-
redirect_to url
|
|
110
|
-
end
|
|
111
99
|
end
|
|
112
100
|
end
|
|
113
101
|
|
|
@@ -154,17 +142,6 @@ module Glib::Json::Libs
|
|
|
154
142
|
redirect_to sign_in_url, **redirect_options
|
|
155
143
|
end
|
|
156
144
|
end
|
|
157
|
-
# Other non-HTML/JSON formats (a protected file link whose filename sets the
|
|
158
|
-
# request format, an XML export, ...) used to raise UnknownFormat -> a bare 406.
|
|
159
|
-
# Mirrors the csv branch: a clean gate status in test, a redirect in production.
|
|
160
|
-
# MUST stay the LAST block -- see glib_redirect_to.
|
|
161
|
-
format.any do
|
|
162
|
-
if Rails.env.test?
|
|
163
|
-
head :unauthorized
|
|
164
|
-
else
|
|
165
|
-
redirect_to sign_in_url, **redirect_options
|
|
166
|
-
end
|
|
167
|
-
end
|
|
168
145
|
end
|
|
169
146
|
end
|
|
170
147
|
|
|
@@ -208,16 +185,6 @@ module Glib::Json::Libs
|
|
|
208
185
|
redirect_to user_default_url
|
|
209
186
|
end
|
|
210
187
|
end
|
|
211
|
-
# Other non-HTML/JSON formats -- mirrors the csv branch (clean gate status in
|
|
212
|
-
# test, redirect in production); previously raised UnknownFormat -> a bare 406.
|
|
213
|
-
# MUST stay the LAST block -- see glib_redirect_to.
|
|
214
|
-
format.any do
|
|
215
|
-
if Rails.env.test?
|
|
216
|
-
head :forbidden
|
|
217
|
-
else
|
|
218
|
-
redirect_to user_default_url
|
|
219
|
-
end
|
|
220
|
-
end
|
|
221
188
|
end
|
|
222
189
|
end
|
|
223
190
|
|
|
@@ -25,7 +25,7 @@ class Glib::JsonUi::ActionBuilder
|
|
|
25
25
|
views :childViews
|
|
26
26
|
end
|
|
27
27
|
|
|
28
|
-
# Consider deprecating this. See `
|
|
28
|
+
# Consider deprecating this. See `logics_set` example in app/views/json_ui/garage/forms/selects.json.jbuilder
|
|
29
29
|
class Replace < Action
|
|
30
30
|
string :targetId
|
|
31
31
|
action :onReplace
|
|
@@ -37,20 +37,5 @@ class Glib::JsonUi::ActionBuilder
|
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
40
|
-
# Deprecated: use `logics_set` instead. `logics_set` is a superset of this
|
|
41
|
-
# action (same `targetId`/`data`/`onSet`/`skipOnChange`, plus
|
|
42
|
-
# `conditionalData`, `targetIds`, `variables` and `cacheData`).
|
|
43
|
-
class Set < Action
|
|
44
|
-
string :targetId
|
|
45
|
-
hash :data
|
|
46
|
-
action :onSet
|
|
47
|
-
bool :skipOnChange
|
|
48
|
-
|
|
49
|
-
def dataBuilder(block)
|
|
50
|
-
json.data do
|
|
51
|
-
block.call(page.sview_builder)
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
end
|
|
55
40
|
end
|
|
56
41
|
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
class Glib::JsonUi::ActionBuilder
|
|
2
2
|
module Logics
|
|
3
|
-
# The canonical setter action.
|
|
4
|
-
# `components_set`: it supports plain static `data` as well as
|
|
3
|
+
# The canonical setter action. It supports plain static `data` as well as
|
|
5
4
|
# `conditionalData` (JsonLogic), `targetIds`, `variables` and `cacheData`.
|
|
6
5
|
class Set < Action
|
|
7
6
|
string :targetId
|
|
@@ -7,31 +7,15 @@ class Glib::JsonUi::ActionBuilder
|
|
|
7
7
|
int :timeout
|
|
8
8
|
action :onClose
|
|
9
9
|
|
|
10
|
-
string :verticalPosition # Deprecated
|
|
11
|
-
string :horizontalPosition # Deprecated
|
|
12
|
-
|
|
13
10
|
string :location
|
|
14
11
|
singleton_array :styleClass, :styleClasses
|
|
15
12
|
end
|
|
16
13
|
|
|
17
|
-
# class Confirm < Action
|
|
18
|
-
# string :message
|
|
19
|
-
# action :onConfirm
|
|
20
|
-
# action :onCancel
|
|
21
|
-
|
|
22
|
-
# string :verticalPosition
|
|
23
|
-
# string :horizontalPosition
|
|
24
|
-
# singleton_array :styleClass, :styleClasses
|
|
25
|
-
# end
|
|
26
|
-
|
|
27
14
|
class Select < Action
|
|
28
15
|
string :message
|
|
29
16
|
int :timeout
|
|
30
17
|
action :onClose
|
|
31
18
|
|
|
32
|
-
string :verticalPosition # Deprecated
|
|
33
|
-
string :horizontalPosition # Deprecated
|
|
34
|
-
|
|
35
19
|
string :location
|
|
36
20
|
singleton_array :styleClass, :styleClasses
|
|
37
21
|
|
|
@@ -10,18 +10,6 @@ module Glib
|
|
|
10
10
|
end
|
|
11
11
|
end
|
|
12
12
|
|
|
13
|
-
# Deprecated
|
|
14
|
-
def json_ui_response_with_view(json)
|
|
15
|
-
json.analytics do
|
|
16
|
-
json.disabled true
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
json.onResponse do
|
|
20
|
-
response = Glib::JsonUi::PageHelper::Page.new(json, self)
|
|
21
|
-
yield response.action_builder
|
|
22
|
-
end
|
|
23
|
-
end
|
|
24
|
-
|
|
25
13
|
class Response
|
|
26
14
|
attr_reader :action_builder
|
|
27
15
|
|
|
@@ -211,51 +211,6 @@ class Glib::JsonUi::ViewBuilder
|
|
|
211
211
|
end
|
|
212
212
|
end
|
|
213
213
|
|
|
214
|
-
# Timing options for the `onChange` / `onChangeAndLoad` actions of fields
|
|
215
|
-
# whose value changes while the user is still typing.
|
|
216
|
-
#
|
|
217
|
-
# Honoured by the single-line text family (text, number, email, url,
|
|
218
|
-
# password -- all one Vue component) and by textarea. Other fields ignore
|
|
219
|
-
# them: the discrete ones (check, radio, select, chip group, date pickers)
|
|
220
|
-
# commit a value the moment it is picked, and richText/phone/file keep
|
|
221
|
-
# their own reporting. The options are declared on `Text`, so its other
|
|
222
|
-
# subclasses accept them without effect -- same as `leftIcon` and
|
|
223
|
-
# `onTypeStart` there.
|
|
224
|
-
#
|
|
225
|
-
# In both modes the change is also reported when focus leaves the field.
|
|
226
|
-
# Under `input` that only flushes a change already pending in the debounce
|
|
227
|
-
# window -- it cannot produce a second run, because a value that was
|
|
228
|
-
# already reported is not reported again.
|
|
229
|
-
module ChangeTrigger
|
|
230
|
-
def self.included(base)
|
|
231
|
-
# When the `onChange` / `onChangeAndLoad` actions fire.
|
|
232
|
-
#
|
|
233
|
-
# - `input` (default): after the user pauses typing for `changeDelay`.
|
|
234
|
-
# - `blur`: only once focus leaves the field. Use for actions too
|
|
235
|
-
# expensive to run mid-word -- a server round trip, a recalculation
|
|
236
|
-
# that rewrites other fields under the user's cursor.
|
|
237
|
-
#
|
|
238
|
-
# @example Round-trip only once the user is done with the field
|
|
239
|
-
# form.fields_text \
|
|
240
|
-
# name: 'user[promo_code]',
|
|
241
|
-
# label: 'Promo code',
|
|
242
|
-
# changeOn: 'blur',
|
|
243
|
-
# onChange: ->(action) { action.http_get url: verify_promo_path }
|
|
244
|
-
base.enum :changeOn, options: %w[input blur]
|
|
245
|
-
|
|
246
|
-
# Milliseconds of no typing before `changeOn: 'input'` fires.
|
|
247
|
-
# Defaults to 300. Ignored under `changeOn: 'blur'`.
|
|
248
|
-
#
|
|
249
|
-
# @example Slow down a search-as-you-type round trip
|
|
250
|
-
# form.fields_text \
|
|
251
|
-
# name: 'q',
|
|
252
|
-
# label: 'Search',
|
|
253
|
-
# changeDelay: 800,
|
|
254
|
-
# onChange: ->(action) { action.http_get url: search_path }
|
|
255
|
-
base.int :changeDelay
|
|
256
|
-
end
|
|
257
|
-
end
|
|
258
|
-
|
|
259
214
|
# Basic text input field for single-line text entry.
|
|
260
215
|
#
|
|
261
216
|
# The most common field type, supporting various customizations like
|
|
@@ -273,8 +228,6 @@ class Glib::JsonUi::ViewBuilder
|
|
|
273
228
|
#
|
|
274
229
|
# @see app/views/json_ui/garage/forms/basic.json.jbuilder Garage example
|
|
275
230
|
class Text < AbstractField
|
|
276
|
-
include ChangeTrigger
|
|
277
|
-
|
|
278
231
|
# Maximum number of characters allowed.
|
|
279
232
|
int :maxLength
|
|
280
233
|
|
|
@@ -706,10 +659,7 @@ class Glib::JsonUi::ViewBuilder
|
|
|
706
659
|
class ChipGroup < AbstractField
|
|
707
660
|
color :color
|
|
708
661
|
array :options
|
|
709
|
-
|
|
710
|
-
# multiple-selection ChipGroup submits under a single key and only the
|
|
711
|
-
# last selected value survives server-side parsing.
|
|
712
|
-
bool :multiple, cache: true
|
|
662
|
+
bool :multiple
|
|
713
663
|
end
|
|
714
664
|
|
|
715
665
|
class TimeZone < AbstractField
|
|
@@ -847,11 +797,7 @@ class Glib::JsonUi::ViewBuilder
|
|
|
847
797
|
include Glib::JsonUi::FileUploadErrorHandler
|
|
848
798
|
|
|
849
799
|
action :onFinishUpload
|
|
850
|
-
|
|
851
|
-
# the submit key — without it the `[]` array suffix is dropped and a
|
|
852
|
-
# multi-file submit collapses to the last file server-side (silently
|
|
853
|
-
# saves one Document per drop instead of one per file).
|
|
854
|
-
bool :multiple, cache: true
|
|
800
|
+
bool :multiple
|
|
855
801
|
hash :placeholderView, required: [:type, :width, :height], optional: [:url]
|
|
856
802
|
hash :inputView, optional: [:files, :variant]
|
|
857
803
|
hash :clipboardView, optional: [:icon]
|
|
@@ -909,88 +855,13 @@ class Glib::JsonUi::ViewBuilder
|
|
|
909
855
|
end
|
|
910
856
|
end
|
|
911
857
|
|
|
912
|
-
# Signature field that lets the user draw a signature on a canvas and
|
|
913
|
-
# upload it as an image via ActiveStorage direct upload.
|
|
914
|
-
#
|
|
915
|
-
# The form shows a placeholder sized by `width`/`height`; tapping it opens
|
|
916
|
-
# a dialog with the drawing canvas, and Confirm uploads the drawing as a
|
|
917
|
-
# PNG to `directUploadUrl` and submits the resulting signed id under
|
|
918
|
-
# `name`. The placeholder then shows the signature, and reopening the
|
|
919
|
-
# dialog lets the user edit it. Because the canvas is not in the form,
|
|
920
|
-
# the placeholder can be given the same height as a neighbouring input
|
|
921
|
-
# (e.g. a typed-name alternative) without losing drawing space.
|
|
922
|
-
#
|
|
923
|
-
# `label` titles the dialog; `placeholder` replaces the "Tap to sign"
|
|
924
|
-
# prompt.
|
|
925
|
-
#
|
|
926
|
-
# With `typedName` the dialog gains Draw/Type tabs: the user can type
|
|
927
|
-
# their name instead of drawing, and the placeholder then shows the name
|
|
928
|
-
# in a handwriting style (the `glib-sign-typed` hook carries the font).
|
|
929
|
-
# The typed name is submitted under `typedName[:name]`; exactly one of the
|
|
930
|
-
# signed id and the typed name is ever non-blank. `typedName[:value]`
|
|
931
|
-
# pre-populates an existing name.
|
|
932
|
-
#
|
|
933
|
-
# @example Basic signature field
|
|
934
|
-
# form.fields_sign \
|
|
935
|
-
# name: 'user[signature]',
|
|
936
|
-
# label: 'Your signature',
|
|
937
|
-
# directUploadUrl: glib_direct_uploads_url,
|
|
938
|
-
# width: 320,
|
|
939
|
-
# height: 160,
|
|
940
|
-
# validation: { required: { message: 'add your signature!' } }
|
|
941
|
-
#
|
|
942
|
-
# @example Drawn or typed
|
|
943
|
-
# form.fields_sign \
|
|
944
|
-
# name: 'user[signature]',
|
|
945
|
-
# label: 'Your signature',
|
|
946
|
-
# typedName: { name: 'user[signature_name]', label: 'Type your full name', placeholder: 'Full name' },
|
|
947
|
-
# directUploadUrl: glib_direct_uploads_url,
|
|
948
|
-
# width: 320,
|
|
949
|
-
# height: 160
|
|
950
|
-
#
|
|
951
|
-
# @example Compact signature without validation
|
|
952
|
-
# form.fields_sign \
|
|
953
|
-
# id: 'signature_compact',
|
|
954
|
-
# name: 'user[signature_compact]',
|
|
955
|
-
# directUploadUrl: glib_direct_uploads_url,
|
|
956
|
-
# width: 220,
|
|
957
|
-
# height: 100
|
|
958
|
-
#
|
|
959
|
-
# @note A saved signature is a signed id that cannot be redrawn from the
|
|
960
|
-
# canvas: when a record is re-edited the field pre-populates `value`
|
|
961
|
-
# with the existing attachment's signed id (the component renders a
|
|
962
|
-
# read-only preview instead of ink). An untouched field therefore
|
|
963
|
-
# re-submits that same signed id, so consumers should treat a
|
|
964
|
-
# same-signed-id re-attach as "no change". Resize it via
|
|
965
|
-
# `components_set`/`logics_set` with `width`/`height`.
|
|
966
|
-
#
|
|
967
|
-
# @see app/views/json_ui/garage/test_page/fields_sign.json.jbuilder Garage examples
|
|
968
858
|
class Sign < AbstractField
|
|
969
859
|
string :directUploadUrl
|
|
970
860
|
required :directUploadUrl
|
|
971
861
|
|
|
972
|
-
# URL of an already-attached signature image to display as a read-only
|
|
973
|
-
# preview (typically `file_url(attachment)` when re-editing a record
|
|
974
|
-
# that has a drawn signature). Pair with `prop:` so the field also
|
|
975
|
-
# submits the existing signed id when left untouched.
|
|
976
|
-
string :fileUrl
|
|
977
|
-
|
|
978
|
-
# Enables the Type tab. `value` pre-populates the previously typed
|
|
979
|
-
# name; `label`/`placeholder` decorate the text input in the dialog.
|
|
980
|
-
# `name` is still accepted but unused: the typed name is submitted
|
|
981
|
-
# through the field's own param (single-param contract), and the
|
|
982
|
-
# server routes it to the name attribute.
|
|
983
|
-
hash :typedName, optional: [:name, :value, :label, :placeholder]
|
|
984
|
-
|
|
985
862
|
# Override
|
|
986
|
-
#
|
|
987
|
-
|
|
988
|
-
# field with the existing blob's signed id instead of serializing the
|
|
989
|
-
# whole attachment proxy.
|
|
990
|
-
def determine_value(context, prop)
|
|
991
|
-
if (value = context.field_value(prop)).attached?
|
|
992
|
-
value.signed_id || ''
|
|
993
|
-
end
|
|
863
|
+
# Signature field doesn't have default value
|
|
864
|
+
def value(value)
|
|
994
865
|
end
|
|
995
866
|
end
|
|
996
867
|
|
|
@@ -493,23 +493,129 @@ class Glib::JsonUi::ViewBuilder
|
|
|
493
493
|
end
|
|
494
494
|
end
|
|
495
495
|
|
|
496
|
-
|
|
497
|
-
# viewCells/viewHeaders, plus the full parse/gate/dedup config so any
|
|
498
|
-
# consumer can compose specialized import behavior (it replaced the
|
|
499
|
-
# retired bulkEdit2 and bulkEditSg -- see the component's header comment
|
|
500
|
-
# for the full mapping).
|
|
501
|
-
class BulkEdit3 < View
|
|
496
|
+
class BulkEdit2 < View
|
|
502
497
|
hash :import, required: [:submitUrl, :paramName]
|
|
503
498
|
|
|
504
499
|
# Override
|
|
505
500
|
def created
|
|
506
|
-
#
|
|
501
|
+
# bulkEdit2 is a form PEER, not a form child: it answers the same
|
|
507
502
|
# forms_submit action a form does (forms/directSubmit) and submits its
|
|
508
503
|
# rows itself to `import.submitUrl`. Inside a form, its repeated
|
|
509
504
|
# per-row input names would collide with the form's FormData scans
|
|
510
505
|
# (duplicate-name warnings, dirty-baseline pollution) while adding
|
|
511
506
|
# nothing to the form's submission -- so, like a nested form, reject
|
|
512
507
|
# the arrangement at render time.
|
|
508
|
+
if page.current_form
|
|
509
|
+
raise 'panels_bulkEdit2 is not allowed inside a form; place it as a sibling and target it with forms_submit targetId'
|
|
510
|
+
end
|
|
511
|
+
end
|
|
512
|
+
|
|
513
|
+
# Maximum number of data rows an uploaded file may contain; files with
|
|
514
|
+
# more rows are rejected with an error dialog. No limit when unset.
|
|
515
|
+
int :maxRows
|
|
516
|
+
|
|
517
|
+
# string :statusViewIdPrefix
|
|
518
|
+
array :viewHeaders
|
|
519
|
+
|
|
520
|
+
# string :paramNameForFormData
|
|
521
|
+
string :paramNameForRowId
|
|
522
|
+
action :onCellChange
|
|
523
|
+
action :onRowsLoad
|
|
524
|
+
action :onRowsSelect
|
|
525
|
+
action :onRowsSucceed
|
|
526
|
+
action :onSubmitStart
|
|
527
|
+
action :onSubmitEnd
|
|
528
|
+
|
|
529
|
+
# Experimental
|
|
530
|
+
# panels_builder :accessory, :header, :footer
|
|
531
|
+
|
|
532
|
+
def viewCells(values)
|
|
533
|
+
json.set! 'viewCells' do
|
|
534
|
+
values.each do |value|
|
|
535
|
+
value.call(page.view_builder)
|
|
536
|
+
end
|
|
537
|
+
end
|
|
538
|
+
end
|
|
539
|
+
|
|
540
|
+
def dataRows(value)
|
|
541
|
+
json.dataRows value
|
|
542
|
+
end
|
|
543
|
+
|
|
544
|
+
def viewRows(value)
|
|
545
|
+
json.viewRows value
|
|
546
|
+
end
|
|
547
|
+
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
# The Surfguard members-import table: a fork of bulkEdit2's builder for
|
|
551
|
+
# glib-web-npm's bulkEditSg component (same skeleton — form-peer
|
|
552
|
+
# submission, per-row POSTs, viewCells/viewHeaders — plus the Surfguard
|
|
553
|
+
# parse inputs). Deliberately SG-specific; consolidate with BulkEdit2 when
|
|
554
|
+
# a second consumer proves which props generalize.
|
|
555
|
+
class BulkEditSg < View
|
|
556
|
+
hash :import, required: [:submitUrl, :paramName]
|
|
557
|
+
|
|
558
|
+
# Override
|
|
559
|
+
def created
|
|
560
|
+
# Same form-peer rule as bulkEdit2 (see its comment).
|
|
561
|
+
if page.current_form
|
|
562
|
+
raise 'panels_bulkEditSg is not allowed inside a form; place it as a sibling and target it with forms_submit targetId'
|
|
563
|
+
end
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
# Maximum number of data rows an uploaded file may contain; files with
|
|
567
|
+
# more rows are rejected with an error dialog. No limit when unset.
|
|
568
|
+
int :maxRows
|
|
569
|
+
|
|
570
|
+
array :viewHeaders
|
|
571
|
+
|
|
572
|
+
# string :paramNameForFormData
|
|
573
|
+
string :paramNameForRowId
|
|
574
|
+
action :onCellChange
|
|
575
|
+
action :onRowsLoad
|
|
576
|
+
action :onRowsSelect
|
|
577
|
+
action :onRowsSucceed
|
|
578
|
+
# Fires when non-importable rows drain out of the table on save (they
|
|
579
|
+
# never POST), so the page can keep its Loaded/Uploaded/Skipped
|
|
580
|
+
# arithmetic honest.
|
|
581
|
+
action :onRowsSkip
|
|
582
|
+
action :onSubmitStart
|
|
583
|
+
action :onSubmitEnd
|
|
584
|
+
|
|
585
|
+
# Surfguard file shape: CSV header => form field. The parser follows
|
|
586
|
+
# this map, so a header-spelling fix is a one-line server change.
|
|
587
|
+
hash :headerMap
|
|
588
|
+
array :requiredHeaders
|
|
589
|
+
string :statusFilter
|
|
590
|
+
|
|
591
|
+
def viewCells(values)
|
|
592
|
+
json.set! 'viewCells' do
|
|
593
|
+
values.each do |value|
|
|
594
|
+
value.call(page.view_builder)
|
|
595
|
+
end
|
|
596
|
+
end
|
|
597
|
+
end
|
|
598
|
+
|
|
599
|
+
def dataRows(value)
|
|
600
|
+
json.dataRows value
|
|
601
|
+
end
|
|
602
|
+
|
|
603
|
+
def viewRows(value)
|
|
604
|
+
json.viewRows value
|
|
605
|
+
end
|
|
606
|
+
|
|
607
|
+
end
|
|
608
|
+
|
|
609
|
+
# The generic bulk-edit table: bulkEdit2's skeleton plus everything
|
|
610
|
+
# bulkEditSg hard-coded for the Surfguard imports, expressed as config so
|
|
611
|
+
# any consumer can compose the same behavior (bulkEditSg's replacement --
|
|
612
|
+
# see the component's header comment for the full mapping).
|
|
613
|
+
class BulkEdit3 < View
|
|
614
|
+
hash :import, required: [:submitUrl, :paramName]
|
|
615
|
+
|
|
616
|
+
# Override
|
|
617
|
+
def created
|
|
618
|
+
# Same form-peer rule as bulkEdit2 (see its comment).
|
|
513
619
|
if page.current_form
|
|
514
620
|
raise 'panels_bulkEdit3 is not allowed inside a form; place it as a sibling and target it with forms_submit targetId'
|
|
515
621
|
end
|
|
@@ -535,7 +641,7 @@ class Glib::JsonUi::ViewBuilder
|
|
|
535
641
|
action :onSubmitEnd
|
|
536
642
|
|
|
537
643
|
# The file shape. Without it the table takes plain CSVs (header row
|
|
538
|
-
# first, header names = field ids):
|
|
644
|
+
# first, header names = field ids -- the bulkEdit2 shape):
|
|
539
645
|
# detectHeader: { allOf: [...], anyOf: [...], scanRows: N } -- find
|
|
540
646
|
# the header row BY CONTENT (report preambles survive);
|
|
541
647
|
# headerMap: { csvHeader => field } -- header-keyed, order-independent
|
|
@@ -610,6 +716,36 @@ class Glib::JsonUi::ViewBuilder
|
|
|
610
716
|
|
|
611
717
|
end
|
|
612
718
|
|
|
719
|
+
# deprecated
|
|
720
|
+
class BulkEdit < View
|
|
721
|
+
hash :nextPage
|
|
722
|
+
hash :export, required: [:label, :fileName]
|
|
723
|
+
hash :import, required: [:submitUrl, :paramName]
|
|
724
|
+
action :onScrollToTop
|
|
725
|
+
action :onScrollToBottom
|
|
726
|
+
string :statusViewIdPrefix
|
|
727
|
+
action :onLoadRows
|
|
728
|
+
|
|
729
|
+
# Experimental
|
|
730
|
+
panels_builder :accessory, :header, :footer
|
|
731
|
+
|
|
732
|
+
def firstSection(block)
|
|
733
|
+
json.sections [1] do
|
|
734
|
+
block.call page.table_section_builder
|
|
735
|
+
end
|
|
736
|
+
end
|
|
737
|
+
|
|
738
|
+
def sections(blocks)
|
|
739
|
+
json.sections do
|
|
740
|
+
blocks.each do |block|
|
|
741
|
+
json.child! do
|
|
742
|
+
block.call page.table_section_builder
|
|
743
|
+
end
|
|
744
|
+
end
|
|
745
|
+
end
|
|
746
|
+
end
|
|
747
|
+
end
|
|
748
|
+
|
|
613
749
|
# Scrollable container panel for content that exceeds viewport height.
|
|
614
750
|
#
|
|
615
751
|
# Scroll panels automatically add scrollbars when content overflows.
|
|
@@ -8,7 +8,7 @@ section.rows builder: ->(template) do
|
|
|
8
8
|
action.windows_open url: json_ui_garage_url(path: 'views/components_replace')
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
template.thumbnail title: '
|
|
12
|
-
action.windows_open url: json_ui_garage_url(path: 'views/
|
|
11
|
+
template.thumbnail title: 'logics/set', onClick: ->(action) do
|
|
12
|
+
action.windows_open url: json_ui_garage_url(path: 'views/logics_set')
|
|
13
13
|
end
|
|
14
14
|
end
|
|
@@ -5,7 +5,7 @@ json_ui_response json do |action|
|
|
|
5
5
|
status_view_id = "row_status_#{params[:_index]}"
|
|
6
6
|
# TODO: This doesn't work. It should update the status icon to indicate that the
|
|
7
7
|
# import is successful.
|
|
8
|
-
multiple.
|
|
8
|
+
multiple.logics_set \
|
|
9
9
|
targetId: status_view_id,
|
|
10
10
|
data: {
|
|
11
11
|
color: 'success',
|
|
@@ -109,13 +109,13 @@ page.scroll childViews: ->(scroll) do
|
|
|
109
109
|
childViews: ->(group) do
|
|
110
110
|
group.panels_flow id: 'flow', xs: { gap: { all: 8 } }, backgroundColor: 'grey', width: 'matchParent', childViews: ->(flow) do
|
|
111
111
|
flow.fields_check checkValue: '1', label: 'Choice 1', onChange: ->(action) do
|
|
112
|
-
action.
|
|
112
|
+
action.logics_set targetId: 'flow', data: { backgroundColor: '#ff0000' }
|
|
113
113
|
end
|
|
114
114
|
flow.fields_check checkValue: '2', label: 'Choice 2', onChange: ->(action) do
|
|
115
|
-
action.
|
|
115
|
+
action.logics_set targetId: 'flow', data: { backgroundColor: '#00ff00' }
|
|
116
116
|
end
|
|
117
117
|
flow.fields_check checkValue: '3', label: 'Choice 3', onChange: ->(action) do
|
|
118
|
-
action.
|
|
118
|
+
action.logics_set targetId: 'flow', data: { backgroundColor: '#0000ff' }
|
|
119
119
|
end
|
|
120
120
|
end
|
|
121
121
|
end
|
|
@@ -38,9 +38,9 @@ page.form(
|
|
|
38
38
|
action.components_findClosest(
|
|
39
39
|
view: 'panels/responsive',
|
|
40
40
|
onFind: ->(find) do
|
|
41
|
-
# This is to demonstrate that `
|
|
41
|
+
# This is to demonstrate that `logics_set` can be a more flexible version
|
|
42
42
|
# of `components_replace`.
|
|
43
|
-
find.
|
|
43
|
+
find.logics_set(
|
|
44
44
|
dataBuilder: ->(set) do
|
|
45
45
|
# Don't update the childViews, just update the footer
|
|
46
46
|
set.panels_responsive(
|
|
@@ -159,7 +159,7 @@ page.form(
|
|
|
159
159
|
action.components_findClosest(
|
|
160
160
|
view: 'fields/select',
|
|
161
161
|
onFind: ->(subaction) do
|
|
162
|
-
subaction.
|
|
162
|
+
subaction.logics_set(
|
|
163
163
|
data: { value: 'pt' },
|
|
164
164
|
onSet: ->(subsubaction) do
|
|
165
165
|
subsubaction.fields_blur
|
|
@@ -194,7 +194,7 @@ page.form(
|
|
|
194
194
|
text: 'Reset',
|
|
195
195
|
styleClass: 'text-primary',
|
|
196
196
|
onClick: ->(action) do
|
|
197
|
-
action.
|
|
197
|
+
action.logics_set targetId: 'lang', data: { value: [] }
|
|
198
198
|
end
|
|
199
199
|
)
|
|
200
200
|
hori.spacer width: 16
|
|
@@ -276,7 +276,7 @@ page.form(
|
|
|
276
276
|
form.button(
|
|
277
277
|
text: 'Swap spec options',
|
|
278
278
|
onClick: ->(action) do
|
|
279
|
-
action.
|
|
279
|
+
action.logics_set targetId: 'spec_options_select', data: { 'spec.options' => spec_options_alt }
|
|
280
280
|
end
|
|
281
281
|
)
|
|
282
282
|
form.button text: 'Submit', onClick: ->(action) { action.forms_submit }
|
|
@@ -17,10 +17,10 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
|
17
17
|
panel.button text: '3'
|
|
18
18
|
end
|
|
19
19
|
scroll.button text: 'show', onClick: ->(action) do
|
|
20
|
-
action.
|
|
20
|
+
action.logics_set targetId: 'flow1', data: { displayed: true }
|
|
21
21
|
end
|
|
22
22
|
scroll.button text: 'hide', onClick: ->(action) do
|
|
23
|
-
action.
|
|
23
|
+
action.logics_set targetId: 'flow1', data: { displayed: false }
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
scroll.h1 text: 'Basic'
|
|
@@ -86,8 +86,8 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
|
86
86
|
backgroundColor: '#b3bac2',
|
|
87
87
|
onMouseEnter: ->(action) {
|
|
88
88
|
action.runMultiple childActions: ->(saction) do
|
|
89
|
-
saction.
|
|
90
|
-
saction.
|
|
89
|
+
saction.logics_set targetId: 'default1', data: { displayed: false }
|
|
90
|
+
saction.logics_set targetId: 'hovered1', data: { displayed: true }
|
|
91
91
|
end
|
|
92
92
|
}, childViews: ->(panel) do
|
|
93
93
|
panel.label text: 'Hover me'
|
|
@@ -99,8 +99,8 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
|
99
99
|
backgroundColor: '#b3bac2',
|
|
100
100
|
onMouseLeave: ->(action) {
|
|
101
101
|
action.runMultiple childActions: ->(saction) do
|
|
102
|
-
saction.
|
|
103
|
-
saction.
|
|
102
|
+
saction.logics_set targetId: 'default1', data: { displayed: true }
|
|
103
|
+
saction.logics_set targetId: 'hovered1', data: { displayed: false }
|
|
104
104
|
end
|
|
105
105
|
}, childViews: ->(panel) do
|
|
106
106
|
panel.label text: 'Hover active'
|