meta_workflows 0.9.31 → 0.9.32

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: '082bc115fde4da66c333a64ed7f8ab9ae036097687297d12813e604cbd907bbc'
4
- data.tar.gz: 4b8ae8d4f4f3ca60cdd6afb6a658cdcaa9c312bcd26f20d5f600abf3ea6edf79
3
+ metadata.gz: 3b6e5652802f3f166ea4d2bc4860e7c3967f5be1b39fb92858dacceb7ce59990
4
+ data.tar.gz: d4ccc1608e8683b73d5a7f38e9a49fc2c7511820bd03abacb3bbacb487722313
5
5
  SHA512:
6
- metadata.gz: e5412dbe3df1a2e872de904fdc80569802bedce14f5656cb3192878df024058ccc32c92d52ad7cd90b57ad550f4f69c49401a51e3637dd01b64937aabd918180
7
- data.tar.gz: b49065a8e236c76a4a50655c462ecb02ee54ae65a0275b2bec9e9807a1da8b58d14101fdf0047089e2db2b76bea5b6e9b8d62730f3d47cb83f24aa7a6729320f
6
+ metadata.gz: c7ea1140103f59aa5667044d9000eb483c06fd5624ed7b761777d3b51e57e7971d040cf5295eee9e2a64a6e0f36d960f6953b65e8440b535520e0155dfd49260
7
+ data.tar.gz: 54a7458c7905680b5cb8a56dfb8a985d8bde3878cc7a7e6e3b745023c8571d6e4a6381d70b5e48668df77cd2eaf8fe2dedaf811b9dd79f551df196bb8851cdf4
@@ -1,7 +1,7 @@
1
1
  import { Controller } from '@hotwired/stimulus';
2
2
 
