super 0.0.16 → 0.17.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/super/application.js +146 -13
  3. data/app/assets/stylesheets/super/application.css +0 -1
  4. data/app/controllers/super/application_controller.rb +15 -2
  5. data/app/controllers/super/substructure_controller.rb +19 -8
  6. data/app/views/super/application/_display_actions.html.erb +1 -1
  7. data/app/views/super/application/_filter.html.erb +62 -2
  8. data/app/views/super/application/_member_header.html.erb +1 -1
  9. data/app/views/super/application/_sort_expression.html.erb +2 -2
  10. data/frontend/super-frontend/dist/application.css +0 -1
  11. data/frontend/super-frontend/dist/application.js +146 -13
  12. data/lib/super.rb +1 -0
  13. data/lib/super/display/guesser.rb +1 -1
  14. data/lib/super/display/schema_types.rb +0 -1
  15. data/lib/super/error.rb +2 -0
  16. data/lib/super/filter.rb +1 -1
  17. data/lib/super/filter/form_object.rb +74 -48
  18. data/lib/super/filter/guesser.rb +2 -0
  19. data/lib/super/filter/operator.rb +90 -64
  20. data/lib/super/filter/schema_types.rb +63 -80
  21. data/lib/super/form/builder.rb +6 -3
  22. data/lib/super/form/field_transcript.rb +43 -0
  23. data/lib/super/form/guesser.rb +1 -1
  24. data/lib/super/form/schema_types.rb +11 -20
  25. data/lib/super/link.rb +1 -1
  26. data/lib/super/schema.rb +4 -0
  27. data/lib/super/version.rb +1 -1
  28. metadata +4 -7
  29. data/app/views/super/application/_filter_type_select.html.erb +0 -21
  30. data/app/views/super/application/_filter_type_text.html.erb +0 -18
  31. data/app/views/super/application/_filter_type_timestamp.html.erb +0 -24
  32. data/app/views/super/application/_form_field_select.html.erb +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 14981d8658b6c65e32ead25ed20481ab4f675928239f72454ed0fc8d2dcd8795
4
- data.tar.gz: 124dc8f187b220e30d171bf4a2dda7f778b52a70088df3ffce5ea15bdfa93196
3
+ metadata.gz: f4c1533c37aaa4f56c80a7111be8f640d33a29e9de966acb5d389556224057c5
4
+ data.tar.gz: d57b41a260d921a135289497b247df2951d2d1c0399b3668f9c54f2c5ddc981a
5
5
  SHA512:
6
- metadata.gz: '0780127899eadf34022440f92166258941a8794a72098af5694b4df28da8b3c7a9f7c91ef8f140c0bc5fdd7154d539d197061229402ad9500c4510928ff0be03'
7
- data.tar.gz: 9025a0591386f938da8dc65a3d3dca846f76093c1d1c529b9df97a3cd0aa14b543dd2b32854273cbe23fd97358fce5dcef0712b96b5b29c09d0b7b0dda2b2b90
6
+ metadata.gz: 67d7be279b48cc7ebbb1ae4a7ea1c1bc6fd6f06ec11e218ccddd590d0392a64cdff7a896d49d0b96b796185a21b08fe4fc15d3cba4299d0d19a419105ee0c4a9
7
+ data.tar.gz: 9d0811ebf7fcd8e70d18285fa9e86979c96334c620c0688843dc85c4b33d695dacba1e6fb5f026e0f900ff930ade5c77b5321b5a428adc3968f92a579f7b2d77
@@ -413,7 +413,7 @@ var Super = (function (exports) {
413
413
  }).call(this);
414
414
  (function () {
415
415
  var AcceptHeaders, CSRFProtection, createXHR, cspNonce, prepareOptions, processResponse;
416
- cspNonce = Rails.cspNonce, CSRFProtection = Rails.CSRFProtection, Rails.fire;
416
+ cspNonce = Rails.cspNonce, CSRFProtection = Rails.CSRFProtection;
417
417
  AcceptHeaders = {
418
418
  '*': '*/*',
419
419
  text: 'text/plain',
@@ -3975,7 +3975,7 @@ var Super = (function (exports) {
3975
3975
  };
3976
3976
  }
3977
3977
 
3978
- var _default$6 = /*#__PURE__*/function (_Controller) {
3978
+ var _default$8 = /*#__PURE__*/function (_Controller) {
3979
3979
  _inherits(_default, _Controller);
3980
3980
 
3981
3981
  var _super = _createSuper(_default);
@@ -4004,7 +4004,7 @@ var Super = (function (exports) {
4004
4004
  return _default;
4005
4005
  }(Controller);
4006
4006
 
4007
- var _default$5 = /*#__PURE__*/function (_Controller) {
4007
+ var _default$7 = /*#__PURE__*/function (_Controller) {
4008
4008
  _inherits(_default, _Controller);
4009
4009
 
4010
4010
  var _super = _createSuper(_default);
@@ -4040,7 +4040,7 @@ var Super = (function (exports) {
4040
4040
  return _default;
4041
4041
  }(Controller);
4042
4042
 
4043
- var _default$4 = /*#__PURE__*/function (_Controller) {
4043
+ var _default$6 = /*#__PURE__*/function (_Controller) {
4044
4044
  _inherits(_default, _Controller);
4045
4045
 
4046
4046
  var _super = _createSuper(_default);
@@ -4064,7 +4064,7 @@ var Super = (function (exports) {
4064
4064
  return _default;
4065
4065
  }(Controller);
4066
4066
 
4067
- var _default$3 = /*#__PURE__*/function (_Controller) {
4067
+ var _default$5 = /*#__PURE__*/function (_Controller) {
4068
4068
  _inherits(_default, _Controller);
4069
4069
 
4070
4070
  var _super = _createSuper(_default);
@@ -4094,7 +4094,7 @@ var Super = (function (exports) {
4094
4094
  return _default;
4095
4095
  }(Controller);
4096
4096
 
4097
- var _default$2 = /*#__PURE__*/function (_Controller) {
4097
+ var _default$4 = /*#__PURE__*/function (_Controller) {
4098
4098
  _inherits(_default, _Controller);
4099
4099
 
4100
4100
  var _super = _createSuper(_default);
@@ -6354,7 +6354,7 @@ var Super = (function (exports) {
6354
6354
  window.flatpickr = flatpickr;
6355
6355
  }
6356
6356
 
6357
- var _default$1 = /*#__PURE__*/function (_Controller) {
6357
+ var _default$3 = /*#__PURE__*/function (_Controller) {
6358
6358
  _inherits(_default, _Controller);
6359
6359
 
6360
6360
  var _super = _createSuper(_default);
@@ -6382,6 +6382,137 @@ var Super = (function (exports) {
6382
6382
  return _default;
6383
6383
  }(Controller);
6384
6384
 
6385
+ var _default$2 = /*#__PURE__*/function (_Controller) {
6386
+ _inherits(_default, _Controller);
6387
+
6388
+ var _super = _createSuper(_default);
6389
+
6390
+ function _default() {
6391
+ _classCallCheck(this, _default);
6392
+
6393
+ return _super.apply(this, arguments);
6394
+ }
6395
+
6396
+ _createClass(_default, [{
6397
+ key: "connect",
6398
+ value: function connect() {
6399
+ var _this = this;
6400
+
6401
+ this.tabTargets.forEach(function (tab) {
6402
+ tab.tabContainer = _this;
6403
+ });
6404
+ }
6405
+ }, {
6406
+ key: "activeTabIdentifier",
6407
+ get: function get() {
6408
+ return this.controlTarget.value;
6409
+ }
6410
+ }, {
6411
+ key: "change",
6412
+ value: function change(event) {
6413
+ this.update(event.target.value);
6414
+ }
6415
+ }, {
6416
+ key: "update",
6417
+ value: function update(newActiveTabIdentifier) {
6418
+ var _this2 = this;
6419
+
6420
+ this.tabTargets.forEach(function (tab) {
6421
+ var tabController = _this2.application.getControllerForElementAndIdentifier(tab, _this2.tabControllerNameValue);
6422
+
6423
+ if (tab.dataset[_this2.tabIdentifierGetterValue] == newActiveTabIdentifier) {
6424
+ tabController.show();
6425
+ } else {
6426
+ tabController.hide();
6427
+ }
6428
+ });
6429
+ }
6430
+ }], [{
6431
+ key: "targets",
6432
+ get: function get() {
6433
+ return ["control", "tab"];
6434
+ }
6435
+ }, {
6436
+ key: "values",
6437
+ get: function get() {
6438
+ return {
6439
+ tabIdentifierGetter: String,
6440
+ tabControllerName: String
6441
+ };
6442
+ }
6443
+ }]);
6444
+
6445
+ return _default;
6446
+ }(Controller);
6447
+
6448
+ var _default$1 = /*#__PURE__*/function (_Controller) {
6449
+ _inherits(_default, _Controller);
6450
+
6451
+ var _super = _createSuper(_default);
6452
+
6453
+ function _default() {
6454
+ _classCallCheck(this, _default);
6455
+
6456
+ return _super.apply(this, arguments);
6457
+ }
6458
+
6459
+ _createClass(_default, [{
6460
+ key: "connect",
6461
+ value: function connect() {
6462
+ var tabContainer = this.element[this.tabContainerGetterValue];
6463
+
6464
+ if (tabContainer.activeTabIdentifier === this.identifierValue) {
6465
+ this.show();
6466
+ } else {
6467
+ this.hide();
6468
+ }
6469
+ }
6470
+ }, {
6471
+ key: "toggle",
6472
+ value: function toggle() {
6473
+ if (this.hasContentTarget) {
6474
+ this.hide();
6475
+ } else {
6476
+ this.show();
6477
+ }
6478
+ }
6479
+ }, {
6480
+ key: "show",
6481
+ value: function show() {
6482
+ if (this.hasContentTarget) {
6483
+ return;
6484
+ }
6485
+
6486
+ var pocketContent = this.pocketTarget.content.cloneNode(true);
6487
+ this.element.appendChild(pocketContent);
6488
+ }
6489
+ }, {
6490
+ key: "hide",
6491
+ value: function hide() {
6492
+ if (!this.hasContentTarget) {
6493
+ return;
6494
+ }
6495
+
6496
+ this.contentTarget.remove();
6497
+ }
6498
+ }], [{
6499
+ key: "targets",
6500
+ get: function get() {
6501
+ return ["pocket", "content"];
6502
+ }
6503
+ }, {
6504
+ key: "values",
6505
+ get: function get() {
6506
+ return {
6507
+ identifier: String,
6508
+ tabContainerGetter: String
6509
+ };
6510
+ }
6511
+ }]);
6512
+
6513
+ return _default;
6514
+ }(Controller);
6515
+
6385
6516
  var _default = /*#__PURE__*/function (_Controller) {
6386
6517
  _inherits(_default, _Controller);
6387
6518
 
@@ -6412,12 +6543,14 @@ var Super = (function (exports) {
6412
6543
  }(Controller);
6413
6544
 
6414
6545
  var StimulusApplication = Application.start();
6415
- StimulusApplication.register("apply-template", _default$6);
6416
- StimulusApplication.register("clean-filter-param", _default$5);
6417
- StimulusApplication.register("clean-filter-params", _default$4);
6418
- StimulusApplication.register("click-outside-to-close", _default$3);
6419
- StimulusApplication.register("delete", _default$2);
6420
- StimulusApplication.register("flatpickr", _default$1);
6546
+ StimulusApplication.register("apply-template", _default$8);
6547
+ StimulusApplication.register("clean-filter-param", _default$7);
6548
+ StimulusApplication.register("clean-filter-params", _default$6);
6549
+ StimulusApplication.register("click-outside-to-close", _default$5);
6550
+ StimulusApplication.register("delete", _default$4);
6551
+ StimulusApplication.register("flatpickr", _default$3);
6552
+ StimulusApplication.register("tab-container", _default$2);
6553
+ StimulusApplication.register("tab", _default$1);
6421
6554
  StimulusApplication.register("toggle-pending-destruction", _default);
6422
6555
 
6423
6556
  exports.StimulusApplication = StimulusApplication;
@@ -1487,7 +1487,6 @@ span.flatpickr-day.selected {
1487
1487
 
1488
1488
  .super-input-select {
1489
1489
  padding-right: 2rem;
1490
- width: 100%;
1491
1490
  background-repeat: no-repeat;
1492
1491
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232b6cb0' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E %3Cpolyline points='6 9 12 15 18 9'/%3E %3C/svg%3E");
1493
1492
  background-position: right 0.5rem center;
@@ -34,7 +34,8 @@ module Super
34
34
 
35
35
  # Creates a record, or shows the validation errors
36
36
  def create
37
- @record = build_record_with_params
37
+ @record = build_record
38
+ set_record_attributes
38
39
 
39
40
  if save_record
40
41
  redirect_to polymorphic_path(Super::Link.polymorphic_parts(@record))
@@ -56,8 +57,9 @@ module Super
56
57
  # Updates a record, or shows validation errors
57
58
  def update
58
59
  @record = load_record
60
+ set_record_attributes
59
61
 
60
- if update_record
62
+ if save_record
61
63
  redirect_to polymorphic_path(Super::Link.polymorphic_parts(@record))
62
64
  else
63
65
  @current_action = ActionInquirer.edit!
@@ -91,5 +93,16 @@ module Super
91
93
  params[:action]
92
94
  )
93
95
  end
96
+
97
+ def with_current_action(action)
98
+ original = @current_action
99
+ @current_action = ActionInquirer.new(
100
+ ActionInquirer.default_for_resources,
101
+ action
102
+ )
103
+ yield
104
+ ensure
105
+ @current_action = original
106
+ end
94
107
  end
95
108
  end
@@ -50,7 +50,18 @@ module Super
50
50
  #
51
51
  # @return [ActionController::Parameters]
52
52
  helper_method def permitted_params
53
- strong_params = Super::Form::StrongParams.new(form_schema)
53
+ strong_params =
54
+ if current_action.create?
55
+ with_current_action("new") do
56
+ Super::Form::StrongParams.new(form_schema)
57
+ end
58
+ elsif current_action.update?
59
+ with_current_action("edit") do
60
+ Super::Form::StrongParams.new(form_schema)
61
+ end
62
+ else
63
+ Super::Form::StrongParams.new(form_schema)
64
+ end
54
65
  params.require(strong_params.require(model)).permit(strong_params.permit)
55
66
  end
56
67
 
@@ -65,8 +76,12 @@ module Super
65
76
  # Configures the actions linked to on the show page as well as each row of
66
77
  # the table on the index page. This is an optional method
67
78
  #
79
+ # Favor the `record` argument over the `@record` instance variable;
80
+ # `@record` won't always be set, notably on the index page where it's
81
+ # called on every row
82
+ #
68
83
  # @return [Array<Link>]
69
- helper_method def member_actions
84
+ helper_method def member_actions(record)
70
85
  if current_action.show?
71
86
  Super::Link.find_all(:edit, :destroy)
72
87
  elsif current_action.edit?
@@ -127,18 +142,14 @@ module Super
127
142
  base_scope.build
128
143
  end
129
144
 
130
- def build_record_with_params
131
- base_scope.build(permitted_params)
145
+ def set_record_attributes
146
+ @record.attributes = permitted_params
132
147
  end
133
148
 
134
149
  def save_record
135
150
  @record.save
136
151
  end
137
152
 
138
- def update_record
139
- @record.update(permitted_params)
140
- end
141
-
142
153
  def destroy_record
143
154
  @record.destroy
144
155
  end
@@ -1,5 +1,5 @@
1
1
  <div>
2
- <% member_actions.each do |link| %>
2
+ <% member_actions(record).each do |link| %>
3
3
  <span class="pr-2 last:pr-0"><%= link.to_s(record: record, params: params) %></span>
4
4
  <% end %>
5
5
  </div>
@@ -1,6 +1,66 @@
1
1
  <h1 class="text-lg">Filter</h1>
2
- <% filter.each_field do |filter_field| %>
2
+ <% filter.each_attribute do |attribute_form_object| %>
3
3
  <div class="mt-4">
4
- <%= render(filter_field, form: form) %>
4
+ <%= form.fields_for(attribute_form_object.field_name, attribute_form_object) do |attribute_form| %>
5
+ <% selected_index = 0 %>
6
+ <div data-controller="tab-container" data-tab-container-tab-identifier-getter-value="tabIdentifierValue" data-tab-container-tab-controller-name-value="tab">
7
+ <div>
8
+ <span class="inline-block"><%= attribute_form_object.humanized_attribute_name %></span>
9
+ <select data-tab-container-target="control" data-action="tab-container#change" class="super-input super-input-select inline-block">
10
+ <% selected = false %>
11
+ <% attribute_form_object.each_operator.with_index do |operator_form_object, index| %>
12
+ <%
13
+ selected_attribute =
14
+ if !selected && operator_form_object.specified?
15
+ selected = true
16
+ selected_index = index
17
+ %(selected=selected)
18
+ else
19
+ ""
20
+ end
21
+ %>
22
+ <option value="<%= operator_form_object.identifier %>" <%= selected_attribute %>><%= operator_form_object.operator.humanized_operator_name %></option>
23
+ <% end %>
24
+ </select>
25
+ </div>
26
+ <div>
27
+ <% attribute_form_object.each_operator.with_index do |operator_form_object, index| %>
28
+ <div data-controller="tab" data-tab-tab-container-getter-value="tabContainer" data-tab-container-target="tab" data-tab-identifier-value="<%= operator_form_object.identifier %>">
29
+ <% form_html = capture do %>
30
+ <div data-tab-target="content">
31
+ <%= attribute_form.fields_for(operator_form_object.identifier, operator_form_object) do |operator_form| %>
32
+ <div class="flex gap-x-2 mt-2">
33
+ <% operator_form_object.each_field.with_index do |operator_field_name, index| %>
34
+ <div class="flex-1">
35
+ <% if operator_field_name == Super::Filter::FormObject::OperatorForm::NULLARY %>
36
+ <%= operator_form.super.check_box(operator_field_name, {}, "1", "") %>
37
+ <%= operator_form.super.label(operator_field_name, nil, super: { class: "select-none ml-1" }) %>
38
+ <% elsif operator_form_object.operator.respond_to?(:field_transcript) && operator_form_object.operator.field_transcript %>
39
+ <% field_transcript = operator_form_object.operator.field_transcript %>
40
+ <% if field_transcript.super? %>
41
+ <%= operator_form.super.public_send(field_transcript.method_name, operator_field_name, *field_transcript.args, **field_transcript.kwargs) %>
42
+ <% else %>
43
+ <%= operator_form.public_send(field_transcript.method_name, operator_field_name, *field_transcript.args, **field_transcript.kwargs) %>
44
+ <% end %>
45
+ <% else %>
46
+ <%= operator_form.super.text_field(operator_field_name) %>
47
+ <% end %>
48
+ </div>
49
+ <% end %>
50
+ </div>
51
+ <% end %>
52
+ </div>
53
+ <% end %>
54
+
55
+ <%= form_html if index == selected_index %>
56
+
57
+ <template data-tab-target="pocket">
58
+ <%= form_html %>
59
+ </template>
60
+ </div>
61
+ <% end %>
62
+ </div>
63
+ </div>
64
+ <% end %>
5
65
  </div>
6
66
  <% end %>
@@ -3,7 +3,7 @@
3
3
  <%= title %>
4
4
  </h1>
5
5
  <div>
6
- <% member_actions.each do |link| %>
6
+ <% member_actions(@record).each do |link| %>
7
7
  <%= link.to_s(
8
8
  default_options: {
9
9
  class: "super-button super-button--border-blue super-button-sm inline-block ml-2"
@@ -5,7 +5,7 @@
5
5
  :a,
6
6
  sort.sortable_columns,
7
7
  {},
8
- {}
8
+ { class: "w-full" }
9
9
  ) %>
10
10
  </div>
11
11
  <div class="flex-none w-2">
@@ -15,7 +15,7 @@
15
15
  :d,
16
16
  sort.class::DIRECTIONS,
17
17
  { include_blank: false },
18
- {}
18
+ { class: "w-full" }
19
19
  ) %>
20
20
  </div>
21
21
  <div class="flex-none pl-2">
@@ -1487,7 +1487,6 @@ span.flatpickr-day.selected {
1487
1487
 
1488
1488
  .super-input-select {
1489
1489
  padding-right: 2rem;
1490
- width: 100%;
1491
1490
  background-repeat: no-repeat;
1492
1491
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%232b6cb0' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E %3Cpolyline points='6 9 12 15 18 9'/%3E %3C/svg%3E");
1493
1492
  background-position: right 0.5rem center;