glib-web 6.10.4 → 6.12.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: af62a06f4071bb5b2779e61b2dfa771d9984d4f2f15bd6ed121fd71a676d7918
4
- data.tar.gz: f5100fe92e6d2959a4479b82887e0009c0aaea1a2ef419f1ae6205c8fbda427b
3
+ metadata.gz: 817984b6f3889911d4fbfa93df3612733ccdc32c424e1047d9fe3a578d771057
4
+ data.tar.gz: dc7aa2551592c95d7808061645eb2c67c7d1c910e9acd994a4357db824ea33a5
5
5
  SHA512:
6
- metadata.gz: b0e19fa8b04dc2a7d44826f0c28eefe5411610d26226180dbd20079af4287177d44967331c56dd1c0dc7ebf0b3f01df08f1a38939958fe58c37a08183e8d10c0
7
- data.tar.gz: 3c717ab4989d1e67f712d7d118d77cc6e99d136e0b1ed2e4e403a0974d0c364f705d064bad706b5f1bbfeca295333c523708e76f259a78cba969e958f6a494de
6
+ metadata.gz: 1f271cf7c9b788dbd9c3cd6e7bafe9cbb020156194cd2f52a6db592616691aa80a297b8f214eb2622b7129abc408a876d8335153aef8cc4031a2e168c58257d2
7
+ data.tar.gz: 52f8ae7045f853ffe7315eed140613d27080ee68868ce7fe603d43266d3968f600779283d6449fbf246066481eac6078925364a48f06c2438b288de5be44b8ad
@@ -493,129 +493,23 @@ class Glib::JsonUi::ViewBuilder
493
493
  end
494
494
  end
495
495
 
496
- class BulkEdit2 < View
496
+ # The generic bulk-edit table: form-peer submission, per-row POSTs,
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
497
502
  hash :import, required: [:submitUrl, :paramName]
498
503
 
499
504
  # Override
500
505
  def created
501
- # bulkEdit2 is a form PEER, not a form child: it answers the same
506
+ # bulkEdit3 is a form PEER, not a form child: it answers the same
502
507
  # forms_submit action a form does (forms/directSubmit) and submits its
503
508
  # rows itself to `import.submitUrl`. Inside a form, its repeated
504
509
  # per-row input names would collide with the form's FormData scans
505
510
  # (duplicate-name warnings, dirty-baseline pollution) while adding
506
511
  # nothing to the form's submission -- so, like a nested form, reject
507
512
  # 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).
619
513
  if page.current_form
620
514
  raise 'panels_bulkEdit3 is not allowed inside a form; place it as a sibling and target it with forms_submit targetId'
621
515
  end
@@ -641,7 +535,7 @@ class Glib::JsonUi::ViewBuilder
641
535
  action :onSubmitEnd
642
536
 
643
537
  # The file shape. Without it the table takes plain CSVs (header row
644
- # first, header names = field ids -- the bulkEdit2 shape):
538
+ # first, header names = field ids):
645
539
  # detectHeader: { allOf: [...], anyOf: [...], scanRows: N } -- find
646
540
  # the header row BY CONTENT (report preambles survive);
647
541
  # headerMap: { csvHeader => field } -- header-keyed, order-independent
@@ -716,36 +610,6 @@ class Glib::JsonUi::ViewBuilder
716
610
 
717
611
  end
718
612
 
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
-
749
613
  # Scrollable container panel for content that exceeds viewport height.
750
614
  #
751
615
  # Scroll panels automatically add scrollbars when content overflows.
@@ -37,17 +37,17 @@ page.scroll childViews: ->(scroll) do
37
37
  displayed: false
38
38
  end
39
39
 
40
- wres.panels_bulkEdit2 \
40
+ wres.panels_bulkEdit3 \
41
41
  id: 'import_table',
42
42
  width: 'matchParent',
43
43
  paramNameForRowId: 'row_id',
44
44
  import: { submitUrl: json_ui_garage_url(path: 'forms/bulk_edit_post2'), paramName: 'user' },
45
45
  viewHeaders: [
46
- { text: 'Month', id: 'month', importable: true, tooltip: { text: 'Month', placement: 'top' } },
47
- { text: 'Electricity usage', id: 'electricity_usage', importable: true },
48
- { text: 'Gas usage', id: 'gas_usage', importable: true },
49
- { text: 'Sources', id: 'sources', importable: true },
50
- { text: 'Compliant', id: 'compliant', importable: true }
46
+ { text: 'Month', id: 'month', tooltip: { text: 'Month', placement: 'top' } },
47
+ { text: 'Electricity usage', id: 'electricity_usage' },
48
+ { text: 'Gas usage', id: 'gas_usage' },
49
+ { text: 'Sources', id: 'sources' },
50
+ { text: 'Compliant', id: 'compliant' }
51
51
  ],
52
52
  viewCells: [
53
53
  ->(view) do
@@ -56,7 +56,6 @@ nav_groups = {
56
56
  'flow',
57
57
  'grid',
58
58
  'horizontal',
59
- 'panels_bulkEdit2',
60
59
  'pagination',
61
60
  'responsive',
62
61
  'scroll',
@@ -83,13 +83,13 @@ page.body(
83
83
  padding: glib_json_padding_body,
84
84
  childViews: ->(res) do
85
85
  res.h2 text: 'Overview'
86
- res.p text: 'panels_bulkEdit3 is the generic bulk-edit table: bulkEdit2’s skeleton plus config-driven file parsing, row gates, read-only columns, view chips and submission extras.'
86
+ res.p text: 'panels_bulkEdit3 is the generic bulk-edit table: cells, pagination and one-POST-per-row submission, plus config-driven file parsing, row gates, read-only columns, view chips and submission extras.'
87
87
  res.spacer height: 12
88
88
  res.hr width: 'matchParent'
89
89
 
90
90
  res.h2 text: 'Basic example (plain CSV)'
91
91
  res.spacer height: 8
92
- res.p text: 'Without parse config the table takes plain CSVs: header row first, header names as field ids (the bulkEdit2 shape). maxRows 3 rejects oversized files whole.'
92
+ res.p text: 'Without parse config the table takes plain CSVs: header row first, header names as field ids. maxRows 3 rejects oversized files whole.'
93
93
  res.spacer height: 8
94
94
  res.panels_horizontal(
95
95
  align: 'middle',
@@ -16,7 +16,7 @@ module Glib
16
16
  raise "Submit action needs to be inside a form: #{http.router.last_log}" unless form
17
17
 
18
18
  case Glib::JsonUi::Name.normalize(form['view'])
19
- when 'panels/bulkEdit2', 'panels/bulkEdit3'
19
+ when 'panels/bulkEdit3'
20
20
  method = 'post'
21
21
  action = "forms/#{method}"
22
22
  url = form['import']['submitUrl']
@@ -239,7 +239,6 @@ module Glib
239
239
  name = Glib::JsonUi::Name.normalize(view['view'])
240
240
  name&.start_with?('panels/form') ||
241
241
  name&.start_with?('panels/fullPageForm') ||
242
- name == 'panels/bulkEdit2' ||
243
242
  name == 'panels/bulkEdit3' ||
244
243
  name == 'panels/splitForm'
245
244
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glib-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 6.10.4
4
+ version: 6.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-09-19 00:00:00.000000000 Z
11
+ date: 2026-09-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activestorage
@@ -499,7 +499,6 @@ files:
499
499
  - app/views/json_ui/garage/test_page/multimedia_video.json.jbuilder
500
500
  - app/views/json_ui/garage/test_page/pagination.json.jbuilder
501
501
  - app/views/json_ui/garage/test_page/panels.json.jbuilder
502
- - app/views/json_ui/garage/test_page/panels_bulkEdit2.json.jbuilder
503
502
  - app/views/json_ui/garage/test_page/panels_bulkEdit3.json.jbuilder
504
503
  - app/views/json_ui/garage/test_page/popovers.json.jbuilder
505
504
  - app/views/json_ui/garage/test_page/progressCircle.json.jbuilder
@@ -1,244 +0,0 @@
1
- json.title 'Test Page (Panels Bulk Edit 2)'
2
-
3
- page = json_ui_page json
4
-
5
- options = [{ text: 'yes', value: 'yes' }, { text: 'no', value: 'no' }]
6
- source_options = ['Generators', 'Power Station', 'Solar Panels'].map do |source|
7
- { text: source, value: source }
8
- end
9
-
10
- default_headers = [
11
- { text: 'Month', id: 'month', importable: true, tooltip: { text: 'Month', placement: 'top' } },
12
- { text: 'Electricity usage', id: 'electricity_usage', importable: true },
13
- { text: 'Gas usage', id: 'gas_usage', importable: true },
14
- { text: 'Sources', id: 'sources', importable: true },
15
- { text: 'Compliant', id: 'compliant', importable: true }
16
- ]
17
-
18
- default_cells = [
19
- ->(view) do
20
- view.fields_number width: 'matchParent'
21
- end,
22
- ->(view) do
23
- view.fields_number width: 'matchParent'
24
- end,
25
- ->(view) do
26
- view.fields_number width: 'matchParent'
27
- end,
28
- ->(view) do
29
- view.fields_select width: 'matchParent', options: source_options, multiple: true
30
- end,
31
- ->(view) do
32
- view.fields_select width: 'matchParent', options: options
33
- end
34
- ]
35
-
36
- [
37
- { text: 'Month', id: 'month', importable: true },
38
- { text: 'Usage (kWh)', id: 'electricity_usage', importable: true },
39
- { text: 'Usage (Therms)', id: 'gas_usage', importable: true }
40
- ]
41
-
42
- [
43
- ->(view) do
44
- view.fields_number width: 120
45
- end,
46
- ->(view) do
47
- view.fields_number width: 140
48
- end,
49
- ->(view) do
50
- view.fields_number width: 140
51
- end
52
- ]
53
-
54
- import_settings = { submitUrl: json_ui_garage_url(path: 'forms/bulk_edit_post2'), paramName: 'user' }
55
-
56
- render 'json_ui/garage/test_page/header', json: json, page: page
57
-
58
- page.body(
59
- childViews: ->(body) do
60
- body.panels_responsive(
61
- padding: glib_json_padding_body,
62
- childViews: ->(res) do
63
- res.h2 text: 'Overview'
64
- res.p text: 'panels_bulkEdit2 renders an editable grid with import-backed rows and bulk submission events.'
65
- res.spacer height: 12
66
- res.hr width: 'matchParent'
67
- res.h2 text: 'Basic example'
68
- res.spacer height: 8
69
- res.panels_horizontal(
70
- align: 'middle',
71
- childViews: ->(horizontal) do
72
- horizontal.label text: 'Loaded: '
73
- horizontal.label id: 'bulk_edit_loaded_count', text: '0'
74
- horizontal.spacer width: 12
75
- horizontal.label text: 'Selected: '
76
- horizontal.label id: 'bulk_edit_selected_count', text: '0'
77
- horizontal.spacer width: 12
78
- horizontal.chip id: 'bulk_edit_succeeded_count', styleClass: 'success', text: 'Uploaded: 0', displayed: false
79
- end
80
- )
81
- res.spacer height: 8
82
- res.panels_bulkEdit2(
83
- id: 'bulk_edit_main',
84
- width: 'matchParent',
85
- paramNameForRowId: 'row_id',
86
- # Files with more data rows than this are rejected wholesale with an
87
- # error dialog (the header row doesn't count).
88
- maxRows: 3,
89
- import: import_settings,
90
- viewHeaders: default_headers,
91
- viewCells: default_cells,
92
- onCellChange: ->(action) do
93
- action.snackbars_alert debug: true, paramName: 'message', fieldName: 'row'
94
- end,
95
- onSubmitStart: ->(action) do
96
- action.runMultiple(
97
- childActions: ->(multiple) do
98
- multiple.components_set targetId: 'bulk_edit_submit_top', data: { disabled: true }
99
- multiple.components_set targetId: 'bulk_edit_submit_bottom', data: { disabled: true }
100
- multiple.components_set targetId: 'bulk_edit_cancel', data: { displayed: true }
101
- end
102
- )
103
- end,
104
- onSubmitEnd: ->(action) do
105
- action.runMultiple(
106
- childActions: ->(multiple) do
107
- multiple.components_set targetId: 'bulk_edit_submit_top', data: { disabled: false }
108
- multiple.components_set targetId: 'bulk_edit_submit_bottom', data: { disabled: false }
109
- multiple.components_set targetId: 'bulk_edit_cancel', data: { displayed: false }
110
- end
111
- )
112
- end,
113
- onRowsLoad: ->(action) do
114
- action.runMultiple(
115
- debug: true,
116
- fieldName: 'data',
117
- childActions: ->(multiple) do
118
- multiple.logics_set(
119
- targetId: 'bulk_edit_loaded_count',
120
- debug: true,
121
- paramName: 'variables',
122
- fieldName: 'data',
123
- conditionalData: {
124
- text: { "count": [{ "var": 'data.loadedRows' }] }
125
- }
126
- )
127
- multiple.components_set targetId: 'bulk_edit_submit_top', data: { displayed: true }
128
- multiple.components_set targetId: 'bulk_edit_submit_bottom', data: { displayed: true }
129
- end
130
- )
131
- end,
132
- onRowsSelect: ->(action) do
133
- action.logics_set(
134
- targetId: 'bulk_edit_selected_count',
135
- debug: true,
136
- paramName: 'variables',
137
- fieldName: 'data',
138
- conditionalData: {
139
- text: { "count": [{ "var": 'data.selectedRows' }] }
140
- }
141
- )
142
- end,
143
- onRowsSucceed: ->(action) do
144
- action.logics_set(
145
- targetId: 'bulk_edit_succeeded_count',
146
- debug: true,
147
- paramName: 'variables',
148
- fieldName: 'data',
149
- conditionalData: {
150
- text: {
151
- "printf": [
152
- 'Uploaded: {0}',
153
- { "count": [{ "var": 'data.succeededRows' }] }
154
- ]
155
- },
156
- displayed: true
157
- }
158
- )
159
- end
160
- )
161
- res.spacer height: 12
162
- res.panels_flow(
163
- innerPadding: { bottom: 0 },
164
- childViews: ->(flow) do
165
- flow.button(
166
- id: 'bulk_edit_submit_top',
167
- text: 'Submit (top)',
168
- displayed: false,
169
- onClick: ->(action) do
170
- action.forms_submit targetId: 'bulk_edit_main'
171
- end
172
- )
173
- flow.spacer width: 8
174
- flow.button(
175
- id: 'bulk_edit_submit_bottom',
176
- text: 'Submit (bottom)',
177
- displayed: false,
178
- onClick: ->(action) do
179
- action.forms_submit targetId: 'bulk_edit_main'
180
- end
181
- )
182
- flow.spacer width: 8
183
- flow.button(
184
- id: 'bulk_edit_cancel',
185
- text: 'Cancel import',
186
- displayed: false,
187
- onClick: ->(action) do
188
- action.components_invoke targetId: 'bulk_edit_main', name: 'cancelImport'
189
- end
190
- )
191
- end
192
- )
193
- res.spacer height: 12
194
- res.hr width: 'matchParent'
195
- # res.h2 text: 'Variants/props'
196
- # res.spacer height: 8
197
- # res.panels_flow innerPadding: { bottom: 0 }, childViews: ->(flow) do
198
- # flow.button text: 'Default columns', onClick: ->(action) do
199
- # action.components_set targetId: 'bulk_edit_main', data: { viewHeaders: default_headers, viewCells: default_cells }
200
- # end
201
- # flow.spacer width: 8
202
- # flow.button text: 'Compact columns', onClick: ->(action) do
203
- # action.components_set targetId: 'bulk_edit_main', data: { viewHeaders: compact_headers, viewCells: compact_cells }
204
- # end
205
- # flow.spacer width: 8
206
- # flow.button text: 'Reset counts', onClick: ->(action) do
207
- # action.runMultiple childActions: ->(multiple) do
208
- # multiple.components_set targetId: 'bulk_edit_loaded_count', data: { text: '0' }
209
- # multiple.components_set targetId: 'bulk_edit_selected_count', data: { text: '0' }
210
- # multiple.components_set targetId: 'bulk_edit_succeeded_count', data: { text: 'Uploaded: 0', displayed: false }
211
- # end
212
- # end
213
- # end
214
- # res.spacer height: 12
215
- # res.hr width: 'matchParent'
216
- res.h2 text: 'Actions/events'
217
- res.spacer height: 8
218
- res.panels_flow(
219
- innerPadding: { bottom: 0 },
220
- childViews: ->(flow) do
221
- flow.button(
222
- text: 'Submit (forms_submit)',
223
- onClick: ->(action) do
224
- action.forms_submit targetId: 'bulk_edit_main'
225
- end
226
- )
227
- flow.spacer width: 8
228
- flow.button(
229
- text: 'Cancel import (invoke)',
230
- onClick: ->(action) do
231
- action.components_invoke targetId: 'bulk_edit_main', name: 'cancelImport'
232
- end
233
- )
234
- end
235
- )
236
- res.spacer height: 12
237
- res.hr width: 'matchParent'
238
- res.h2 text: 'Edge/advanced'
239
- res.spacer height: 8
240
- res.label text: 'Swap to compact headers then try editing rows before submitting.'
241
- end
242
- )
243
- end
244
- )