3
3
  export default class extends Controller {
4
- static targets = ['textarea', 'form', 'structuredInputForm', 'hiddenMessage'];
4
+ static targets = ['textarea', 'form', 'structuredInputForm', 'hiddenMessage', 'structuredInput'];
5
5
 
6
6
  connect() {
7
7
  this.submitted = false;
@@ -14,7 +14,6 @@ export default class extends Controller {
14
14
  handleKeyDown(event) {
15
15
  if (event.key === 'Enter' && !event.shiftKey) {
16
16
  event.preventDefault();
17
- event.stopPropagation();
18
17
  this.handleSubmit();
19
18
  }
20
19
  }
@@ -24,7 +23,22 @@ export default class extends Controller {
24
23
  return;
25
24
  }
26
25
 
27
- if (!this.hasTextareaTarget || this.textareaTarget.value.trim() === '') {
26
+ // Check if we have structured input selections
27
+ const hasStructuredSelections = this.hasStructuredInputTargets.some(input =>
28
+ input.checked || (input.type === 'range' && input.value !== input.min)
29
+ );
30
+
31
+ if (hasStructuredSelections) {
32
+ // Submit the structured form to StructuredHumansController
33
+ this.submitted = true;
34
+ this.hideStructuredInputForm();
35
+ this.structuredInputFormTarget.requestSubmit();
36
+ return;
37
+ }
38
+
39
+ // Otherwise, handle normal text submission to HumansController
40
+ const textValue = this.hasTextareaTarget ? this.textareaTarget.value.trim() : '';
41
+ if (!textValue) {
28
42
  return;
29
43
  }
30
44
 
@@ -1,42 +1,61 @@
1
1
  import { Controller } from '@hotwired/stimulus';
2
2
 
3
3
  export default class extends Controller {
4
- static targets = ['form', 'submitButton', 'checkbox', 'slider'];
4
+ static targets = ['form', 'checkbox', 'slider'];
5
5
 
6
6
  connect() {
7
7
  this.submitted = false;
8
+ this.setupKeyboardListener();
8
9
  }
9
10
 
10
- sliderTargetConnected(slider) {
11
- this.updateSliderAria(slider);
11
+ disconnect() {
12
+ this.removeKeyboardListener();
12
13
  }
13
14
 
14
- updateSliderAria(slider) {
15
- slider.setAttribute('aria-valuenow', slider.value);
16
- slider.setAttribute('aria-valuetext', slider.value);
15
+ setupKeyboardListener() {
16
+ this.keydownHandler = this.handleKeyDown.bind(this);
17
+ if (this.hasFormTarget) {
18
+ this.formTarget.addEventListener('keydown', this.keydownHandler);
19
+ }
17
20
  }
18
21
 
19
- handleSliderChange(event) {
20
- this.updateSliderAria(event.target);
22
+ removeKeyboardListener() {
23
+ if (this.keydownHandler && this.hasFormTarget) {
24
+ this.formTarget.removeEventListener('keydown', this.keydownHandler);
25
+ }
21
26
  }
22
27
 
23
- checkboxTargetConnected() {
24
- this.updateSubmitButtonState();
28
+ handleKeyDown(event) {
29
+ if (event.key === 'Enter' && !event.shiftKey) {
30
+ // Check if we have selected checkboxes
31
+ const selectedCheckboxes = this.checkboxTargets.filter(checkbox => checkbox.checked);
32
+
33
+ if (selectedCheckboxes.length > 0) {
34
+ event.preventDefault();
35
+ event.stopPropagation();
36
+ this.handleSubmit();
37
+ }
38
+ }
25
39
  }
26
40
 
27
- checkboxTargetDisconnected() {
28
- this.updateSubmitButtonState();
41
+ sliderTargetConnected(slider) {
42
+ this.updateSliderAria(slider);
43
+ this.updateSliderFill(slider);
29
44
  }
30
45
 
31
- updateSubmitButtonState() {
32
- if (!this.hasSubmitButtonTarget) return;
46
+ updateSliderAria(slider) {
47
+ slider.setAttribute('aria-valuenow', slider.value);
48
+ slider.setAttribute('aria-valuetext', slider.value);
49
+ }
33
50
 
34
- const hasSelection = this.checkboxTargets.some(checkbox => checkbox.checked);
35
- this.submitButtonTarget.disabled = !hasSelection;
51
+ updateSliderFill(slider) {
52
+ const percentage = ((slider.value - slider.min) / (slider.max - slider.min)) * 100;
53
+ slider.style.setProperty('--slider-fill', `${percentage}%`);
36
54
  }
37
55
 
38
- handleCheckboxChange() {
39
- this.updateSubmitButtonState();
56
+ handleSliderChange(event) {
57
+ this.updateSliderAria(event.target);
58
+ this.updateSliderFill(event.target);
40
59
  }
41
60
 
42
61
  handleSubmit() {
@@ -48,19 +67,15 @@ export default class extends Controller {
48
67
  this.hideFormAndSubmit();
49
68
  }
50
69
 
51
- handleCheckboxSubmit(event) {
52
- event.preventDefault();
70
+ hideFormAndSubmit() {
71
+ // Hide the structured input form
72
+ if (this.hasFormTarget) {
73
+ this.formTarget.style.display = 'none';
74
+ }
53
75
 
54
- if (this.submitted) {
55
- return;
76
+ // Submit the form to StructuredHumansController
77
+ if (this.hasFormTarget) {
78
+ this.formTarget.requestSubmit();
56
79
  }
57
-
58
- this.submitted = true;
59
- this.hideFormAndSubmit();
60
- }
61
-
62
- hideFormAndSubmit() {
63
- this.formTarget.style.display = 'none';
64
- this.formTarget.requestSubmit();
65
80
  }
66
81
  }
@@ -840,8 +840,7 @@
840
840
  padding: 1rem;
841
841
  background-color: rgba(255, 255, 255, 0.9);
842
842
  border-radius: 0.75rem;
843
- border: 1px solid var(--gray-300);
844
- margin-bottom: 1rem;
843
+ margin-bottom: .5rem;
845
844
  }
846
845
 
847
846
  .structured-input-options {
@@ -856,28 +855,28 @@
856
855
  align-items: center;
857
856
  gap: 0.75rem;
858
857
  padding: 0.75rem 1rem;
859
- border: 1px solid var(--gray-300);
858
+ border: 2px solid transparent;
860
859
  border-radius: 0.5rem;
861
860
  background-color: white;
862
861
  cursor: pointer;
863
862
  transition: all 0.2s ease;
863
+ background-image: linear-gradient(white, white), linear-gradient(var(--gray-300), var(--gray-300));
864
+ background-origin: border-box;
865
+ background-clip: padding-box, border-box;
864
866
  }
865
867
 
866
868
  .structured-radio-option:hover {
867
- background-color: var(--gray-50);
868
- border-color: var(--purple-300);
869
+ background-image: linear-gradient(white, white), linear-gradient(45deg, #F3B51C, #E87C66, #F3B51C, #E87C66);
870
+ background-size: auto, 300% 300%;
871
+ animation: animatedgradient 3s ease alternate infinite;
869
872
  }
870
873
 
871
874
  .structured-radio-option:has(.structured-radio-input:checked) {
872
875
  background-color: var(--purple-50);
873
- border-color: var(--purple-500);
874
876
  }
875
877
 
876
878
  .structured-radio-input {
877
- width: 1.25rem;
878
- height: 1.25rem;
879
- accent-color: var(--purple-600);
880
- cursor: pointer;
879
+ display: none;
881
880
  }
882
881
 
883
882
  .structured-radio-label {
@@ -894,27 +893,32 @@
894
893
  align-items: center;
895
894
  gap: 0.75rem;
896
895
  padding: 0.75rem 1rem;
897
- border: 1px solid var(--gray-300);
896
+ border: 2px solid transparent;
898
897
  border-radius: 0.5rem;
899
898
  background-color: white;
900
899
  cursor: pointer;
901
900
  transition: all 0.2s ease;
901
+ background-image: linear-gradient(white, white), linear-gradient(var(--gray-300), var(--gray-300));
902
+ background-origin: border-box;
903
+ background-clip: padding-box, border-box;
902
904
  }
903
905
 
904
906
  .structured-checkbox-option:hover {
905
- background-color: var(--gray-50);
906
- border-color: var(--purple-300);
907
+ background-image: linear-gradient(white, white), linear-gradient(45deg, #F3B51C, #E87C66, #F3B51C, #E87C66);
908
+ background-size: auto, 300% 300%;
909
+ animation: animatedgradient 3s ease alternate infinite;
907
910
  }
908
911
 
909
912
  .structured-checkbox-option:has(.structured-checkbox-input:checked) {
910
- background-color: var(--purple-50);
911
- border-color: var(--purple-500);
913
+ background-image: linear-gradient(white, white), linear-gradient(45deg, #F3B51C, #E87C66);
912
914
  }
913
915
 
916
+
917
+
914
918
  .structured-checkbox-input {
915
919
  width: 1.25rem;
916
920
  height: 1.25rem;
917
- accent-color: var(--purple-600);
921
+ accent-color: var(--purple-700);
918
922
  cursor: pointer;
919
923
  }
920
924
 
@@ -929,12 +933,14 @@
929
933
  /* Slider Styles */
930
934
  .structured-slider-container {
931
935
  padding: 1rem;
936
+ border: 1px solid var(--gray-300);
937
+ border-radius: 0.5rem;
938
+ background-color: var(--gray-50);
932
939
  }
933
940
 
934
941
  .structured-slider-labels {
935
942
  display: flex;
936
943
  justify-content: space-between;
937
- margin-bottom: 1rem;
938
944
  font-size: 0.875rem;
939
945
  color: var(--gray-600);
940
946
  font-weight: 500;
@@ -948,46 +954,90 @@
948
954
 
949
955
  .structured-slider-input {
950
956
  width: 100%;
951
- height: 0.5rem;
957
+ height: 1rem;
952
958
  border-radius: 0.25rem;
953
- background: var(--gray-200);
959
+ background: transparent;
954
960
  outline: none;
955
961
  -webkit-appearance: none;
956
962
  appearance: none;
957
963
  cursor: pointer;
964
+ --slider-fill: 0%;
965
+ border: none;
966
+ }
967
+
968
+ .structured-slider-input::-webkit-slider-runnable-track {
969
+ width: 100%;
970
+ height: 1rem;
971
+ border-radius: 0.25rem;
972
+ background: linear-gradient(90deg,
973
+ #F3B51C 0%,
974
+ #E87C66 var(--slider-fill),
975
+ #e5e7eb var(--slider-fill),
976
+ #e5e7eb 100%
977
+ );
978
+ background-size: 100% 100%;
979
+ background-repeat: no-repeat;
980
+ border: 1px solid var(--gray-300);
981
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
982
+ }
983
+
984
+ .structured-slider-input::-moz-range-track {
985
+ width: 100%;
986
+ height: 1rem;
987
+ border-radius: 0.25rem;
988
+ background: linear-gradient(90deg,
989
+ #F3B51C 0%,
990
+ #E87C66 var(--slider-fill),
991
+ #e5e7eb var(--slider-fill),
992
+ #e5e7eb 100%
993
+ );
994
+ background-size: 100% 100%;
995
+ background-repeat: no-repeat;
996
+ border: 1px solid var(--gray-300);
997
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
958
998
  }
959
999
 
960
1000
  .structured-slider-input::-webkit-slider-thumb {
961
1001
  -webkit-appearance: none;
962
1002
  appearance: none;
963
- width: 1.5rem;
964
- height: 1.5rem;
965
- border-radius: 50%;
966
- background: var(--purple-600);
1003
+ width: 2.25rem;
1004
+ height: 2.25rem;
1005
+ border-radius: 0.5625rem;
1006
+ background: var(--purple-700);
1007
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='white' viewBox='0 0 320 512'%3e%3cpath d='M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z'/%3e%3c/svg%3e");
1008
+ background-size: 12px 12px;
1009
+ background-position: center;
1010
+ background-repeat: no-repeat;
967
1011
  cursor: pointer;
968
1012
  border: 2px solid white;
969
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
1013
+ box-shadow: 0 3px 6px rgba(0, 0, 0, 0.25);
970
1014
  transition: all 0.2s ease;
1015
+ margin-top: -0.65rem;
971
1016
  }
972
1017
 
973
1018
  .structured-slider-input::-webkit-slider-thumb:hover {
974
- background: var(--purple-700);
1019
+ background-color: var(--purple-800);
975
1020
  transform: scale(1.1);
976
1021
  }
977
1022
 
978
1023
  .structured-slider-input::-moz-range-thumb {
979
- width: 1.5rem;
980
- height: 1.5rem;
981
- border-radius: 50%;
982
- background: var(--purple-600);
1024
+ width: 2.25rem;
1025
+ height: 2.25rem;
1026
+ border-radius: 0.5625rem;
1027
+ background: var(--purple-700);
1028
+ background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' fill='white' viewBox='0 0 320 512'%3e%3cpath d='M96 480c-8.188 0-16.38-3.125-22.62-9.375c-12.5-12.5-12.5-32.75 0-45.25L242.8 256L73.38 86.63c-12.5-12.5-12.5-32.75 0-45.25s32.75-12.5 45.25 0l192 192c12.5 12.5 12.5 32.75 0 45.25l-192 192C112.4 476.9 104.2 480 96 480z'/%3e%3c/svg%3e");
1029
+ background-size: 12px 12px;
1030
+ background-position: center;
1031
+ background-repeat: no-repeat;
983
1032
  cursor: pointer;
984
1033
  border: 2px solid white;
985
- box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
1034
+ box-shadow: 0 3px 6px rgba(0, 0, 0, 0.25);
986
1035
  transition: all 0.2s ease;
1036
+ margin-top: -0.65rem;
987
1037
  }
988
1038
 
989
1039
  .structured-slider-input::-moz-range-thumb:hover {
990
- background: var(--purple-700);
1040
+ background-color: var(--purple-800);
991
1041
  transform: scale(1.1);
992
1042
  }
993
1043
 
@@ -1062,3 +1112,16 @@
1062
1112
  white-space: nowrap;
1063
1113
  border: 0;
1064
1114
  }
1115
+
1116
+ /* Animated Gradient Keyframes */
1117
+ @keyframes animatedgradient {
1118
+ 0% {
1119
+ background-position: 0% 50%;
1120
+ }
1121
+ 50% {
1122
+ background-position: 100% 50%;
1123
+ }
1124
+ 100% {
1125
+ background-position: 0% 50%;
1126
+ }
1127
+ }
@@ -12,6 +12,7 @@
12
12
  value="<%= option['value'] %>"
13
13
  class="structured-checkbox-input"
14
14
  data-meta-workflows--structured-form-submit-target="checkbox"
15
+ data-meta-workflows--lexi-form-submit-target="structuredInput"
15
16
  data-action="change->meta-workflows--structured-form-submit#handleCheckboxChange"
16
17
  aria-describedby="structured-checkbox-help"
17
18
  >
@@ -22,19 +23,4 @@
22
23
  <% end %>
23
24
  </div>
24
25
  <div id="structured-checkbox-help" class="sr-only">Use space to select/deselect options</div>
25
-
26
- <div class="structured-submit-container">
27
- <button
28
- type="submit"
29
- class="structured-submit-button"
30
- data-meta-workflows--structured-form-submit-target="submitButton"
31
- data-action="click->meta-workflows--structured-form-submit#handleCheckboxSubmit"
32
- disabled
33
- aria-describedby="structured-submit-help"
34
- aria-label="Submit your selections"
35
- >
36
- <i class="fa-solid fa-arrow-up"></i>
37
- </button>
38
- <div id="structured-submit-help" class="sr-only">Submit your selections. Button is disabled until at least one option is selected.</div>
39
- </div>
40
26
  </div>
@@ -36,12 +36,15 @@
36
36
  } %>
37
37
  </div>
38
38
 
39
+ <!-- Structured inputs area (above avatar) -->
40
+ <div class="structured-input-area" data-controller="meta-workflows--lexi-form-submit">
41
+ <%= render meta_structured_input, record: local_assigns[:record], structured_input_config: false, is_structured_input: false %>
42
+ </div>
43
+
39
44
  <!-- Avatar and input area pinned to bottom -->
40
45
  <div class="lexi-chat-bottom">
41
46
  <%= image_tag("lexi-expanded.png", alt: "Lexi Avatar", class: "lexi-avatar") %>
42
- <div class="lexi-input-wrapper" data-controller="meta-workflows--lexi-form-submit">
43
- <%= render meta_structured_input, record: local_assigns[:record], structured_input_config: false, is_structured_input: false %>
44
-
47
+ <div class="lexi-input-wrapper">
45
48
  <%= render partial: meta_response_form, locals: {record: local_assigns[:record], response_enabled: true, workflow_execution_id: active_execution&.id,
46
49
  chat_id: active_execution&.workflow_steps&.last&.chat&.id, workflow_execution: active_execution, is_structured_input: is_structured_input } %>
47
50
  </div>
@@ -12,6 +12,7 @@
12
12
  name="single_choice_selection"
13
13
  value="<%= option['value'] %>"
14
14
  class="structured-radio-input"
15
+ data-meta-workflows--lexi-form-submit-target="structuredInput"
15
16
  data-action="change->meta-workflows--structured-form-submit#handleSubmit"
16
17
  aria-describedby="structured-radio-help"
17
18
  required
@@ -19,6 +19,7 @@
19
19
  value="<%= options['min']['value'] %>"
20
20
  class="structured-slider-input"
21
21
  data-meta-workflows--structured-form-submit-target="slider"
22
+ data-meta-workflows--lexi-form-submit-target="structuredInput"
22
23
  data-action="change->meta-workflows--structured-form-submit#handleSubmit input->meta-workflows--structured-form-submit#handleSliderChange"
23
24
  aria-describedby="structured-slider-help"
24
25
  aria-valuemin="<%= options['min']['value'] %>"
@@ -3,7 +3,7 @@
3
3
  module MetaWorkflows
4
4
  MAJOR = 0
5
5
  MINOR = 9
6
- PATCH = 31 # this is automatically incremented by the build process
6
+ PATCH = 32 # this is automatically incremented by the build process
7
7
 
8
8
  VERSION = "#{MetaWorkflows::MAJOR}.#{MetaWorkflows::MINOR}.#{MetaWorkflows::PATCH}".freeze
9
9
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: meta_workflows
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.31
4
+ version: 0.9.32
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leonid Medovyy
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2025-07-24 00:00:00.000000000 Z
12
+ date: 2025-07-25 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails