widget_list 1.3.7 → 2.0.1
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 +5 -13
- data/README.md +143 -696
- data/app/views/widget_list/administration/_button_row.html.erb +2 -2
- data/app/views/widget_list/administration/_field_row.html.erb +2 -2
- data/app/views/widget_list/administration/_output.html.erb +89 -55
- data/checkin_gem.sh +10 -10
- data/docs/legacy-readme.md +757 -0
- data/docs/screenshots/admin1.jpg +0 -0
- data/docs/screenshots/admin2.jpg +0 -0
- data/docs/screenshots/admin3.jpg +0 -0
- data/docs/screenshots/admin4.jpg +0 -0
- data/docs/screenshots/admin5.png +0 -0
- data/docs/screenshots/admin6.png +0 -0
- data/docs/screenshots/filtered.png +0 -0
- data/docs/screenshots/main.png +0 -0
- data/docs/screenshots/ransack1.png +0 -0
- data/docs/screenshots/ransack2.png +0 -0
- data/docs/screenshots/ransack3.png +0 -0
- data/docs/screenshots/search.png +0 -0
- data/docs/screenshots/theme_blue_sky_basin.png +0 -0
- data/docs/widget-list-demo-thumbnail.png +0 -0
- data/lib/extensions/action_controller_base.rb +22 -29
- data/lib/widget_list/engine.rb +1 -4
- data/lib/widget_list/railtie.rb +10 -33
- data/lib/widget_list/request_context.rb +5 -0
- data/lib/widget_list/sequel.rb +17 -41
- data/lib/widget_list/utils.rb +7 -7
- data/lib/widget_list/version.rb +1 -1
- data/lib/widget_list/widgets.rb +1 -2
- data/lib/widget_list.rb +267 -269
- data/publish_gem.sh +14 -35
- data/vendor/assets/stylesheets/{widget_list.css → widget_list.css.erb} +21 -21
- data/vendor/assets/stylesheets/{widgets.css → widgets.css.erb} +9 -9
- data/widget_list.gemspec +8 -10
- metadata +58 -32
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<!--TEXT_DESC-->: <input type="text" class="<!--SUBJECT-->_<!--TEXT_KEY-->" style="width:170px" onblur="jQuery(this).attr('value',jQuery(this).val().trim());<!--ONBLUR1-->" name="<!--SUBJECT-->[<!--TEXT_KEY-->][]" id="<!--SUBJECT-->[<!--TEXT_KEY-->][]" value="<!--BUTTON_TEXT-->"/><%= raw WidgetList::Widgets::widget_button('?', {'onclick' => "alert('<!--TEXT_HELP-->')", 'innerClass' => "default <!--SUBJECT-->_<!--TEXT_KEY-->_button" }, true ) %>
|
|
4
4
|
</td>
|
|
5
5
|
<td>
|
|
6
|
-
<!--URL_DESC-->: 
|
|
6
|
+
<!--URL_DESC-->: <% if local_assigns[:middle_column_select] %><select class="<!--SUBJECT-->_<!--URL_KEY--> widget-list-column-select" style="width:170px" name="<!--SUBJECT-->[<!--URL_KEY-->][]" data-selected="<!--BUTTON_URL-->" onchange="<!--ONBLUR2-->"><option value="">Select a column</option></select><% else %><input type="text" class="<!--SUBJECT-->_<!--URL_KEY-->" style="width:170px" onblur="jQuery(this).attr('value',jQuery(this).val().trim());<!--ONBLUR2-->" name="<!--SUBJECT-->[<!--URL_KEY-->][]" id="<!--SUBJECT-->[<!--URL_KEY-->][]" value="<!--BUTTON_URL-->"/><% end %><%= raw WidgetList::Widgets::widget_button('?', {'onclick' => "alert('<!--2_HELP->')", 'innerClass' => "default <!--SUBJECT-->_<!--URL_KEY-->_button" }, true ) %>
|
|
7
7
|
</td>
|
|
8
8
|
<td>
|
|
9
9
|
<!--COLOR_DESC-->: <input type="text" class="<!--SUBJECT-->_<!--COLOR_KEY-->" style="width:170px" onblur="jQuery(this).attr('value',jQuery(this).val().trim());<!--ONBLUR3-->" name="<!--SUBJECT-->[<!--COLOR_KEY-->][]" id="<!--SUBJECT-->[<!--COLOR_KEY-->][]" value="<!--BUTTON_CLASS-->"/><%= raw WidgetList::Widgets::widget_button('?', {'onclick' => "alert('<!--COLOR_HELP-->')", 'innerClass' => "default <!--SUBJECT-->_<!--COLOR_KEY-->_button" }, true ) %>
|
|
@@ -11,4 +11,4 @@
|
|
|
11
11
|
<td>
|
|
12
12
|
<!--REMOVE_FIELD_BUTTON-->
|
|
13
13
|
</td>
|
|
14
|
-
</tr>
|
|
14
|
+
</tr>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<tr style="<!--TR_STYLE-->">
|
|
2
2
|
<td style="<!--TR1_STYLE-->">
|
|
3
|
-
<!--FIELD-->: 
|
|
3
|
+
<!--FIELD-->: <% if local_assigns[:key_select] %><select style="width:350px" class="<!--SUBJECT-->_keys widget-list-column-select" name="<!--SUBJECT-->[key][]" data-selected="<!--FIELD_VALUE-->" onchange="<!--ONBLUR1-->"><option value="">Select a column</option></select><% else %><input type="text" style="width:350px" class="<!--SUBJECT-->_keys" onblur="jQuery(this).attr('value',jQuery(this).val().trim());<!--ONBLUR1-->" name="<!--SUBJECT-->[key][]" id="<!--SUBJECT-->[key][]" value="<!--FIELD_VALUE-->"/><% end %>
|
|
4
4
|
</td>
|
|
5
5
|
<td>
|
|
6
6
|
<!--DESC-->: <input <!--DISABLED--> type="text" style="width:350px" class="<!--SUBJECT-->_descriptions" onblur="jQuery(this).attr('value',jQuery(this).val().trim());<!--ONBLUR2-->" name="<!--SUBJECT-->[description][]" id="<!--SUBJECT-->[description][]" value="<!--FIELD_DESC-->"/>
|
|
@@ -9,4 +9,4 @@
|
|
|
9
9
|
<!--REMOVE_FIELD_BUTTON-->
|
|
10
10
|
</td>
|
|
11
11
|
</tr>
|
|
12
|
-
<!--EXTRA-->
|
|
12
|
+
<!--EXTRA-->
|
|
@@ -39,6 +39,10 @@
|
|
|
39
39
|
var all = '.init,.start,.fields,.rows,.search,.footer,.misc_submit';
|
|
40
40
|
var all_btns = '#start,#fields,#rows,#search,#footer,#misc_submit';
|
|
41
41
|
jQuery(document).ready(function () {
|
|
42
|
+
PopulateColumnSelects();
|
|
43
|
+
jQuery(document).on('change', 'select.widget-list-column-select', function () {
|
|
44
|
+
jQuery(this).attr('data-selected', this.value);
|
|
45
|
+
});
|
|
42
46
|
if (jQuery('#view').val() != '') {
|
|
43
47
|
jQuery(all_btns).removeClass('disabled');
|
|
44
48
|
}
|
|
@@ -49,6 +53,9 @@
|
|
|
49
53
|
}
|
|
50
54
|
|
|
51
55
|
window.onbeforeunload = function (evt) {
|
|
56
|
+
if (isSubmitting) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
52
59
|
var message = 'Are you sure you want to abandon this widget_list implementation? Doing so will lose all your work?';
|
|
53
60
|
if (typeof evt == 'undefined') {
|
|
54
61
|
evt = window.event;
|
|
@@ -57,9 +64,7 @@
|
|
|
57
64
|
if (evt) {
|
|
58
65
|
evt.returnValue = message;
|
|
59
66
|
}
|
|
60
|
-
|
|
61
|
-
return message;
|
|
62
|
-
}
|
|
67
|
+
return message;
|
|
63
68
|
}
|
|
64
69
|
|
|
65
70
|
});
|
|
@@ -82,33 +87,29 @@
|
|
|
82
87
|
var by_pass = false;
|
|
83
88
|
}
|
|
84
89
|
if (by_pass || VerifyOK(func_name)) {
|
|
85
|
-
jQuery('.search_dependent').hide(
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
if (func_name == 'ShowFields') {
|
|
96
|
-
ShowHiddenOptions();
|
|
97
|
-
ShowFunctionOptions();
|
|
98
|
-
}
|
|
99
|
-
if (func_name == 'ShowSubmit') {
|
|
100
|
-
ShowCheckboxOptions();
|
|
101
|
-
}
|
|
102
|
-
if (func_name == 'ShowRows') {
|
|
103
|
-
ShowButtonOptions();
|
|
104
|
-
ShowDrillDownOptions();
|
|
105
|
-
}
|
|
106
|
-
if (func_name == 'ShowFooter') {
|
|
107
|
-
ShowFooterOptions();
|
|
108
|
-
}
|
|
109
|
-
});
|
|
90
|
+
jQuery('.search_dependent').hide();
|
|
91
|
+
jQuery(all).hide();
|
|
92
|
+
jQuery(which_class).show();
|
|
93
|
+
if (func_name == 'ShowSearch') {
|
|
94
|
+
ShowSearchOptions(function() {
|
|
95
|
+
ShowGroupingOptions();
|
|
96
|
+
ShowExportOptions();
|
|
110
97
|
});
|
|
111
|
-
}
|
|
98
|
+
}
|
|
99
|
+
if (func_name == 'ShowFields') {
|
|
100
|
+
ShowHiddenOptions();
|
|
101
|
+
ShowFunctionOptions();
|
|
102
|
+
}
|
|
103
|
+
if (func_name == 'ShowSubmit') {
|
|
104
|
+
ShowCheckboxOptions();
|
|
105
|
+
}
|
|
106
|
+
if (func_name == 'ShowRows') {
|
|
107
|
+
ShowButtonOptions();
|
|
108
|
+
ShowDrillDownOptions();
|
|
109
|
+
}
|
|
110
|
+
if (func_name == 'ShowFooter') {
|
|
111
|
+
ShowFooterOptions();
|
|
112
|
+
}
|
|
112
113
|
|
|
113
114
|
if (!by_pass) {
|
|
114
115
|
SaveChanges();
|
|
@@ -141,31 +142,60 @@
|
|
|
141
142
|
ClickTab('.misc_submit',arguments.callee.name);
|
|
142
143
|
}
|
|
143
144
|
|
|
145
|
+
function SetColumnValue(control, value) {
|
|
146
|
+
var field = jQuery(control);
|
|
147
|
+
if (field.is('select') && !field.find('option').filter(function () { return this.value == value; }).length) {
|
|
148
|
+
field.append(jQuery('<option>').val(value).text(value));
|
|
149
|
+
}
|
|
150
|
+
field.val(value);
|
|
151
|
+
field.attr(field.is('select') ? 'data-selected' : 'value', value);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
function PopulateColumnSelects() {
|
|
155
|
+
var columns = jQuery('#checkboxField option').map(function () { return this.value; }).get().filter(Boolean);
|
|
156
|
+
if (!columns.length) return;
|
|
157
|
+
|
|
158
|
+
jQuery('select.widget-list-column-select').each(function () {
|
|
159
|
+
var field = jQuery(this);
|
|
160
|
+
var selected = field.val() || field.attr('data-selected') || '';
|
|
161
|
+
if (['column_name', 'col_name', 'field_name'].indexOf(selected) !== -1) selected = '';
|
|
162
|
+
|
|
163
|
+
field.empty().append(jQuery('<option>').val('').text(field.hasClass('group_by_keys') ? 'All items / select a column' : 'Select a column'));
|
|
164
|
+
columns.forEach(function (column) {
|
|
165
|
+
field.append(jQuery('<option>').val(column).text(column));
|
|
166
|
+
});
|
|
167
|
+
if (selected && columns.indexOf(selected) === -1) {
|
|
168
|
+
field.append(jQuery('<option>').val(selected).text(selected + ' (saved value)'));
|
|
169
|
+
}
|
|
170
|
+
SetColumnValue(field, selected);
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
|
|
144
174
|
function ReplaceColumnsToLinked(obj) {
|
|
175
|
+
var isPassColumn = jQuery(obj).hasClass('drill_downs_data_to_pass_from_view');
|
|
176
|
+
var displayColumn = jQuery(obj).closest('tr').find('.drill_downs_column_to_show').val() || '';
|
|
177
|
+
if (isPassColumn && displayColumn.endsWith('_linked')) return;
|
|
145
178
|
found = false;
|
|
146
|
-
var className = obj.className;
|
|
147
179
|
jQuery(obj).css('background-color','white');
|
|
148
180
|
jQuery('.fields_keys, .fields_hidden_keys, .fields_function_keys').each(
|
|
149
181
|
function(key, value) {
|
|
150
182
|
if(jQuery(value).val() == jQuery(obj).val().trim() && jQuery(obj).val().search(/_linked/i) == -1) {
|
|
151
183
|
found = true;
|
|
152
184
|
var id_original = jQuery(obj).val().trim();
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
if (className == 'drill_downs_data_to_pass_from_view') {
|
|
185
|
+
SetColumnValue(value, jQuery(obj).val().trim() + '_linked');
|
|
186
|
+
SetColumnValue(obj, isPassColumn ? id_original : id_original + '_linked');
|
|
187
|
+
if (isPassColumn) {
|
|
157
188
|
jQuery('.drill_downs_column_to_show[value="col_name"]').each(
|
|
158
189
|
function(key1, value1) {
|
|
159
|
-
jQuery(value1).val(
|
|
160
|
-
jQuery(value1).attr('value',
|
|
190
|
+
jQuery(value1).val(id_original + '_linked');
|
|
191
|
+
jQuery(value1).attr('value',id_original + '_linked');
|
|
161
192
|
return false;
|
|
162
193
|
}
|
|
163
194
|
)
|
|
164
195
|
} else {
|
|
165
|
-
jQuery('.drill_downs_data_to_pass_from_view
|
|
196
|
+
jQuery('.drill_downs_data_to_pass_from_view').filter(function () { return !this.value || this.value == 'col_name'; }).each(
|
|
166
197
|
function(key1, value1) {
|
|
167
|
-
|
|
168
|
-
jQuery(value1).attr('value',jQuery(value1).val().trim());
|
|
198
|
+
SetColumnValue(value1, id_original);
|
|
169
199
|
return false;
|
|
170
200
|
}
|
|
171
201
|
)
|
|
@@ -182,10 +212,9 @@
|
|
|
182
212
|
|
|
183
213
|
jQuery('#showHidden').attr('checked',true);
|
|
184
214
|
AddHiddenField();
|
|
185
|
-
jQuery('.fields_hidden_keys
|
|
215
|
+
jQuery('.fields_hidden_keys').filter(function () { return !this.value; }).each(
|
|
186
216
|
function(key1, value1) {
|
|
187
|
-
|
|
188
|
-
jQuery(value1).attr('value',id_original);
|
|
217
|
+
SetColumnValue(value1, id_original);
|
|
189
218
|
return false;
|
|
190
219
|
}
|
|
191
220
|
);
|
|
@@ -200,6 +229,7 @@
|
|
|
200
229
|
}
|
|
201
230
|
|
|
202
231
|
function InvalidField(obj) {
|
|
232
|
+
if (!jQuery(obj).val()) return;
|
|
203
233
|
found = false;
|
|
204
234
|
jQuery(obj).css('background-color','white');
|
|
205
235
|
jQuery('.fields_keys, .fields_hidden_keys, .fields_function_keys').each(
|
|
@@ -330,6 +360,7 @@
|
|
|
330
360
|
|
|
331
361
|
function AddGroupBy() {
|
|
332
362
|
jQuery('#grouping_table').html(jQuery('#grouping_table').html() + jQuery('#default_grouping_template').html());
|
|
363
|
+
PopulateColumnSelects();
|
|
333
364
|
}
|
|
334
365
|
|
|
335
366
|
function AddButton() {
|
|
@@ -339,6 +370,7 @@
|
|
|
339
370
|
|
|
340
371
|
function AddDrillDown() {
|
|
341
372
|
jQuery('#drill_down_table').html(jQuery('#drill_down_table').html() + jQuery('#default_drill_down_template').html());
|
|
373
|
+
PopulateColumnSelects();
|
|
342
374
|
}
|
|
343
375
|
|
|
344
376
|
function AddFooterButton() {
|
|
@@ -348,10 +380,12 @@
|
|
|
348
380
|
|
|
349
381
|
function AddHiddenField() {
|
|
350
382
|
jQuery('#hidden_field_table').html(jQuery('#hidden_field_table').html() + jQuery('#default_hidden_field_template').html());
|
|
383
|
+
PopulateColumnSelects();
|
|
351
384
|
}
|
|
352
385
|
|
|
353
386
|
function AddFieldFunction() {
|
|
354
387
|
jQuery('#field_function_table').html(jQuery('#field_function_table').html() + jQuery('#default_field_function_template').html());
|
|
388
|
+
PopulateColumnSelects();
|
|
355
389
|
}
|
|
356
390
|
|
|
357
391
|
function FakeCheck(obj) {
|
|
@@ -360,11 +394,11 @@
|
|
|
360
394
|
|
|
361
395
|
function RemoveField(obj) {
|
|
362
396
|
var isHiddenRemoval = false;
|
|
363
|
-
if (jQuery(obj).parent().parent().find('
|
|
397
|
+
if (jQuery(obj).parent().parent().find('.fields_hidden_keys').length > 0) {
|
|
364
398
|
isHiddenRemoval = true;
|
|
365
399
|
}
|
|
366
400
|
var isFunctionRemoval = false;
|
|
367
|
-
if (jQuery(obj).parent().parent().find('
|
|
401
|
+
if (jQuery(obj).parent().parent().find('.fields_function_keys').length > 0) {
|
|
368
402
|
isFunctionRemoval = true;
|
|
369
403
|
}
|
|
370
404
|
|
|
@@ -406,10 +440,9 @@
|
|
|
406
440
|
}
|
|
407
441
|
AddHiddenField();
|
|
408
442
|
jQuery('.hidden_fields_dependent').show();
|
|
409
|
-
jQuery('.fields_hidden_keys
|
|
443
|
+
jQuery('.fields_hidden_keys').filter(function () { return !this.value; }).each(
|
|
410
444
|
function(key1, value1) {
|
|
411
|
-
|
|
412
|
-
jQuery(value1).attr('value',field_name);
|
|
445
|
+
SetColumnValue(value1, field_name);
|
|
413
446
|
return false;
|
|
414
447
|
}
|
|
415
448
|
);
|
|
@@ -439,17 +472,16 @@
|
|
|
439
472
|
if (jQuery('#fieldFunctionOn').not(':checked')) {
|
|
440
473
|
jQuery('#fieldFunctionOn').attr('checked',true);
|
|
441
474
|
}
|
|
442
|
-
var objExists = '.fields_function_keys
|
|
443
|
-
if (
|
|
475
|
+
var objExists = jQuery('.fields_function_keys').filter(function () { return this.value == field_name; });
|
|
476
|
+
if (objExists.length > 0) {
|
|
444
477
|
alert('Field Function for ' + field_name + ' already exists, please modify');
|
|
445
478
|
jQuery(objExists).css('background-color','pink');
|
|
446
479
|
} else {
|
|
447
480
|
AddFieldFunction();
|
|
448
481
|
jQuery('.function_dependent').show();
|
|
449
|
-
jQuery('.fields_function_keys
|
|
482
|
+
jQuery('.fields_function_keys').filter(function () { return !this.value; }).each(
|
|
450
483
|
function(key1, value1) {
|
|
451
|
-
|
|
452
|
-
jQuery(value1).attr('value',field_name);
|
|
484
|
+
SetColumnValue(value1, field_name);
|
|
453
485
|
return false;
|
|
454
486
|
}
|
|
455
487
|
);
|
|
@@ -466,7 +498,7 @@
|
|
|
466
498
|
|
|
467
499
|
function ShowField(obj) {
|
|
468
500
|
|
|
469
|
-
var field_name = jQuery(obj).parent().parent().find('
|
|
501
|
+
var field_name = jQuery(obj).parent().parent().find('.fields_hidden_keys').val();
|
|
470
502
|
RemoveField(obj);
|
|
471
503
|
AddField();
|
|
472
504
|
jQuery('.fields_keys[value=""]').each(
|
|
@@ -504,6 +536,7 @@
|
|
|
504
536
|
jQuery('#checkboxField').html(response['checked_fields']);
|
|
505
537
|
jQuery('#footer_table').html(response['footer_buttons']);
|
|
506
538
|
jQuery('#grouping_table').html(response['group_by']);
|
|
539
|
+
PopulateColumnSelects();
|
|
507
540
|
SaveChanges();
|
|
508
541
|
if (jQuery(obj).val() != '') {
|
|
509
542
|
jQuery(all_btns).removeClass('disabled');
|
|
@@ -521,7 +554,7 @@
|
|
|
521
554
|
if (jQuery(obj).val() != '' && jQuery('#showExport').is(':checked')) {
|
|
522
555
|
jQuery('#exportButtonTitle').val('Export All ' + jQuery(obj).val() + 's');
|
|
523
556
|
}
|
|
524
|
-
}, "json").
|
|
557
|
+
}, "json").fail(function(response) {
|
|
525
558
|
alert('An error occurred instantiating this model. Check the response for errors.');
|
|
526
559
|
});
|
|
527
560
|
}
|
|
@@ -568,6 +601,7 @@
|
|
|
568
601
|
|
|
569
602
|
</script>
|
|
570
603
|
<form action="<!--POST_URL-->" method="post" id="widget_list_administration">
|
|
604
|
+
<input type="hidden" name="authenticity_token" value="<!--AUTH_TOKEN-->"/>
|
|
571
605
|
<h1 style="font-size:24;"><!--TITLE--></h1><div class="horizontal_rule"></div>
|
|
572
606
|
<h3>Get started quickly by selecting the features you need for this list</h3>
|
|
573
607
|
<table>
|
|
@@ -1098,4 +1132,4 @@
|
|
|
1098
1132
|
</tr>
|
|
1099
1133
|
|
|
1100
1134
|
</table>
|
|
1101
|
-
</form>
|
|
1135
|
+
</form>
|
data/checkin_gem.sh
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
2
3
|
|
|
3
|
-
|
|
4
|
+
cd "$(dirname "$0")"
|
|
5
|
+
version=$(ruby -Ilib -rwidget_list/version -e 'print WidgetList::VERSION')
|
|
6
|
+
gem build widget_list.gemspec --output "widget_list-${version}.gem"
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
example_dir="../widget_list_example"
|
|
9
|
+
if [[ -f "${example_dir}/bin/rails" ]]; then
|
|
10
|
+
(cd "$example_dir" && bundle install && bin/rails test)
|
|
11
|
+
fi
|
|
6
12
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
echo -e -n "Please test your solution and press enter to checkin new gem"
|
|
10
|
-
read THEMENAME
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
svn commit vendor/cache/widget_list-$1.gem vendor/bundle/ruby/1.9.1/cache/widget_list-$1.gem vendor/bundle/ruby/1.9.1/specifications/widget_list-$1.gemspec vendor/bundle/ruby/1.9.1/gems/widget_list-$1 vendor/cache/widget_list-$2.gem vendor/bundle/ruby/1.9.1/cache/widget_list-$2.gem vendor/bundle/ruby/1.9.1/specifications/widget_list-$2.gemspec vendor/bundle/ruby/1.9.1/gems/widget_list-$2 Gemfile.lock Gemfile -m "$1 -> $2 gem update"
|
|
13
|
+
printf 'Built widget_list-%s.gem. Review git diff and commit on main before publishing.\n' "$version"
|